.NET- এ কোনও প্রদত্ত অ্যাপ্লিকেশনটির একাধিক ঘটনা প্রতিরোধ করবেন?


123

.NET- এ, একই সাথে কোনও অ্যাপ্লিকেশনটির একাধিক ঘটনা চালানো থেকে রোধ করার সর্বোত্তম উপায় কী? এবং যদি কোনও "সেরা" কৌশল না থাকে তবে প্রতিটি সমাধানের সাথে বিবেচনা করার মতো কিছু সাবধানবাণী কী?

উত্তর:


151

Mutex ব্যবহার করুন। গেটপ্রসেসবাইনেম ব্যবহার করে উপরের উদাহরণগুলির মধ্যে একটিতে অনেকগুলি সতর্কতা রয়েছে। এখানে বিষয় সম্পর্কে একটি ভাল নিবন্ধ:

http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

[STAThread]
static void Main() 
{
   using(Mutex mutex = new Mutex(false, "Global\\" + appGuid))
   {
      if(!mutex.WaitOne(0, false))
      {
         MessageBox.Show("Instance already running");
         return;
      }

      Application.Run(new Form1());
   }
}

private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9";

1
একটি মিউটেক্স ব্যবহার নন নেট কোডের জন্যও কাজ করে (যদিও বাক্য
— গঠনটি

8
এখানে কিছু ভাল মন্তব্য সহ কিছুটা ভরাট-আউট সংস্করণ: স্ট্যাকওভারফ্লো.com
— রিচার্ড ওয়াটসন

2
@ ক্লার্ককেন্ট: কেবল একটি এলোমেলো স্ট্রিং যাতে মুটেক্স নামটি অন্য কোনও অ্যাপ্লিকেশন থেকে নামের সাথে সংঘর্ষে না আসে।
— jgauffin

এটি কি উদাহরণগুলির একটি নির্দিষ্ট সংখ্যার মধ্যেও সীমাবদ্ধ রাখতে পারে?
— আলেজান্দ্রো দেল

3
আপনার অ্যাপ্লিকেশন string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value;
— নির্দেশিকাটির সংস্করণকরণ

22
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
{
  AppLog.Write("Application XXXX already running. Only one instance of this application is allowed", AppLog.LogMessageType.Warn);
  return;
}

1
আমি মনে করি এটি দেখতে হবে: odetocode.com/blogs/scott/archive/2004/08/20/…
— সাবমেরিনএক্স

আপনি কীভাবে নিশ্চিত হন যে নিবন্ধটি সঠিক? এটি এখনও মিটেক্স
— জন

আপনার সময় এবং প্রচেষ্টার জন্য আশ্চর্যজনক ঠিক নিখুঁত ধন্যবাদ
— আহমেদ মাহমুদ

2
-১ যদিও এটি দ্রুত সমাধান, এটি খুব সহজেই বন্ধ করা যায় a.exe এর নাম পরিবর্তন করে b.exe করা যেতে পারে এবং উভয়ই চলবে। + অন্যান্য ক্ষেত্রে যেখানে এটি কেবল উদ্দেশ্য হিসাবে কাজ করবে না। সতর্কতার সাথে ব্যবহার করুন!
— লার্স নীলসন

এটি মনো-বিকাশের সাথে কাজ করে না। উইন্ডোজের পরিবেশের অধীনে এটি দুর্দান্ত কাজ করে।
— টোনো নাম

20

আপনার কেবলমাত্র একটি উদাহরণ চলমান আছে তা নিশ্চিত করার জন্য কোডটি এখানে। এটি একটি নামযুক্ত মুটেক্স ব্যবহার করার পদ্ধতি।

public class Program
{
    static System.Threading.Mutex singleton = new Mutex(true, "My App Name");

    static void Main(string[] args)
    {
        if (!singleton.WaitOne(TimeSpan.Zero, true))
        {
            //there is already another instance running!
            Application.Exit();
        }
    }
}

2
কোনও ডাব্লুপিএফ অ্যাপ্লিকেশনটির জন্য অ্যাপ্লিকেশন.কন্টেন.শুটডাউন () ব্যবহার করুন; এই পদ্ধতিটি কবজির মতো কাজ করে। ধন্যবাদ টেরাপিন
— জেফ

এখানে মূল জিনিসটি আপনি মুটেক্সকে স্থির করেন। পাশাপাশি অন্য ক্ষেত্রে জিসি এটি সংগ্রহ করবে।
— ওলেকসেই

আমি নামটির মুটেক্সের সরলতা এবং স্পষ্টতা উপভোগ করেছি। এই কোডটি সংক্ষিপ্ত এবং কার্যকর।
— চাদ

7

হ্যানসেলম্যানের মাইক্রোসফ্ট থেকে উইনফরমস অ্যাপ্লিকেশনবেস ক্লাসটি ব্যবহার করার জন্য একটি পোস্ট রয়েছে is এটি করার জন্য ভিজুয়ালবাসিক সমাবেশ।


আমি কয়েক বছর ধরে এটি ব্যবহার করে আসছি তবে এখন আমি একটি মুটেক্স-ভিত্তিক সমাধানে পরিবর্তনের সন্ধান করছি। আমার কাছে এমন গ্রাহক রয়েছে যা এটি নিয়ে সমস্যার প্রতিবেদন করে এবং আমার সন্দেহ হয় এটি এটি করতে রিমোটিং ব্যবহার করছে।
— রিচার্ড ওয়াটসন

5

দেখে মনে হচ্ছে 3 টি মৌলিক কৌশল রয়েছে যা এখন পর্যন্ত পরামর্শ দেওয়া হয়েছে।

  1. মাইক্রোসফ্ট.ভিজুয়ালবাসিক.এপ্লিকেশন সার্ভিসস। উইন্ডোজফর্মস অ্যাপ্লিকেশনবেস ক্লাস থেকে উত্সাহ দিন এবং ইসসিংলআইনস্ট্যান্স সম্পত্তিটি সত্য হিসাবে সেট করুন। (আমি বিশ্বাস করি যে এখানে একটি সতর্কতাই ডাব্লুপিএফ অ্যাপ্লিকেশনগুলির সাথে কাজ করবে না, তাই করবে?)
  2. একটি নামযুক্ত মুটেক্স ব্যবহার করুন এবং এটি ইতিমধ্যে তৈরি করা হয়েছে কিনা তা পরীক্ষা করুন।
  3. চলমান প্রক্রিয়াগুলির একটি তালিকা পান এবং প্রক্রিয়াগুলির নামের তুলনা করুন। (এতে কোনও প্রদত্ত ব্যবহারকারীর মেশিনে চলমান অন্য কোনও প্রক্রিয়ার তুলনায় আপনার প্রক্রিয়াটির নামটি অনন্য হতে হবে the

কোন অনুমান আমি মিস করেছি?


3
আমি মনে করি না 3 খুব দক্ষ। আমি মুটেক্সকে ভোট দিয়েছি, বহুবার সমস্যা ছাড়াই এটি ব্যবহার করেছি। আমি কখনই আইটেম 1 ব্যবহার করি নি তা নিশ্চিত নয় যখন আপনি সি # তে থাকবেন কীভাবে তা উড়ে যায়।
— টাইপমিসম্যাচ

2
বিকল্প 1 এখনও ডাব্লুপিএফ এর সাথে কাজ করে এটি আরও খানিকটা জড়িত। msdn.microsoft.com/en-us/library/ms771662.aspx
— গ্রিম ব্র্যাডবেরি

5

1 - program.cs -> এ একটি রেফারেন্স তৈরি করুন

using System.Diagnostics;

2 - void Main()কোডের প্রথম লাইন হিসাবে লিখুন ->

 if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length >1)
                return;

এটাই.


এর সাথে তফাত কী Mutex? একটা ধরা আছে?
— হারাম্বে অ্যাটাক হেলিকপ্টার

এটি প্রক্রিয়াটির নাম ব্যবহার করছে। যদি নামটি পুনরাবৃত্তি করা হয় তবে এটি একটি মিথ্যা পতাকা তৈরি করবে। অন্য কোন ক্ষেত্রে, এটা চেয়ে mutex ক্লিনার এর
— Magallanes

4

আপনি যখন কোনও এক্সিকিউটেবলের জন্য একটি প্রকল্প তৈরি করেন তখন ভিজুয়াল স্টুডিও 2005 বা 2008 ব্যবহার করে "অ্যাপ্লিকেশন" প্যানেলের অভ্যন্তরীণ বৈশিষ্ট্য উইন্ডোগুলিতে "একক উদাহরণ প্রয়োগ করুন" নামে একটি চেক বাক্স থাকে যা আপনি একক উদাহরণ অ্যাপ্লিকেশনটিতে অ্যাপ্লিকেশনটি রূপান্তর করতে সক্রিয় করতে পারেন ।

আমি যে উইন্ডোটির সাথে কথা বলছি তার একটি ক্যাপচার এখানে দেওয়া হয়েছে: এখানে চিত্র বর্ণনা লিখুন এটি একটি ভিজ্যুয়াল স্টুডিও ২০০৮ উইন্ডোজ অ্যাপ্লিকেশন প্রকল্প।


3
আমার সি # / ডাব্লুপিএফ অ্যাপ্লিকেশনটির জন্য আপনি উল্লিখিত এই চেকবক্সটি সন্ধান করেছি এবং এর মধ্যে কোনও কিছুই নেই।
— শুভনোমাদ

3
আমি এটি আমার ভিএস ২০০৮ সি # / উইনফর্মস অ্যাপ্লিকেশনটির বৈশিষ্ট্যগুলিতে দেখতে পাচ্ছি না।
— জেসি ম্যাকগ্রু 20:25

ভিএস ২০০৫ তেও নয়। তিনি অবশ্যই পুরানো ভিবি স্টুডিওর উল্লেখ করবেন।
— নওফাল

হ্যাঁ বিকল্পটি বিদ্যমান, আমি উইন্ডোটিতে ক্যাপচার যুক্ত করতে পোস্টটি সংশোধন করেছি যাতে আপনি এই বিকল্পটি খুঁজে পেতে পারেন।
— ডলিভেরাস

6
বিকল্পটি কেবল ভিবি.এনইটি অ্যাপ্লিকেশনের জন্য বিদ্যমান, সি # এর জন্য নয়। স্পষ্টতই অপশনটি মাইক্রোসফ্ট থেকে উইনফরমস অ্যাপ্লিকেশনবেস ক্লাস ব্যবহার করে।
— amolbk

4

আমি এখানে সমস্ত সমাধান চেষ্টা করেছি এবং আমার সি #। নেট 4.0 প্রকল্পে কোনও কিছুই কাজ করে নি। আমার জন্য কাজ করে এমন সমাধানটি এখানে কাউকে সহায়তা করার আশায়:

প্রধান শ্রেণীর ভেরিয়েবল হিসাবে:

private static string appGuid = "WRITE AN UNIQUE GUID HERE";
private static Mutex mutex;

আপনার যখন অ্যাপ্লিকেশনটি ইতিমধ্যে চলছে কিনা তা পরীক্ষা করতে হবে:

bool mutexCreated;
mutex = new Mutex(true, "Global\\" + appGuid, out mutexCreated);
if (mutexCreated)
    mutex.ReleaseMutex();

if (!mutexCreated)
{
    //App is already running, close this!
    Environment.Exit(0); //i used this because its a console app
}

আমি অন্যান্য শর্তগুলি কেবল কিছু শর্তের সাথে বন্ধ করে দেওয়া দরকার, এটি আমার উদ্দেশ্যটির জন্য ভাল কাজ করেছে


আপনার আসলে মুটেক্স অর্জন এবং এটি ছেড়ে দেওয়ার দরকার নেই। আপনার যা জানা দরকার তা অন্য কোনও অ্যাপ্লিকেশন ইতিমধ্যে বস্তুটি তৈরি করেছে (যেমন, এর কর্নেল রেফারেন্স গণনা> = 1)।
— মাইকেল গোল্ডস্টেইন


3

একাধিক সমাধান চেষ্টা করার পরে আমি প্রশ্ন। আমি এখানে ডাব্লুপিএফ এর উদাহরণটি ব্যবহার করে শেষ করেছি : http://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/

public partial class App : Application  
{  
    private static Mutex _mutex = null;  

    protected override void OnStartup(StartupEventArgs e)  
    {  
        const string appName = "MyAppName";  
        bool createdNew;  

        _mutex = new Mutex(true, appName, out createdNew);  

        if (!createdNew)  
        {  
            //app is already running! Exiting the application  
            Application.Current.Shutdown();  
        }  

    }          
}  

App.xaml এ:

x:Class="*YourNameSpace*.App"
StartupUri="MainWindow.xaml"
Startup="App_Startup"

2

এই নিবন্ধটি সহজভাবে ব্যাখ্যা করে যে আপনি কীভাবে উইন্ডোজ অ্যাপ্লিকেশনটির উদাহরণগুলির সংখ্যার উপর নিয়ন্ত্রণ রেখে তৈরি করতে পারেন বা কেবলমাত্র একক উদাহরণ চালাতে পারেন। এটি একটি ব্যবসায়িক প্রয়োগের খুব সাধারণ প্রয়োজন typ এটি নিয়ন্ত্রণ করার জন্য ইতিমধ্যে প্রচুর অন্যান্য সম্ভাব্য সমাধান রয়েছে।

http://www.openwinforms.com/single_instance_application.html


লিঙ্কটি নষ্ট হয়ে গেছে।
— চাদ

2

VB.NET ব্যবহার করুন! সত্যিই না ;)

