【发布时间】:2014-12-08 17:58:44
【问题描述】:
我知道我以前做过,但似乎不记得是怎么做的。
我有一个程序,我已设置为使用可执行名称上的互斥锁运行单例。 单位 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? -
互斥体名称的参数最多可以是
MAX_PATHlong,这还不够,例如通过约。 250 个字符长 (MAX_PATH - 'EPRmailer') 命令行参数。在这种情况下,您的互斥锁创建失败,但不是因为错误ERROR_ALREADY_EXISTS并且您将从函数返回错误值。为了防止这种情况,我会在这里考虑一个哈希(在对参数进行排序之后)。 -
如果 Application.Title 足够独特,则可以使用它来代替 Application.ExeName,因为它要短得多并且不包含“\”字符。
-
我看不出您的
IsAppRunning(以当前形式)如何以您描述的方式使用。所以我怀疑当你上次使用它来强制执行基于参数的单实例时,它的实现方式略有不同。或者也许你改变了它以适应那个要求。
标签: delphi singleton delphi-xe6