我已经成功创建了这样的.net互斥锁: SingleIns = new Mutex(true,AppName); 一阵子。它适用于XP,Vista,但显然不适用于Windows7。所以我需要对Win32库进行互操作调用,以便其他Com组件可以识别互斥锁。我找到了以下代码,但Win32Calls。找不到......我需要一个装配或参考吗? 提前谢谢,
找到的代码来自: http://www.pinvoke.net/default.aspx/kernel32/CreateMutex.html
使用System.Runtime.InteropServices;
[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 :(得分:2)
它不起作用是因为您的CreateMutex声明不在Win32Calls命名空间中。您的下一个问题是它仍然无法工作,因为您忘记在[DllImport]属性中设置SetLastError属性。需要使Marshal.GetLastWin32Error()返回错误。
使用Win7中的Mutex类重绕一点应该没有问题。我能想到的唯一失败模式是没有为互斥锁名称加上“Global”前缀,因此互斥锁在所有会话中都可见。那有点偏僻。
更重要的是,您正在尝试做一些已经在.NET框架中得到很好支持的事情。 Project + Add Reference,选择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 :(得分:1)
如果它可能对您有所帮助,.NET Framework已经提供了Win32互斥对象的包装器。见System.Threading.Mutex。所有主要功能都在那里,包括使用“Global \”等前缀的能力。
答案 2 :(得分:0)
应该像这样简单:
private static System.Threading.Mutex _mutex = null;
const string guid = "{...GUID...}";
bool createdNew;
_mutex = new Mutex(true, guid, out createdNew);
if (!createdNew) {
// it is in use already
}
创建系统互斥量-所有权:https://stackoverflow.com/a/3111740/1644202