মাইক্রোসফ্ট.ভিজুয়ালবাসিক.এপ্লিকেশন সার্ভিস ব্যবহার করে;

ভিবি.নেট থেকে উইন্ডোজফর্মস অ্যাপ্লিকেশনবেস আপনাকে একটি "সিঙ্গেলআইনেস্টেস" সম্পত্তি সরবরাহ করে যা অন্যান্য উদাহরণগুলি নির্ধারণ করে এবং কেবল একটি ইনস্ট্যান্স চালাতে দেয়।


2

এটি ভিবি.নেটের কোড

Private Shared Sub Main()
    Using mutex As New Mutex(False, appGuid)
        If Not mutex.WaitOne(0, False) Then
              MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return
        End If

        Application.Run(New Form1())
    End Using
End Sub

এটি সি # এর জন্য কোড

private static void Main()
{
    using (Mutex mutex = new Mutex(false, appGuid)) {
        if (!mutex.WaitOne(0, false)) {
            MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }

        Application.Run(new Form1());
    }
}



1

(দ্রষ্টব্য: এটি একটি মজাদার-সমাধান! এটি কাজ করে তবে এটি অর্জনের জন্য খারাপ জিডিআই + ডিজাইন ব্যবহার করে))

আপনার অ্যাপ্লিকেশন সহ একটি চিত্র রাখুন এবং এটি শুরুতে লোড করুন। অ্যাপটি প্রস্থান না হওয়া অবধি এটিকে ধরে রাখুন। ব্যবহারকারী 2 য় দৃষ্টান্ত শুরু করতে সক্ষম হবে না। (অবশ্যই মিউটেক্স দ্রবণটি অনেক ক্লিনার)

