学无先后达者为师!
不忘初心,砥砺前行。

开发 WPF 程序时,限制一次只能打开一个程序。

场景:如果程序 D 已被运行 进程 A,那么再次启动程序D 运行进程 B,B 会识别到已有相同的进程,此时 B 会将 A 窗口激活弹出来,然后 B 再退出。这样不仅可以限制只能运行一个进程,而且可以让用户体验更加好。

如果程序 D 在一台计算机的多个目录下有多个副本,那么最好可以准确的激活对应目录下的进程,防止启动新版本程序时反倒将旧版本程序激活的情况。

本文大部分内容修改自 痴者工良 的文章:疯狂吐槽 MAUI 以及 MAUI 入坑知识点 。代码仅支持 Windows 平台,无论 WinForm、WPF 或 MAUI 均兼容。

internal static class ProcessManager
{
    private static Mutex ProcessLock;
    private static bool HasLock;

    /// <summary>
    /// 获取进程锁
    /// </summary>
    public static void GetProcessLock()
    {
        // 全局锁,锁名称可以自定义。
        ProcessLock = new Mutex(false, $"Global\\LuYao.Toolkit[{GetUid()}]", out HasLock);

        if (!HasLock)
        {
            ActiveWindow();
            Environment.Exit(0);
        }
    }

    private static string GetUid()
    {
        var bytes = Encoding.UTF8.GetBytes(Assembly.GetExecutingAssembly().Location);
        using (var md5 = MD5.Create())
        {
            bytes = md5.ComputeHash(bytes);
        }
        return BitConverter.ToString(bytes);
    }

    /// <summary>
    /// 激活当前进程并将其窗口放到屏幕最前面
    /// </summary>
    public static void ActiveWindow()
    {
        using (var p = Process.GetCurrentProcess())
        {
            string pName = p.ProcessName;
            Process[] temp = Process.GetProcessesByName(pName);
            foreach (var item in temp)
            {
                if (item.MainModule.FileName == p.MainModule.FileName)
                {
                    IntPtr handle = item.MainWindowHandle;
                    SwitchToThisWindow(handle, true);
                    break;
                }
            }
        }
    }

    /// <summary>
    /// 释放当前进程的锁
    /// </summary>
    /// <remarks>小心使用</remarks>
    public static void ReleaseLock()
    {
        if (ProcessLock != null && HasLock)
        {
            ProcessLock.Dispose();
            HasLock = false;
        }
    }

    // 将另一个窗口激活放到前台。
    // Win32 API
    [DllImport("user32.dll")]
    public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
}

然后在程序启动时调用:

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    public App()
    {
        ProcessManager.GetProcessLock();
    }
}
赞(5) 打赏
未经允许不得转载:码农很忙 » 开发 WPF 程序时,限制一次只能打开一个程序。

评论 抢沙发

给作者买杯咖啡

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册