2011-03-21 16 views
14

काम नहीं कर रहा है मैं अपने ऐप के एक उदाहरण को चलाने की अनुमति देने के लिए mutex विधि का उपयोग करने की कोशिश कर रहा हूं। यही है - मैं केवल मशीन पर सभी उपयोगकर्ताओं के लिए अधिकतम एक उदाहरण चाहता हूं। मैंने इस मुद्दे पर विभिन्न अन्य धागे के माध्यम से पढ़ा है और समाधान काफी सरल लगता है लेकिन परीक्षण में मुझे अपना दूसरा उदाहरण चलाने के लिए नहीं मिल सकता है। यहाँ मेरी कोड ...एकल ऐप उदाहरण के लिए WPF mutex

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     // check that there is only one instance of the control panel running... 
     bool createdNew = true; 
     using (Mutex instanceMutex = new Mutex(true, @"Global\ControlPanel", out createdNew)) 
     { 
      if (!createdNew) 
      { 
       Application.Current.Shutdown(); 
       return; 
      } 
     } 

     base.OnStartup(e); 
    } 
} 

उत्तर

29

तुम भी एक ही विधि में म्युटेक्स निपटाने रहे हैं ताकि म्युटेक्स केवल विधि की अवधि के लिए रहता है,। एक स्थिर क्षेत्र में mutex स्टोर करें, और अपने आवेदन की अवधि के लिए इसे जीवित रखें।

+0

+1। हां मुझे इसे हराया;) –

+2

धन्यवाद @ विलेम वैन रूम्प्ट (और @ ओजे)। यह काम करता है। मैंने गलती से सोचा कि म्यूटेक्स वास्तव में दृश्यों के पीछे कुछ था, सिस्टम स्तर पर और म्यूटेक्स ऑब्जेक्ट उदाहरण महत्वपूर्ण नहीं था।मैंने भविष्य में संदर्भ के लिए नीचे अपना नया कोड शामिल किया है ... – flobadob

+0

@ ओजे: परिवर्तन के लिए "जीतने" पक्ष पर होना अच्छा है :) –

4

आप इसे बनाने और परीक्षण करने के तुरंत बाद म्यूटेक्स को नष्ट कर रहे हैं। आपको अपने आवेदन के जीवनकाल के लिए म्यूटेक्स संदर्भ को जीवित रखने की आवश्यकता है।

म्यूटेक्स को अपनी एप्लिकेशन क्लास का सदस्य/फ़ील्ड बनाएं। जब आपका एप्लिकेशन बंद हो जाता है तो म्यूटेक्स को छोड़ दें।

25

यह मेरा नया कोड है जो @Willem वैन रुम्प्ट (और @OJ) द्वारा प्रदान की जवाब है ...

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

    protected override void OnStartup(StartupEventArgs e) 
    { 
     // check that there is only one instance of the control panel running... 
     bool createdNew; 
     _instanceMutex = new Mutex(true, @"Global\ControlPanel", out createdNew); 
     if (!createdNew) 
     { 
      _instanceMutex = null; 
      Application.Current.Shutdown(); 
      return; 
     } 

     base.OnStartup(e); 
    } 

    protected override void OnExit(ExitEventArgs e) 
    {   
     if(_instanceMutex != null) 
      _instanceMutex.ReleaseMutex(); 
     base.OnExit(e); 
    } 
} 
1

मैं एक अधिक स्वच्छ तरीके को अधिभावी की उपयोगी अवधारणा लागू कर सकते हैं सुझाव है डब्ल्यूपीएफ आवेदन में मुख्य विधि। साथ ही, यदि आप अपने समाधान का उपयोग करते हैं तो आप कार्य प्रबंधक को देखेंगे, आप देखेंगे कि नया उदाहरण वास्तव में निष्पादन स्थिति तक पहुंचता है (आप कार्य की सूची में बनाई गई एक नई प्रक्रिया देख सकते हैं) और फिर अचानक बंद हो जाएं। इस पोस्ट में प्रस्तावित दृष्टिकोण इस दोष से भी बच जाएगा। http://blog.clauskonrad.net/2011/04/wpf-how-to-make-your-application-single.html

0

मैं इस लिंक से ऐसा किया केवल आपके App.Xaml.cs http://wpfsingleinstance.codeplex.com/

public partial class App : Application  
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     WpfSingleInstance.Make(); //added this is the function of that class 
     base.OnStartup(e); 
    } 
} 
1

में दिए गए वर्ग और एक लाइन जोड़ने मैं एक पहले से ही विकसित WPF पर इस म्युटेक्स दृष्टिकोण को लागू करने के लिए कहा गया था हमारे पास आवेदन था। कि मैंने पाया OnStart() की ओवरराइड का उपयोग कर के साथ समस्या के आसपास काम

App.g.cs 

इस फ़ाइल

obj\x86\debug\ 

में स्थित है में था और main() समारोह में शामिल है, तो आप बस के इस टुकड़े डाल आपके मुख्य समारोह में कोड।

bool isOnlyInstance = false; 
Mutex m = new Mutex(true, @"WpfSingleInstanceApplication", out isOnlyInstance); 
if (!isOnlyInstance) 
{ 
    MessageBox.Show("Another Instance of the application is already running.", 
        "Alert", 
        MessageBoxButton.OK, 
        MessageBoxImage.Exclamation); 
    return; 
} 
GC.KeepAlive(m); 

लेकिन यह आप के लिए ApplicationDefinition

नोट अपने App.xaml सेट के BUILD ACTION रखने की जरूरत के लिए: यह सबसे अच्छा तरीका है नहीं हो सकता है, के बाद से मैं अभी शुरुआत कर रहा हूँ। (वहाँ कुछ मैं बदलना चाहिए अगर कृपया मुझे बताओ)

2

विस्तार नमूना के रूप में:

public static class Extension 
{ 
    private static Mutex mutex; 

    public static bool IsOneTimeLaunch(this Application application, string uniqueName = null) 
    { 
     var applicationName = Path.GetFileName(Assembly.GetEntryAssembly().GetName().Name); 
     uniqueName = uniqueName ?? string.Format("{0}_{1}_{2}", 
      Environment.MachineName, 
      Environment.UserName, 
      applicationName); 

     application.Exit += (sender, e) => mutex.Dispose(); 
     bool isOneTimeLaunch; 
     mutex = new Mutex(true, uniqueName, out isOneTimeLaunch); 
     return isOneTimeLaunch; 
    } 
} 

अनुप्रयोग वर्ग:

protected override void OnStartup(StartupEventArgs e) 
    { 
     if (this.IsOneTimeLaunch()) 
     { 
      base.OnStartup(e); 
     } 
     else 
     { 
      this.Shutdown(); 
     } 
    } 
+0

प्रत्येक उपयोगकर्ता के लिए अद्वितीय नाम के लिए +1। – slavoo

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