禁止软件多开的方法有很多种,但基本原理都是在软件启动入口检测现在运行的进程中有没有本软件的进程。整体实现思路分为一下两个步骤:
- 首先检查是否已经有软件开启了
- 将开启的软件窗口调至桌面最顶端
判断本程序是不是已经开启了
这里使用System.Threading.Mutex同步基元 Mutex 类 (System.Threading) | Microsoft Learn
/// <summary>
/// 重写启动方法
/// </summary>
protected override void OnStartup(StartupEventArgs e)
{
//创建一个Mutex对象,这里亦可以用Mutex(Boolean, String, Boolean)方法,
//第三个参数可以指示当前线程是否获取了所有权
mutex = new System.Threading.Mutex(true, "自行设置标识");
if (mutex.WaitOne(0, false))
{
base.OnStartup(e);
}
else
{
MessageBox.Show("程序已经在运行!", "提示");
this.Shutdown();
}
}
调用已经开启的窗口到桌面最前端
这里需要用到window的三个API:
SetForegroundWindow(IntPtr hWnd); 设置窗口到桌面最前端显示ShowWindow(IntPtr hWnd, int nCmdShow); 显示已经最小化的窗口FindWindow(string lpClassName, string lpWindowName); 寻找窗口句柄 其中寻找窗口句柄由很多中方法,可以直接从进程中获取。
/// <summary>
/// App.xaml 的交互逻辑
/// </summary>
public partial class App : Application
{
/// <summary>
/// 程序标识
/// </summary>
private static System.Threading.Mutex mutex;
private const int SW_SHOWNORMAL = 1;
private const int SW_RESTORE = 9;
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
protected override void OnStartup(StartupEventArgs e)
{
mutex = new System.Threading.Mutex(true, "WCTAMTool");
if (mutex.WaitOne(0, false))
{
base.OnStartup(e);
}
else
{
//Window的Title
string windowName = "你程序主窗口名称";
IntPtr mhw = FindWindow(null,windowName);
if (mhw != IntPtr.Zero)
{
//成功拿到窗口句柄
//这两个都要调用,只调用SetForegroundWindow时,当窗口最小化时没有效果
ShowWindow(mhw, SW_RESTORE);
SetForegroundWindow(mhw);
}
else
{
//没拿到给个提示
MessageBox.Show("程序已经在运行!", "提示");
}
this.Shutdown();
}
}
}