2011-06-26 22 views
17

संभव डुप्लिकेट सुनिश्चित करना:
What is the correct way to create a single instance application?केवल एक ही आवेदन उदाहरण

मैं एक winforms अनुप्रयोग है, जो निम्नलिखित कोड के माध्यम से एक स्प्लैश स्क्रीन की शुरूआत है:

Hide(); 
     bool done = false; 
     // Below is a closure which will work with outer variables. 
     ThreadPool.QueueUserWorkItem(x => 
            { 
             using (var splashForm = new SplashScreen()) 
             { 
              splashForm.Show(); 
              while (!done) 
               Application.DoEvents(); 
              splashForm.Close(); 
             } 
            }); 

     Thread.Sleep(3000); 
     done = true; 

उपरोक्त मुख्य रूप के कोडबेंड में है और लोड इवेंट हैंडलर से बुलाया गया है।

हालांकि, मैं कैसे सुनिश्चित कर सकता हूं कि एक समय में एप्लिकेशन का केवल एक उदाहरण लोड होगा? मुख्य रूप के लोड इवेंट हैंडलर में, मैं जांच सकता हूं कि प्रक्रिया सूची सिस्टम पर है (GetProcessesByName (...) के माध्यम से), लेकिन क्या कोई बेहतर तरीका है?

.NET 3.5 का उपयोग करना।

+1

आप बुलाना चाहिए 'Application.Run (splashForm)' बजाय एक 'DoEvents की()' पाश। – SLaks

उत्तर

50

GetProcessesByName यह जांचने का धीमा तरीका है कि कोई अन्य उदाहरण चल रहा है या नहीं। सबसे तेजी से और सुरुचिपूर्ण विधि म्युटेक्स उपयोग कर रहा है:

[STAThread] 
    static void Main() 
    { 
     bool result; 
     var mutex = new System.Threading.Mutex(true, "UniqueAppId", out result); 

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

     Application.Run(new Form1()); 

     GC.KeepAlive(mutex);    // mutex shouldn't be released - important line 
    } 

कृपया यह भी ध्यान में रखना है कि कोड आप प्रस्तुत सबसे अच्छा तरीका नहीं है। चूंकि इसे लूप में DoEvents() को कॉल करने वाली टिप्पणियों में से एक में सलाह दी गई थी, यह सबसे अच्छा विचार नहीं है।

+0

जीसी.किप अलाइव (म्यूटेक्स); - कुछ कारणों से मेरे लिए काम नहीं करता है। मुझे निजी स्थैतिक म्यूटेक्स का उपयोग करने के लिए छोड़ दिया गया था; – monstr

+0

मैं गलत हो सकता हूं, लेकिन 'जीसी.किपअलीव (म्यूटेक्स) नहीं होना चाहिए;' लाइन 'आवेदन से पहले हो। रुन (नया फॉर्म 1());'? 'Application.Run()' विधि प्रोग्राम के संदेश लूप को शुरू करती है और 'फॉर्म 1' बंद होने तक वापस नहीं आती है। –

+0

@AlexB .: नहीं, यह उद्देश्य पर है। लक्ष्य म्यूटेक्स को रिहा होने से रोकने के लिए है, जो तब हो सकता है जब कोई नया फॉर्म खोला जाता है और फॉर्म 1 बंद हो जाता है। फॉर्म 1 बंद होने से पहले म्यूटेक्स को – michalczerwinski

16
static class Program 
{ 
    // Mutex can be made static so that GC doesn't recycle 
    // same effect with GC.KeepAlive(mutex) at the end of main 
    static Mutex mutex = new Mutex(false, "some-unique-id"); 

    [STAThread] 
    static void Main() 
    { 
     // if you like to wait a few seconds in case that the instance is just 
     // shutting down 
     if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false)) 
     { 
      MessageBox.Show("Application already started!", "", MessageBoxButtons.OK); 
      return; 
     } 

     try 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
     finally { mutex.ReleaseMutex(); } // I find this more explicit 
    } 
} 

कुछ अद्वितीय-आईडी के बारे में एक नोट -> यह मशीन पर अद्वितीय होना चाहिए, इसलिए अपनी कंपनी के नाम/एप्लिकेशन नाम की तरह कुछ उपयोग करें।

संपादित करें:

http://sanity-free.org/143/csharp_dotnet_single_instance_application.html

संबंधित मुद्दे