private static Bitmap randomName = new Bitmap("my_image.jpg");

এটি তার সরলতায় প্রকৃতপক্ষে উজ্জ্বল এবং এটি কেবল চিত্রগুলি নয়, কোনও ধরণের ফাইলের সাথে কাজ করে। আমার মনে হচ্ছে মেটেক্স সমাধানটি "পরিষ্কার" থেকে অনেক দূরে। এটি অত্যন্ত জটিল এবং এটি "সঠিক" না করার কারণে এটি ব্যর্থ হওয়ার জন্য দৃশ্যত অনেকগুলি উপায় রয়েছে। Main()এটিতে এমন একটি পদ্ধতিও প্রয়োজন যা ডাব্লুপিএফ কীভাবে কাজ করবে বলে মনে করা যায় তার বিপরীতে।
— কাইল ডেলানি

এটি ব্যাগ ব্যবহারের মতো। এটি কাজ করে তবে এটি সে উদ্দেশ্যে তৈরি হয়নি। আমি এটি পেশাদার হিসাবে ব্যবহার করব না।
— বিটারব্লিউ

হ্যাঁ, এটি দুর্ভাগ্যজনক যে ব্যতিক্রমগুলির উপর নির্ভর না করে আমাদের কাছে কার্যকর এবং কার্যকর এর সমাধান নেই।
— কাইল ডেলাানি

