zl程序教程

您现在的位置是:首页 >  .Net

当前栏目

WPF程序开发-保证程序启动唯一

2023-03-20 14:52:53 时间

前言

要保证程序唯一,有两种方式

  1. 新程序启动时发现已启动就自动退出
  2. 新程序启动发现已启动关闭之前的程序

关闭新进程

根据进程

protected override void OnStartup(StartupEventArgs e)
{
    checkProcess();
}

private void checkProcess()
{
    Console.WriteLine("程序启动");
    //获取欲启动进程名
    string ProcessName = Process.GetCurrentProcess().ProcessName;
    //检查进程是否已经启动,已经启动则显示报错信息退出程序。
    if (Process.GetProcessesByName(ProcessName).Length > 1)
    {
        MessageBox.Show("当前程序已在运行,请勿重复运行。");
        Environment.Exit(1);//退出程序
        return;
    }
}

互斥锁

private void checkProcess()
{
    //控制当前程序已经打开(即启动)
    //利用Mutex互斥量实现同时只有一个进程实例在运行
    //互斥锁(Mutex)
    //互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它。
    //互斥锁可适用于一个共享资源每次只能被一个线程访问的情况
    bool flag;
    string ProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
    Mutex hMutex = new Mutex(true, ProcessName, out flag);
    hMutex.WaitOne(0, false);
    //上面的参数说明:
    //第一个参数【initiallyOwned】:true:指示调用线程是否应具有互斥体的初始所有权
    //第二个参数【name】:程序唯一name,(当前操作系统中)判定重复运行的标志
    //第三个参数【createdNew】:返回值,如果检测到已经启动则返回(false)。
    if (!flag)
    {
        MessageBox.Show("当前程序已在运行,请勿重复运行。");
        Environment.Exit(1);//退出程序
        return;
    }
}

根据事件

private void checkProcess()
{
    Console.WriteLine("程序启动");
    bool createNew;
    string strProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
    new EventWaitHandle(false, EventResetMode.AutoReset, strProcessName, out createNew);

    if (!createNew)
    {
        MessageBox.Show("当前程序已在运行,请勿重复运行。");
        Current.Shutdown();
        Environment.Exit(0);
        return;
    }
}

关闭旧进程

private static void StopSameProcess()
{
    var current = Process.GetCurrentProcess();
    string strProcessName = current.ProcessName;
    var processList = Process.GetProcessesByName(strProcessName);
    foreach (var process in processList)
    {
        if (process.Id == current.Id) continue;
        try
        {
            MessageBox.Show("当前程序已在运行,请勿重复运行。");
            process.Kill(); //结束进程
        }
        catch (Exception)
        {
        }
    }
}

让进程对应的窗口显示

[DllImportAttribute("User32.dll")]
private static extern int FindWindow(String ClassName, String WindowName);

[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(int hWnd);

public static void DoOnProcess(string processName)
{
    var allProcs = Process.GetProcessesByName(processName);
    if (allProcs.Length > 0)
    {
        Process proc = allProcs[0];
        int hWnd = FindWindow(null, proc.MainWindowTitle.ToString());
        SetForegroundWindow(hWnd);
    }
}

两者结合

关闭新进程,旧进程窗口获取焦点

[DllImportAttribute("User32.dll")]
private static extern int FindWindow(String ClassName, String WindowName);

[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(int hWnd);

private void checkProcess()
{
    Console.WriteLine("程序启动");
    Process current = Process.GetCurrentProcess();
    //获取欲启动进程名
    string strProcessName = Process.GetCurrentProcess().ProcessName;
    var processList = Process.GetProcessesByName(strProcessName);
    if (processList.Length > 1)
    {
        MessageBox.Show("当前程序已在运行,请勿重复运行。");
        foreach (var process in processList)
        {
            if (process.Id == current.Id) continue;
            int hWnd = FindWindow(null, process.MainWindowTitle.ToString());
            SetForegroundWindow(hWnd);
        }
        Environment.Exit(1);//退出程序
        return;
    }
}