我知道以前做过这件事,但似乎想不起来怎么做了。
我有一个程序,我已经设置为使用可执行文件名称上的互斥体来运行单例模式。
单位 GlobalSU;
interface
function IsAppRunning: Boolean;
implementation
uses
Windows, SysUtils, Forms;
function IsAppRunning: Boolean;
var
rtn : Cardinal;
begin
result := False;
CreateMutex(nil, False, PWideChar(ExtractFileName(Application.ExeName)));
rtn := GetLastError;
if rtn = ERROR_ALREADY_EXISTS then
result := True;
end;
该程序接受特定的命令行参数来指示要执行的数据。我不希望使用相同的命令行参数运行超过一个程序实例,但我想能够以不同的参数启动第二个实例。
大约一年前,我曾这样做过,但现在不记得具体方法了。我通过在DPR中使用命令行参数修改名称,然后使用互斥体进行测试。
我尝试重命名Application.ExeName,但它是只读的,所以我必须更改其他内容。
下面的代码不能编译,但是添加了以说明我要做什么。 顺便说一下,“##”始终是第三个参数的前两个字符,但我会用正则表达式进行测试。
program EPRmailer;
uses
Vcl.Forms,
uMainMailer in 'uMainMailer.pas' {frmMainMailer},
configXML in 'configXML.pas',
GlobalSU in 'GlobalSU.pas',
CVUtils in 'CVUtils.pas',
QMConst in 'QMConst.pas',
ServerAttachmentDMu in 'ServerAttachmentDMu.pas';
{$R *.res}
var
i : integer;
begin
for i := 0 to ParamCount do
if TestParam('##', ParamStr(i)) then
Application.ExeName := Application.ExeName + '-' + ParamStr(i);
if IsAppRunning then exit;
Application.Initialize;
ReportMemoryLeaksOnShutdown := DebugHook <> 0;
Application.MainFormOnTaskbar := false;
Application.CreateForm(TfrmMainMailer, frmMainMailer);
frmMainMailer.RunEPR;
end.
foo.exe -a -b
视为等同于foo.exe -b -a
和foo.exe -B -a
吗? - Sir RufoMAX_PATH
长,这对于传递大约250个字符长(MAX_PATH - 'EPRmailer'
)的命令行参数是不够的。在这种情况下,您的互斥体创建将失败,但不是因为错误ERROR_ALREADY_EXISTS
,并且您将从函数返回错误值。为了防止这种情况,我会考虑在此处使用哈希(在排序参数之后)。 - TLamaIsAppRunning
(以其当前形式)如何能按照你所描述的方式使用。因此,我怀疑当你最后一次使用它来根据参数实现单实例时,它是以稍微不同的方式实现的。或者说,你可能改变了它以适应那个要求。 - Disillusioned