从其它平台迁移而来


有时候我们会期望所编写的应用只运行一个实例,比如监听网络端口或串口,用Lazarus有两种不同的实现方案。

SingleInstanceEnabled属性

SingleInstanceEnabledTCustomApplication的属性,在初始化之前设置为True即可轻松实现单实例应用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
program project1;

{$mode objfpc}{$H+}

uses
  AdvancedSingleInstance, //注意:必须引用该单元!!!
  Interfaces,
  Forms,
  ...;

{$R *.res}

begin
  Application.SingleInstanceEnabled := True; //注意:必须在调用 Initialize 前赋值!!!
  Application.Initialize;
  ...
  Application.Run;
end.

特别注意

  • 必须引用AdvancedSingleInstance单元,且该单元必须在Interfaces单元和Forms单元前

  • 必须在调用Application.Initialize前赋值

  • 该方法仅针对同一个可执行文件生效,并非系统全局生效

互斥对象

利用操作系统的互斥对象可实现系统级的单例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var
  AppMutex: THandle;

begin
  Application.Initialize;
  if OpenMutex(MUTEX_ALL_ACCESS, False, PChar('唯一标识')) = 0 then
  begin
    AppMutex := CreateMutex(nil, False, PChar('唯一标识'));
    ...
    Application.Run;
    CloseHandle(AppMutex);
  end
  else
    Application.Terminate;
end.

特别注意

  • 唯一标识必须唯一,否则,即使完全不同的应用也只能运行其中一个