您现在的位置是:首页 > 编程 > 

.ET桌面应用保持程序唯一性打开的一种方式

2025-07-27 06:53:52
.ET桌面应用保持程序唯一性打开的一种方式 在开发桌面应用程序时,可能会遇到这样一种需求:限制程序只能同时运行一个实例。如果用户试图再次启动同一个程序,应该将已经运行的程序窗口置于前台而不是启动一个新实例。这篇文章提供了一种通过检测当前程序实例并激活已运行实例的方法。核心思路检查是否已有程序实例运行 使用 System.Diagnostics.Process 获取当前程序进程,并与系统中所有同名

.ET桌面应用保持程序唯一性打开的一种方式

在开发桌面应用程序时,可能会遇到这样一种需求:限制程序只能同时运行一个实例。如果用户试图再次启动同一个程序,应该将已经运行的程序窗口置于前台而不是启动一个新实例。这篇文章提供了一种通过检测当前程序实例并激活已运行实例的方法。


核心思路

  1. 检查是否已有程序实例运行 使用 System.Diagnostics.Process 获取当前程序进程,并与系统中所有同名的程序进程进行比较。如果发现另一个同名进程,则认为程序已经运行。
  2. 激活已运行的程序窗口 如果发现已有实例运行,使用 Win2 API 操作将其窗口置于前台,避免用户启动多个实例。
  3. 运行主程序逻辑 如果没有其他实例运行,正常启动主程序。

代码解析

1. 检查是否已有程序运行

以下代码通过进程名称筛选当前运行的程序进程列表,返回除当前进程外的其他同名进程(如果存在):

代码语言:javascript代码运行次数:0运行复制
public static Process GetExistProcess()
{
    Process currentProcess = Process.GetCurrentProcess(); // 当前程序
    foreach (Process process in Process.GetProcessesByame(currentProcess.Processame))
    {
        if (process.Id != currentProcess.Id) // 到其他同名进程
        {
            return process; // 返回已运行的进程
        }
    }
    return null; // 没有其他实例
}
2. 主程序入口

Main 方法中调用 GetExistProcess 检查程序实例:

代码语言:javascript代码运行次数:0运行复制
static classProgram
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        var runningProcess = GetExistProcess();
        if (runningProcess != null) // 如果有实例运行
        {
            IntPtr mainWindowHandle = runningProcess.MainWindowHandle;
            if (mainWindowHandle == IntPtr.Zero) // 窗口被隐藏
            {
                mainWindowHandle = FindWindow(null, "唯一程序");
            }
            ShowWindowAsync(mainWindowHandle, ); // 显示窗口
            SetForegroundWindow(mainWindowHandle); // 置于前台
        }
        else
        {
            Application.Run(new MainForm()); // 启动新实例
        }
    }
}
. Win2 API 调用

以下是关键的 Win2 API 函数,用于操作窗口显示和前台设置:

代码语言:javascript代码运行次数:0运行复制
[DllImport("User2.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassame, string lpWindowame);

[DllImport("user2.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

[DllImport("user2.dll ")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
  • FindWindow: 根据窗口名称查窗口句柄。
  • ShowWindowAsync: 显示或隐藏窗口。
  • SetForegroundWindow: 将窗口设置为前台窗口。

注意事项

  1. 窗口名称匹配问题 如果窗口标题动态变化,FindWindow 的效果可能不佳,需保证窗口标题唯一或改用其他识别方法。
  2. 权限问题 如果以管理员权限运行程序,SetForegroundWindow 操作可能会被限制。需要确保权限一致。
  3. 多线程问题 如果程序使用了多线程,需注意线程间的窗口操作同步。

优化建议

使用互斥量 利用 Mutex 可以更简洁地实现程序唯一性。例如:

代码语言:javascript代码运行次数:0运行复制
static Mutex mutex = new Mutex(true, "UniqueAppame", out bool createdew);
if (!createdew)
{
    // 已经有实例运行
    return;
}

窗口句柄缓存 可以在程序启动时缓存主窗口句柄,避免频繁调用 FindWindow

日志记录 在实际应用中建议记录重复启动的尝试,以便后续调试和优化。


总结

这是一种基于进程和 Win2 API 的方法来保持程序唯一性的解决方案。代码逻辑清晰,适用于大多数桌面应用场景。如果你有更复杂的需求或更高的性能要求,建议结合互斥量或现代框架特性来实现更可靠的方案。

参考来源:

本文参与 腾讯云自媒体同步曝光计划,分享自。原始发表:2025-01-01,如有侵权请联系 cloudcommunity@tencent 删除多线程进程权限缓存程序

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1204105.html

相关标签:无
上传时间: 2025-07-24 06:18:34
留言与评论(共有 9 条评论)
本站网友 成人身份证和姓名
22分钟前 发表
日志记录 在实际应用中建议记录重复启动的尝试
本站网友 孕妇可以吃桑葚吗
26分钟前 发表
out bool createdew); if (!createdew) { // 已经有实例运行 return; } 窗口句柄缓存 可以在程序启动时缓存主窗口句柄
本站网友 鲜竹沥液
30分钟前 发表
"唯一程序"); } ShowWindowAsync(mainWindowHandle
本站网友 网易每日轻松一刻
28分钟前 发表
EntryPoint = "FindWindow")] public static extern IntPtr FindWindow(string lpClassame
本站网友 爱迪生的发明
12分钟前 发表
并与系统中所有同名的程序进程进行比较
本站网友 vde证书查询
9分钟前 发表
应该将已经运行的程序窗口置于前台而不是启动一个新实例
本站网友 创明遮阳
14分钟前 发表
string lpWindowame); [DllImport("user2.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd
本站网友 会阴图片
26分钟前 发表
"唯一程序"); } ShowWindowAsync(mainWindowHandle