2009-12-15 37 views
0

我一直在成功地創建一個.net互斥體,如下所示: SingleIns = new Mutex(true,AppName); 一段時間。它適用於XP,Vista,但顯然不適用於Windows7。所以我需要對Win32庫進行互操作,以便其他Com組件可以識別互斥鎖。我發現了下面的代碼,但是Win32Calls。沒有找到...有我需要的裝配或參考嗎? 由於提前,如何從.Net打電話給win32 CreateMutex

實測值代碼:使用System.Runtime.InteropServices http://www.pinvoke.net/default.aspx/kernel32/CreateMutex.html

;

[DllImport("kernel32.dll")] 
    public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitialOwner, string lpName); 


     // create IntPtrs for use with CreateMutex() 
     IntPtr ipMutexAttr = new IntPtr(0); 
     IntPtr ipHMutex = new IntPtr(0); 

     try 
     { 
      // Create the mutex and verify its status BEFORE construction 
      // of the main form. 

      ipHMutex = Win32Calls.CreateMutex(ipMutexAttr, 
       true, "CompanyName_AppName_MUTEX"); 

      if (ipHMutex != (IntPtr)0) 
      { 
       // check GetLastError value (MUST use this call. See MSDN) 

       int iGLE = Marshal.GetLastWin32Error(); 

       // if we get the ERROR_ALREADY_EXISTS value, there is 
       // already another instance of this application running. 

       if (iGLE == Win32Calls.ERROR_ALREADY_EXISTS) 
        // So, don't allow this instance to run. 
        return; 
      } 
      else  
      { // CreateMutex() failed. 
       // once the app is up and running, I log the failure from 
       // within the frmMain constructor. 
       bool m_bMutexFailed = true; 
      } 

      // construct the main form object and 
      //form = new frmMain(); 

      // run the app. 
      //Application.Run(form); 

     } 
     catch(Exception oEx) 
     { 
      //...handle it... 
     } 
     finally 
     { 
      // release the mutex 
      if (ipHMutex != (IntPtr)0) 
       Win32Calls.ReleaseMutex(ipHMutex); 

      // cleanup the main form object instance. 
      if (form != null) { 
       form.Dispose(); 
      } 
     } 
    } 
+0

嗯。我剛剛刪除了Win32Calls.CreateMutex的Win32Calls部分,並將其命名爲CreateMutex direct ...似乎可能會起作用 – mytwocents 2009-12-15 00:36:45

+0

您是否使用64位版本的Windows 7? .NET'Mutex'應該在Windows 7中基本上與以前的版本一樣。 – 2009-12-15 00:49:59

+0

這是一個更好的參考... http://msdn.microsoft.com/en-us/library/microsoft.win32.safehandles.safewaithandle.aspx – mytwocents 2009-12-15 01:06:45

回答

2

它不工作是因爲你CreateMutex聲明不是在Win32Calls命名空間。您的下一個問題是它仍然無法工作,因爲您忘記在[DllImport]屬性中設置SetLastError屬性。使Marshal.GetLastWin32Error()返回錯誤是必需的。

倒退了一下,使用Win7中的Mutex類應該沒有問題。我能想到的唯一失敗模式不是將互斥體名稱作爲「Global」的前綴,因此互斥體在所有會話中都可見。這有點遙遠。

更重要的是,你正在嘗試做一些已經在.NET框架中得到很好支持的東西。 Project +添加引用,選擇Microsoft.VisualBasic。讓你的Program.cs中的代碼如下所示:

using System; 
using System.Windows.Forms; 
using Microsoft.VisualBasic.ApplicationServices; 

namespace WindowsFormsApplication1 { 
    class Program : WindowsFormsApplicationBase { 
    [STAThread] 
    static void Main(string[] args) { 
     var prog = new Program(); 
     prog.EnableVisualStyles = true; 
     prog.IsSingleInstance = true; 
     prog.MainForm = new Form1(); 
     prog.Run(args); 
    } 
    } 
} 

本辦法獎勵的好東西是當用戶再次啓動它,它會自動將焦點設置到你的程序的運行實例。你可以重寫OnStartupNextInstance方法來知道使用了哪些命令行參數並作出相應的響應。

1

如果它可能對您有所幫助,.NET Framework已經提供了Win32互斥體對象的封裝。見System.Threading.Mutex。所有的主要功能都在那裏,包括使用像「Global」這樣的前綴的能力。

+0

問題是可用於XP和Vista的.Net Mutex,Windows 7的非託管程序(C++)沒有檢測到該問題。在Windows 7上,GetLastError()始終返回ERROR_SUCCESS是否存在互斥鎖。所以,我試圖改變我稱之爲互斥體的方式來適應本機C++代碼。注意:.NET的.net互斥體在Windows 7上工作正常。互操作互斥量互斥體的.net互斥體是失敗的......可能在C++端。 – mytwocents 2009-12-15 02:39:55

+0

我認爲問題不在於Windows 7中的互斥體並未以全局公認的方式創建,因爲服務正在創建該互斥體。我已將「Global \」附加到互斥體名稱上,因爲有些帖子指出它們適用於它們。但是,這對我也不起作用。 (該服務創建的互斥體並未顯示在ProcessExplorer查找句柄中,但我知道它在那裏,因爲如果我運行相同的程序,互斥體會激活它已經創建的。)微軟,服務和互斥體發生了什麼? – mytwocents 2009-12-17 01:32:18