我正试图从我的程序中以提升的权限启动另一个应用程序,并等待其终止后才能继续。
我尝试了几种不同的解决方案,但没有找到完全正确的方法。
下面的代码是最接近正确的代码。它以提升的特权运行应用程序并等待其终止,但一旦外部应用程序终止,它就会冻结。换句话说,在启动的应用程序关闭后,它将不再继续处理。
我该如何实现我的目标?
procedure TfMain.RunFileAsAdminWait(hWnd: HWND; aFile, aParameters: string);
var
sei: TShellExecuteInfo;
begin
FillChar(sei, SizeOf(sei), 0);
sei.cbSize := SizeOf(sei);
sei.Wnd := hWnd;
sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
sei.lpVerb := 'runas';
sei.lpFile := PChar(aFile);
sei.lpParameters := PChar(aParameters);
sei.nShow := SW_SHOWNORMAL;
if not ShellExecuteEx(@sei) then
RaiseLastOSError
else
while WaitForSingleObject(sei.hProcess, 50) <> WAIT_OBJECT_0 do
Application.ProcessMessages;
CloseHandle(sei.hProcess);
end;
更新:
我想出了以下函数,但仅在调用它后有一个ShowMessage语句时才有效。 因此,我必须包含:
RunFileAsAdminWait(Handle, ExtractFilePath(Application.Exename) + 'AutoUpdate.exe', '/auto');
ShowMessage('test');
为了使函数起作用。我如何在不调用ShowMessage的情况下使它正常工作?
这是更新后的函数:
procedure TfMain.RunFileAsAdminWait(hWnd: HWND; aFile, aParameters: string);
var
sei: TShellExecuteInfo;
begin
FillChar(sei, SizeOf(sei), 0);
sei.cbSize := SizeOf(sei);
sei.Wnd := hWnd;
sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
sei.lpVerb := 'runas';
sei.lpFile := PChar(aFile);
sei.lpParameters := PChar(aParameters);
sei.nShow := SW_SHOWNORMAL;
if not ShellExecuteEx(@sei) then
RaiseLastOSError
else
if sei.hProcess <> 0 then
WaitForSingleObject(sei.hProcess, 50)
else
Exit;
CloseHandle(sei.hProcess);
end;
MsgWaitForMultipleObjects()
比使用WaitForSingleObject()
更有效率,这样你就可以在它告诉你有消息等待处理时才调用Application.ProcessMessages()
。不要盲目地无谓地调用ProcessMessages()
。 - Remy Lebeau