gpt4 book ai didi

delphi - 未提升的程序启动提升的更新程序,更新程序应等待程序完成

转载 作者:行者123 更新时间:2023-12-03 14:47:53 25 4
gpt4 key购买 nike

我有 2 个应用程序,program.exe 和 updater.exe,都是用 Delphi5 编写的。程序在没有管理员权限的情况下运行(并且没有 list ),更新者有一个带有“requireAdministrator”的 list ,因为他必须能够在程序文件夹中写入才能更新program.exe。

问题是启动更新程序并让他等待程序关闭。我在网络上找到了不同的方法,但都不起作用(在大多数情况下,第一个应用程序启动第二个应用程序并等待第二个应用程序结束,在我的情况下,第二个应用程序应该等待第一个应用程序结束)。

更新程序应该等待,这很容易
更新程序.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

方法一
使用 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 的 list 时才起作用。如果我使用明确的管理员权限运行程序,它也可以工作。

方法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的句柄写入文件中。

我对编程的这些部分不太熟悉......有人对我的问题有想法吗?

最佳答案

您的代码不起作用,因为句柄表是每个进程的,这意味着第二个进程可能具有指向另一个内核对象的相同句柄。下面是许多可能的解决方案之一:

创建进程2时,传入进程1的PID作为参数:

procedure CreateUpdater;
var
Info: TShellExecuteInfo;
begin
FillChar(Info, SizeOf(TShellExecuteInfo), 0);
Info.cbSize := SizeOf(TShellExecuteInfo);
Info.fMask := SEE_MASK_NOCLOSEPROCESS;
Info.lpVerb := PChar('runas');
Info.lpFile := PChar('Update.exe');
Info.lpParameters := PChar(IntToStr(GetCurrentProcessId));
Info.lpDirectory := nil;
Info.nShow := SW_RESTORE;
ShellExecuteEx(@Info);
//NOTE: MISSING ERROR CHECKING!
end;

在更新程序内,等待 process1 终止:

procedure WaitForAndClose;
var
PID: String;
AHandle: Cardinal;
Ret: longbool;
ExitNumber: DWORD;
begin
PID:= ParamStr(1);
if PID <> '' then
begin
AHandle:= OpenProcess(PROCESS_QUERY_INFORMATION, False, StrToInt(PID));
//NOTE: MISSING ERROR CHECKING!
try
repeat
Ret:= GetExitCodeProcess(AHandle, ExitNumber);
//NOTE: MISSING ERROR CHECKING!
Sleep(1000); //define a time to poolling
until (ExitNumber <> STILL_ACTIVE);
finally
CloseHandle(AHandle);
end;
//Terminate the process;
Application.Terminate;
end;
end;

您还可以使用WaitForSingleObject来避免轮询:

WaitForSingleObject(AHandle, INFINITE);
//NOTE: MISSING ERROR CHECKING!

但是您需要 SYNCHRONIZE 访问权限才能打开该进程:

AHandle:= OpenProcess(SYNCHRONIZE, False, StrToInt(PID));
//NOTE: MISSING ERROR CHECKING!

注意:这里没有错误检查。您应该阅读文档并正确检查错误。

注2:我想让您注意您正在泄漏 handle 这一事实。当您使用SEE_MASK_NOCLOSEPROCESS时,调用者负责关闭被调用者的句柄。就你的情况而言,我认为你根本不需要那个面具。我会删除它。

关于delphi - 未提升的程序启动提升的更新程序,更新程序应等待程序完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30759365/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com