如何确保只运行我的应用程序的单个实例?

mj2*_*008 26 delphi delphi-xe

Delphi XE VCL是否支持确保只运行单个应用程序实例?

在过去,我使用库代码来控制一直看起来很复杂的Mutex.当我在Delphi XE中开始一个新项目时,我想知道是否需要挖掘旧代码,或者是否已经在XE中内置了支持?或者是否有另一个易于应用的代码,既漂亮又现代?

Cos*_*und 36

您在启动应用程序时创建一个命名的Mutex.检查GetLastError其他实例是否已在运行.

将此代码放在DPR文件中的"begin"之后.用您自己的GUID替换GUID.当我需要一个不太可能用于其他任何东西的文本常量时,我​​通常只需按Ctrl+ G即可获得GUID!

if CreateMutex(nil, True, '6EACD0BF-F3E0-44D9-91E7-47467B5A2B6A') = 0 then
  RaiseLastOSError;

if GetLastError = ERROR_ALREADY_EXISTS then
  Exit;
Run Code Online (Sandbox Code Playgroud)

它可能看起来像代码泄漏一个句柄,因为它没有保存返回CreateMutex.不是.当我们的应用程序终止时,Windows将自动释放句柄,这对我们来说绝对没问题.

  • 这将在会话命名空间中创建互斥锁.不同会话中的进程(想想快速用户切换)将能够在另一个会话中的进程正在运行时启动新进程.您可以使用Global \作为名称的前缀,以在全局命名空间中获取互斥锁. (7认同)
  • 大卫好点.但是,也许这种行为(会话命名空间)可能是一些开发人员真正想要的,即使他们没有想到这一点.想象一下,您希望部署一个可以使用Windows终端服务运行的富数据库客户端应用程序,您可以使用一个应用程序,每个桌面而不是一台应用程序每台计算机. (6认同)
  • 对于两行Windows API,您不需要特定的"Delphi XE"支持.确保将"Windows"和"SysUtils"添加到DPR的uses子句中. (4认同)
  • +1直接转到VCL和Win API而不是JCL.JCL没有错,但为什么在没有必要时使用外部工具?我们在我们的商店使用这种解决方案多年没有问题.对于不同的用户,正如您所提到的,通常这就是您想要的 - 不同的用户**应该**获得不同的会话/实例. (3认同)
  • 更简单的例子:想象一下,你为你的下一个大聊天计划实现了这一点; 妻子来到电脑,实际上做"切换用户"(我的妻子做!)并登录到她的帐户,尝试启动下一个大聊天程序.Oooops!无论如何,好的观点大卫,无论如何每个人都应该阅读文档. (2认同)

Cló*_*ior 25

我使用JCL来做到这一点:

program MyProgram;

uses
  JclAppInst;

begin
  JclAppInstances.CheckSingleInstance; // Added instance checking
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end.
Run Code Online (Sandbox Code Playgroud)

有关此文档和通知方案的文档位于JCL Wiki.