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

如何确保Inno Setup安装的应用仅运行单个实例?

实现单实例运行的两种可行方案

方案一:在程序内部实现(推荐,最稳定)

这是Windows平台实现单实例程序的标准做法,通过互斥量(Mutex)确保同一时间只有一个程序实例运行,无论用户通过何种方式启动程序都能生效。

以常见编程语言为例:

  • C#:在Program.cs的Main方法中添加互斥量检查逻辑:
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MyProg
{
    static class Program
    {
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

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

        [STAThread]
        static void Main()
        {
            const string UniqueMutexName = "MyProg_SingleInstance_Mutex";
            bool isNewInstance;
            using (var mutex = new Mutex(true, UniqueMutexName, out isNewInstance))
            {
                if (isNewInstance)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new MainForm());
                }
                else
                {
                    // 激活已有窗口并提示
                    var mainWindow = FindWindow(null, "MyProg主窗口标题");
                    if (mainWindow != IntPtr.Zero)
                    {
                        SetForegroundWindow(mainWindow);
                    }
                    MessageBox.Show("程序已在运行中!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }
    }
}
  • C++:在WinMain中添加互斥量检查:
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    const wchar_t* MutexName = L"MyProg_SingleInstance_Mutex";
    HANDLE hMutex = CreateMutexW(nullptr, TRUE, MutexName);
    
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        // 找到已有窗口并激活
        HWND hWnd = FindWindowW(nullptr, L"MyProg主窗口标题");
        if (hWnd)
        {
            ShowWindow(hWnd, SW_RESTORE);
            SetForegroundWindow(hWnd);
        }
        MessageBoxW(nullptr, L"程序已在运行中!", L"提示", MB_OK | MB_ICONINFORMATION);
        CloseHandle(hMutex);
        return 0;
    }

    // 正常初始化并运行程序
    // ...

    CloseHandle(hMutex);
    return 0;
}

方案二:通过Inno Setup修改快捷方式(无需修改程序)

如果无法修改MyProg.exe的代码,可以通过Inno Setup生成一个辅助脚本,让快捷方式先检查进程再启动程序。

1. 生成辅助VBScript

在脚本的[Code]段添加代码,安装完成后生成用于检查进程的VBScript:

[Code]
procedure CurStepChanged(CurStep: TSetupStep);
var
  VBSPath: string;
  VBSContent: string;
begin
  if CurStep = ssPostInstall then
  begin
    VBSPath := ExpandConstant('{app}\RunMyProgSingle.vbs');
    VBSContent := 
      'Set WMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")' + #13#10 +
      'Set Processes = WMI.ExecQuery("SELECT * FROM Win32_Process WHERE Name = ''MyProg.exe''")' + #13#10 +
      'If Processes.Count = 0 Then' + #13#10 +
      '  CreateObject("WScript.Shell").Run """' + ExpandConstant('{app}\MyProg.exe') + '""", 1, False' + #13#10 +
      'Else' + #13#10 +
      '  MsgBox "程序已在运行中!", vbInformation, "提示"' + #13#10 +
      'End If';
    SaveStringToFile(VBSPath, VBSContent, False);
  end;
end;

2. 修改快捷方式指向脚本

更新[Icons]段,让快捷方式调用wscript.exe运行刚才生成的VBScript:

[Icons]
Name: "{group}\MyProg"; Filename: "wscript.exe"; Parameters: """{app}\RunMyProgSingle.vbs"""; IconFilename: "app.ico"
Name: "{userdesktop}\MyProg"; Filename: "wscript.exe"; Parameters: """{app}\RunMyProgSingle.vbs"""; IconFilename: "app.ico"

3. 卸载时清理脚本

在[UninstallDelete]段添加,确保卸载时删除辅助脚本:

[UninstallDelete]
Type: files; Name: "{app}\RunMyProgSingle.vbs"

注意:这种方法依赖进程名检测,如果存在同名进程会有误判,若程序有唯一窗口标题,可以修改VBScript通过窗口标题检测来提高准确性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:35:38