限制只运行一个实例的问题(同样的文件名不同的配置)
一个根目录下,有几个文件夹,每个文件夹下都有一个执行文件player.exe和Set.ini配置文件,Set.ini里面有窗口的标题、大小、坐标等信息,程序创建时调用Set.ini文件,来显示不同的信息,现在想要每个文件夹下的执行文件只运行一个实例,如果该程序运行了,则将该程序置顶显示出来(窗口本身已置顶,每个文件夹下的执行文件运行后,窗口的标题都不相同);简单的置顶、互斥、原子方法都达不到效果,C#里可以用进程名称+路径来判断,在delphi里面如果设置这个条件。 实例
[解决办法]
同一个exe,复制到不同的子目录
同一个子目录的exe只能同时运行一个,不同子目录的exe可以同时运行着?
创建互斥对象时,以子目录完整路径的hash值作为对象名
[解决办法]
照下边的项目文件改, 已经在delphiXE下测试通过
如果是低版本的delphi程序, 用其他方法代替Base64EncodeString编码即可
program Project6;
uses
Forms, Windows,
EBase64,
Unit8 in 'Unit8.pas' {Form8};
{$R *.res}
var
HMutex:Hwnd;
begin
Application.Initialize;
//根据你的描述, 提取可执行程序的路径进行base64编码, 然后建立互斥对象
//使用base64编码是为过滤特殊符号
HMutex:=CreateMutex(nil,False,Pchar(Base64EncodeString(Application.ExeName)));
If GetLastError <> ERROR_ALREADY_EXISTS Then //互斥对象创建成功
begin
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm8, Form8);
end
else //互斥对象已存在
begin
Application.MessageBox(pchar('相同路径下的同名实例已创建!' + char(13) +
'文件路径:'+Application.ExeName + char(13) +
'base64编码:'+Base64EncodeString(Application.ExeName)
), pchar('提示'), mb_ok+mb_iconinformation);
ReleaseMutex(hMutex);
end;
Application.Run;
end.
program Project1;
uses
Forms,
Windows,
IdHashMessageDigest,
IdGlobal,
IdHash,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
HMutex:Hwnd;
MyMD5: TIdHashMessageDigest5;
Digest: T4x4LongWordRecord;
begin
Application.Initialize;
MyMD5 := TIdHashMessageDigest5.Create;
Digest := MyMD5.HashValue(Application.ExeName);
//根据你的描述, 提取可执行程序的路径进行base64编码, 然后建立互斥对象
HMutex:=CreateMutex(nil,False,Pchar(MyMD5.AsHex(Digest)));
If GetLastError <> ERROR_ALREADY_EXISTS Then //互斥对象创建成功
begin
Application.CreateForm(TForm1, Form1);
end
else //互斥对象已存在
begin
Application.MessageBox(pchar('相同路径下的同名实例已创建!' + char(13) +
'文件路径:'+Application.ExeName + char(13) +
'MD5编码:'+ MyMD5.AsHex(Digest)
), pchar('提示'), mb_ok+mb_iconinformation);
ReleaseMutex(hMutex);
end;
Application.Run;
end.