যদিও এটি ঠিক বাগ নেই। এটি এখনও। নেট ইচ্ছানুসারে আচরণ করছে।
— কাইল ডেলাানি

1
[STAThread]
static void Main()                  // args are OK here, of course
{
    bool ok;
    m = new System.Threading.Mutex(true, "YourNameHere", out ok);

    if (! ok)
    {
        MessageBox.Show("Another instance is already running.");
        return;
    }

    Application.Run(new Form1());   // or whatever was there

    GC.KeepAlive(m);                // important!
}

থেকে: নেট অ্যাপ্লিকেশনটির একক উদাহরণ নিশ্চিত করা

এবং: একক দৃষ্টিকোণ অ্যাপ্লিকেশন নীরব

টুইটারের সাহায্যে @ সিমিং এবং @ সামঞ্জস্যপূর্ণ হিসাবে একই উত্তর:

উপর সি # জন স্কিট এর প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী খুঁজে বের করতে কেন GC.KeepAlive বিষয়


-1, কারণ আপনি মুটেক্সের সাথে একটি ব্যবহারের ব্লক ব্যবহার করতে ব্যর্থ হন, যা কিপএলাইভকে অতিমাত্রায় পরিণত করবে। এবং হ্যাঁ, আমি মনে করি জন স্কিটি এটিকে ভুল করেছে। এক্ষেত্রে মিটেক্সকে কেন নিষ্পত্তি করা ভুল হবে তা তিনি বিশদভাবে ব্যাখ্যা করেন না।

