针对“解决C#程序只允许运行一个实例的几种方法详解”,这是一个常见的需求,我们可以通过以下几种方式来解决。
方法一:使用Mutex互斥量
互斥体是一种用于在进程之间进行同步的对象,也是实现单实例应用程序的首选方法之一。具体操作如下:
- 在Program.cs文件中创建一个Mutex对象。
static Mutex mutex = new Mutex(true, "MyApplication");
- 第一个参数为程序是否拥有Mutex的初始所有权,这里我们选择为“是”,即true。
-
第二个参数为Mutex的名称,这个名称需要很好地反映出应用程序的名称。
-
构造没有名称的Mutex会检查j此前是否已存在同名的Mutex。
static Mutex mutex;
static Program()
{
bool hasHandle = false;
try
{
mutex = new Mutex(true, "MyApplication", out hasHandle);
}
catch (Exception ex)
{
mutex = null;
MessageBox.Show(ex.ToString());
}
if (!hasHandle)
{
MessageBox.Show("MyApplication is already running.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(0);
}
}
方法二:使用Win32 API
使用Win32 API,利用InstallTask钩子函数进行回调。 在实现之前,需要在User32.dll中声明InstallTask钩子函数。具体操作如下:
- 声明如下:
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookHandler lpfn, IntPtr hInstance, int threadId);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll")]
private static extern int UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, ref CWPSTRUCT lParam);
const int WH_CALLWNDPROCRET = 12;
delegate IntPtr HookHandler(int nCode, IntPtr wParam, ref CWPSTRUCT lParam);
[StructLayout(LayoutKind.Sequential)]
public struct CWPSTRUCT
{
public IntPtr lParam;
public IntPtr wParam;
public int message;
public IntPtr hwnd;
}
- 在Program.cs文件中创建HOOK
class Program
{
static void Main(string[] args)
{
bool returnValue;
Mutex mutex = new Mutex(true, "MyApplication", out returnValue);
if (returnValue)
{
IntPtr hInstance = GetModuleHandle(null);
hookId = SetWindowsHookEx(WH_CALLWNDPROCRET, new HookHandler(MyHookProc), hInstance, 0);
Application.Run(new Form1());
UnhookWindowsHookEx(hookId);
mutex.ReleaseMutex();
}
else
{
MessageBox.Show("MyApplication is already running.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
static int hookId;
static IntPtr MyHookProc(int nCode, IntPtr wParam, ref CWPSTRUCT lParam)
{
if (lParam.message == WM_SHOWME)
{
Form1.Instance.WindowState = FormWindowState.Normal;
Form1.Instance.Activate();
}
return CallNextHookEx(IntPtr.Zero, nCode, wParam, ref lParam);
}
const int WM_SHOWME = 0x18;
}
上述两种方法非常容易实现,并且可以确保程序只运行一个实例。根据需要,可以选择一种方法来实现。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解决C#程序只允许运行一个实例的几种方法详解 - Python技术站