【发布时间】:2015-06-10 14:29:39
【问题描述】:
我有 2 个应用程序,program.exe 和 updater.exe,它们都是用 Delphi5 编写的。 程序在没有管理员权限(也没有清单)的情况下运行,更新程序有一个带有“requireAdministrator”的清单,因为他必须能够在 Program-Folder 写入来更新 program.exe。
问题是启动更新程序并让他等到程序关闭。 我在网上找到了不同的方法,但都没有奏效(在大多数情况下,第一个应用程序启动第二个应用程序并等待第二个应用程序结束,在我的情况下,第二个应用程序应该等待第一个应用程序结束)。
更新程序应该等待,这很容易
updater.exe
{$R manifest.res}
label.caption:='Wait for program.exe closing';
repeat
sleep(1000);
until File is not open
ProgramHandle := Read Handle from File
WaitForSingleObject(ProgramHandle,INFINITE);
label.caption:='program.exe CLOSED';
Do updates
方式 1
使用 CreateProcess 启动更新程序:
程序.exe
FillChar(siInfo, SizeOf(siInfo), 0);
siInfo.cb := SizeOf(siInfo);
saProcessAttributes.nLength := SizeOf(saProcessAttributes);
saProcessAttributes.lpSecurityDescriptor := nil;
saProcessAttributes.bInheritHandle := TRUE;
saThreadAttributes.nLength := SizeOf(saThreadAttributes);
saThreadAttributes.lpSecurityDescriptor := nil;
saThreadAttributes.bInheritHandle := True;
if CreateProcess(nil,
PChar('updater.exe'),
@saProcessAttributes,
@saThreadAttributes,
TRUE, NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(Application.ExeName)),
siInfo, piInfo) then
begin
DuplicateHandle(GetCurrentProcess, GetCurrentProcess,
piInfo.hProcess, @MyHandle,
PROCESS_QUERY_INFORMATION, TRUE,
DUPLICATE_SAME_ACCESS) then
Write MyHandle in a File
end;
Close program
不做任何事情,仅当更新程序没有带有 requireAdministrator 的清单时才有效。 如果我以 explizit 管理员权限运行程序,它也可以工作。
方式 2
使用 ShellExecuteEx 启动更新程序:
程序.exe
FillChar(Info, SizeOf(Info), Chr(0));
Info.cbSize := SizeOf(Info);
Info.fMask := SEE_MASK_NOCLOSEPROCESS;
Info.lpVerb := PChar('runas');
Info.lpFile := PChar('update.exe');
Info.lpDirectory := nil;
Info.nShow := SW_RESTORE;
ShellExecuteEx(@Info);
MyHandle:=OpenProcess(PROCESS_ALL_ACCESS, False, GetCurrentProcessId())));
Write MyHandle in a File
Close program
不起作用,MyHandle 每次运行此过程时都有不同的值(无需重新启动程序),因此更新程序无法使用它。
所以我不知道如何启动updater.exe并将program.exe的句柄写入文件中。
我对编程的这些部分不是很熟悉......有人对我的问题有想法吗?
【问题讨论】:
-
可能是枚举Updater中的进程,找到程序然后等到进程终止才是正确的方法。
-
也许这可以帮助stackoverflow.com/questions/5608502/…。如果标题名称已知,您可以找到窗口并使用计时器检查句柄是否仍然有效
-
我的回答中有一个重要说明是关于泄漏的句柄。看看吧
-
您确实需要两个程序的清单。你甚至不需要requireAdministrator。您可以使用 runas。但最好显示 requireAdministrator。
标签: delphi handle createprocess waitforsingleobject shellexecuteex