1

কেবল একটি ব্যবহার করছেন StreamWriter, এটি কীভাবে?

System.IO.File.StreamWriter OpenFlag = null;   //globally

এবং

try
{
    OpenFlag = new StreamWriter(Path.GetTempPath() + "OpenedIfRunning");
}
catch (System.IO.IOException) //file in use
{
    Environment.Exit(0);
}

0

সাধারণত এটি একটি নামযুক্ত মুটেক্স (নতুন ম্যাটেক্স ব্যবহার করে ("আপনার অ্যাপের নাম", সত্য)) ব্যবহার করে সম্পন্ন হয় এবং ফেরতের মানটি পরীক্ষা করে থাকে) তবে মাইক্রোসফ্টে কিছু সমর্থন ক্লাস রয়েছে V ভিজুয়ালবাসিক.ডিল যা এটি আপনার পক্ষে করতে পারে ।


0

এটি খাঁটি সি # তে আমার জন্য কাজ করেছে। চেষ্টা / ধরা তখনই হয় যখন তালিকার কোনও প্রক্রিয়া আপনার লুপের সময় প্রস্থান করে।

using System.Diagnostics;
....
[STAThread]
static void Main()
{
...
        int procCount = 0;
        foreach (Process pp in Process.GetProcesses())
        {
            try
            {
                if (String.Compare(pp.MainModule.FileName, Application.ExecutablePath, true) == 0)
                {
                    procCount++;                        
                    if(procCount > 1) {
                       Application.Exit();
                       return;
                    }
                }
            }
            catch { }
        }
        Application.Run(new Form1());
}

0

