Delphi:如何启动具有提升状态的应用程序并等待它终止? [英] Delphi: How to start application with elevated status and wait for it to terminate?
问题描述
我正在尝试从我的程序中启动另一个应用程序,提升版权,并等待它继续执行。
I'm trying to start another application from my program with elevated rights, and wait for it to terminate before continuing.
我已经尝试了几种不同的解决方案网络,但我找不到一个正确的工作。
I've tried several different solutions on the web, but I can't find one that works exactly right.
下面的代码是我最接近的工作。它以高级特权运行应用程序,并等待它终止,但一旦外部应用程序终止,它就会冻结。换句话说,一旦启动的应用程序关闭,它不会继续处理。
The code below is the closest I have to working right. It runs the app with elevated privileges and waits for it to terminate, but it freezes once the external app is terminated. In other words, it doesn't keep processing once the launched app is closed.
如何完成我在这里之后?
How can I accomplish what I'm after here?
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语句之后,它才起作用。所以,我必须有:
I've come up with the following function, but it only works if I have a ShowMessage statement after calling it. So, I have to have:
RunFileAsAdminWait(Handle, ExtractFilePath(Application.Exename) + 'AutoUpdate.exe', '/auto');
ShowMessage('test');
以使功能正常工作。
in order to make the function work. How can I make it work without the ShowMessage call?
这是更新的功能:
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;
推荐答案
以下代码适用于我:
procedure 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_NO_UI or SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb := 'runas';
sei.lpFile := PChar(aFile);
sei.lpParameters := PChar(aParameters);
sei.nShow := SW_SHOWNORMAL;
if not ShellExecuteEx(@sei) then
RaiseLastOSError;
if sei.hProcess <> 0 then begin
while WaitForSingleObject(sei.hProcess, 50) = WAIT_TIMEOUT do
Application.ProcessMessages;
CloseHandle(sei.hProcess);
end;
end;
您必须将 SEE_MASK_NOCLOSEPROCESS
标志传递给获取进程句柄等待。只要 WaitForSingleObject()
返回超时,我也将代码更改为循环。
You have to pass the SEE_MASK_NOCLOSEPROCESS
flag to get the process handle to wait for. I also changed the code to loop as long as WaitForSingleObject()
returns with timeout.
有关标志请参阅 的MSDN页面SHELLEXECUTEINFO
结构。
For more information on the flags see the MSDN page for the SHELLEXECUTEINFO
structure.
这篇关于Delphi:如何启动具有提升状态的应用程序并等待它终止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!