You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#单实例程序实现:后台运行时通过快捷方式唤起主窗口

搞定C#单实例程序:隐藏后唤起的完美方案

嘿,这个需求我之前帮不少开发者解决过,咱们一步步来实现它——既要让程序关闭时隐藏到后台,又能在用户点击快捷方式时立刻唤起第一个实例。

核心思路拆解

  • 用**互斥体(Mutex)**确保程序只能启动一个实例
  • 处理窗体关闭事件,把“关闭”改成“隐藏”
  • 当第二个实例启动时,找到第一个实例的窗口,触发它显示并前置

具体代码实现

第一步:Program.cs里的单实例检测与唤起逻辑

首先用Mutex判断是否已有实例在运行,如果有,就找到它并唤起;没有的话就启动主窗体。这里提供两种唤起方式,第二种更可靠(避免窗体隐藏后句柄获取不到的问题)。

方式一:通过进程句柄直接唤起

using System;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace SingleInstanceDemo
{
    static class Program
    {
        // 替换成你自己的唯一GUID,避免和其他程序冲突
        private static readonly Mutex _instanceMutex = new Mutex(true, "{F5A0B987-1234-5678-90AB-CDEF12345678}");

        // Windows API声明
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private const int SW_RESTORE = 9; // 恢复最小化窗口
        private const int SW_SHOW = 5;    // 显示窗口

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            if (_instanceMutex.WaitOne(TimeSpan.Zero, true))
            {
                // 第一个实例,启动主窗体
                var mainForm = new MainForm();
                Application.Run(mainForm);
                _instanceMutex.ReleaseMutex();
            }
            else
            {
                // 找到已运行的实例并唤起
                var currentProcess = Process.GetCurrentProcess();
                foreach (var process in Process.GetProcessesByName(currentProcess.ProcessName))
                {
                    if (process.Id != currentProcess.Id)
                    {
                        // 先恢复(如果最小化),再前置
                        ShowWindow(process.MainWindowHandle, SW_RESTORE);
                        SetForegroundWindow(process.MainWindowHandle);
                        break;
                    }
                }
            }
        }
    }
}

方式二:自定义消息唤起(更可靠)

如果窗体隐藏后MainWindowHandle获取不到,就用自定义Windows消息通知第一个实例自己显示:
首先在Program.cs里添加API:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

// 自定义消息ID(范围0x0040到0x7FFF是应用程序自定义消息)
private const int WM_SHOW_INSTANCE = 0x0040 + 1;

然后在else块里替换成:

// 通过窗口标题找到第一个实例的主窗口
var mainWindowHandle = FindWindow(null, "MainForm"); // 替换成你的主窗体标题
if (mainWindowHandle != IntPtr.Zero)
{
    // 发送自定义消息让它显示
    SendMessage(mainWindowHandle, WM_SHOW_INSTANCE, IntPtr.Zero, IntPtr.Zero);
}

然后在主窗体MainForm.cs里监听这个消息:

using System.Windows.Forms;

namespace SingleInstanceDemo
{
    public partial class MainForm : Form
    {
        private const int WM_SHOW_INSTANCE = 0x0040 + 1;

        public MainForm()
        {
            InitializeComponent();
        }

        // 重写WndProc监听自定义消息
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_SHOW_INSTANCE)
            {
                ShowAndBringToFront();
            }
            base.WndProc(ref m);
        }

        private void ShowAndBringToFront()
        {
            // 恢复窗口状态
            if (WindowState == FormWindowState.Minimized)
            {
                WindowState = FormWindowState.Normal;
            }
            // 显示并前置
            Show();
            BringToFront();
        }

        // 处理窗体关闭事件,改成隐藏
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 取消默认关闭行为
            e.Cancel = true;
            // 隐藏窗体到后台
            Hide();
        }
    }
}

关键注意事项

  • 唯一GUID:Mutex的名称一定要用唯一的GUID,防止和其他程序冲突
  • 窗体关闭事件:一定要在FormClosing里取消关闭并调用Hide(),不要用FormClosed(那时已经晚了)
  • 权限问题:如果程序需要管理员权限,确保Mutex的权限设置正确(避免普通用户和管理员用户各启动一个实例)

内容的提问来源于stack exchange,提问作者Harman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:17:40