কোনও একক ক্ষেত্রে কোনও অ্যাপ্লিকেশন সীমাবদ্ধ করার সময় সুরক্ষা বিবেচনা করতে ভুলবেন না:

সম্পূর্ণ নিবন্ধ: https://blogs.msdn.microsoft.com/oldnewthing/20060620-13/?p=30813

প্রোগ্রামটির আর একটি অনুলিপি চলছে কিনা তা সনাক্ত করতে আমরা একটি স্থির নামের সাথে একটি নামযুক্ত মুটেক্স ব্যবহার করছি। তবে এর অর্থ এটিও হ'ল কোনও আক্রমণকারী প্রথমে মিউটেক্স তৈরি করতে পারে, যার ফলে আমাদের প্রোগ্রামটি একেবারেই চলতে বাধা দেয়! কীভাবে আমি এই ধরণের পরিষেবা আক্রমণকে অস্বীকার করতে পারি?

...

যদি আক্রমণকারী আপনার সুরক্ষা প্রসঙ্গে একই প্রোগ্রামে চলছে (বা হবে) তবে আপনি যা করতে পারেন তা কিছুই নেই। আপনার প্রোগ্রামটির আর একটি অনুলিপি চলছে কিনা তা নির্ধারণ করতে আপনি যে কোনও "গোপন হ্যান্ডশেক" নিয়ে আসেন না কেন, আক্রমণকারী এটি নকল করতে পারে। যেহেতু এটি সঠিক সুরক্ষা প্রসঙ্গে চলছে তাই এটি "আসল" প্রোগ্রামটি যা কিছু করতে পারে তা করতে পারে।

...

স্পষ্টতই আপনি একই সুরক্ষা সুবিধায় চালিত আক্রমণকারীর হাত থেকে নিজেকে রক্ষা করতে পারবেন না, তবে আপনি এখনও অন্য সুরক্ষা সুবিধায় দৌড়াদৌড়িহীন আক্রমণকারীদের হাত থেকে নিজেকে রক্ষা করতে পারবেন।

আপনার নিঃশব্দে একটি ডিএসিএল সেট করার চেষ্টা করুন, এখানে নেট নেট পদ্ধতি: https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.mutexsecurity(v=vs.110).aspx


0

এই উত্তরগুলির কোনওটিই আমার পক্ষে কাজ করেনি কারণ মনোপল্ফ ব্যবহার করে লিনাক্সের অধীনে কাজ করার জন্য আমার এটির দরকার ছিল। এটি আমার পক্ষে দুর্দান্ত কাজ করে:

এই পদ্ধতিটিকে একটি অনন্য আইডি পাস করার জন্য কল করুন

    public static void PreventMultipleInstance(string applicationId)
    {
        // Under Windows this is:
        //      C:\Users\SomeUser\AppData\Local\Temp\ 
        // Linux this is:
        //      /tmp/
        var temporaryDirectory = Path.GetTempPath();

        // Application ID (Make sure this guid is different accross your different applications!
        var applicationGuid = applicationId + ".process-lock";

        // file that will serve as our lock
        var fileFulePath = Path.Combine(temporaryDirectory, applicationGuid);

        try
        {
            // Prevents other processes from reading from or writing to this file
            var _InstanceLock = new FileStream(fileFulePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
            _InstanceLock.Lock(0, 0);
            MonoApp.Logger.LogToDisk(LogType.Notification, "04ZH-EQP0", "Aquired Lock", fileFulePath);

            // todo investigate why we need a reference to file stream. Without this GC releases the lock!
            System.Timers.Timer t = new System.Timers.Timer()
            {
                Interval = 500000,
                Enabled = true,
            };
            t.Elapsed += (a, b) =>
            {
                try
                {
                    _InstanceLock.Lock(0, 0);
                }
                catch
                {
                    MonoApp.Logger.Log(LogType.Error, "AOI7-QMCT", "Unable to lock file");
                }
            };
            t.Start();

        }
        catch
        {
            // Terminate application because another instance with this ID is running
            Environment.Exit(102534); 
        }
    }         
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.