我正在使用我在互联网上找到的代码以及它等待的某些设备,但在其他设备上却没有。有人可以解释我哪里出错了。我的应用程序在Truecrypt中加载,然后等待用户输入密码。退出Truecrypt后,它会启动我的菜单程序。
我的联想Miix 2 8"平板电脑,win8.1(全部都是最新的)将等待,我父亲的win8.0(全部是最新的)将等待,但我的朋友的华硕M80TA 8" win8.1平板电脑(全部都是最新的)不会。另一位朋友的win7笔记本电脑(全部都是最新的)不等待以太。
var
aTSI : TStartupInfo;
aTPI : TProcessInformation;
iRet : Integer;
ExitCode: Cardinal;
begin
FillChar(aTSI, SizeOf(aTSI), #0);
FillChar(aTPI, SizeOf(aTPI), #0);
aTSI.CB:=SizeOf(aTSI);
if not CreateProcess(nil, PChar(sEXE), nil, nil, False,
NORMAL_PRIORITY_CLASS,
nil, nil, aTSI, aTPI) then
RaiseLastWin32Error;
repeat
iRet:=MsgWaitForMultipleObjects(1, aTPI.hProcess,
False, INFINITE, (QS_ALLINPUT));
if iRet <> (WAIT_OBJECT_0) then
Application.ProcessMessages;
until iRet = (WAIT_OBJECT_0); // use this for normal programs
ExitCode:= 0;
if not GetExitCodeProcess(aTPI.hProcess, ExitCode) then
RaiseLastWin32Error;
Result:= ExitCode;
CloseHandle(aTPI.hProcess);
end;
答案 0 :(得分:0)
可能的解释如下:
为了了解如何处理此问题,您需要提供有关您尝试启动的流程的一些详细信息。至于为什么代码在某些机器而不是其他机器上工作,这可能取决于目标应用程序的实现细节,即您正在启动的外部应用程序。据推测,它因机器而异。
查看代码,它总是泄漏aTPI.hThread
中返回的线程句柄。如果aTPI.hProcess
失败,它会泄漏GetExitCodeProcess
。
您还需要确保传递给CreateProcess
命令行参数的字符串是可编辑的字符串,而不是存储在只读存储器中的文字。
初始化ExitCode
然后立即覆盖它也毫无意义。您还可以删除ExitCode
变量并将Result
直接传递给GetExitCodeProcess
。
您的代码也无法确认wait函数返回错误。
我可能会这样写:
function ExecAndWait(CommandLine: string): DWORD;
var
si: TStartupInfo;
pi: TProcessInformation;
iRet: Integer;
begin
UniqueString(CommandLine);
si := Default(TStartupInfo);
si.cb := SizeOf(si);
Win32Check(CreateProcess(nil, PChar(CommandLine), nil, nil, False,
NORMAL_PRIORITY_CLASS, nil, nil, si, pi));
CloseHandle(pi.hThread);
try
while True do
begin
iRet := MsgWaitForMultipleObjects(1, pi.hProcess, False, INFINITE, QS_ALLINPUT);
Win32Check(iRet <> WAIT_FAILED);
case iRet of
WAIT_OBJECT_0:
break;
WAIT_OBJECT_0+1:
Application.ProcessMessages;
end;
end;
Win32Check(GetExitCodeProcess(pi.hProcess, Result));
finally
CloseHandle(pi.hProcess);
end;
end;
在我的机器上,当我将'notepad.exe'
传递给此函数时,在记事本进程关闭之前,该函数不会返回。
另一方面,如果我将'explorer.exe'
传递给进程,则函数立即返回。这里发生的是新的资源管理器进程启动,但它检测到一个已经在运行,并要求该进程打开一个新窗口。新启动的资源管理器进程会立即终止。