执行并等待有时不起作用 [英] Execute and Wait not working sometimes
问题描述
我正在使用在Internet上找到的这段代码,并且在某些设备上等待,但是在其他设备上则没有.有人可以解释我要去哪里了.我的应用程序在Truecrypt中加载,然后等待用户输入密码.退出Truecrypt后,它将启动我的菜单程序.
I am using this code I found on the Internet and on some devices it waits, but on others it does not. Can someone please explain where I am going wrong. My app loads in Truecrypt and then waits for the user to enter the password. On exiting Truecrypt, it then launches my menu-program.
我的Lenovo Miix 2 8平板电脑,win8.1(所有最新版本)将等待,我父亲的win8.0(所有文字,最新)将等待,但是我朋友的ASUS M80TA 8" win8.1平板电脑(全部(最新)).另一个朋友的win7笔记本电脑(都是最新的)不等待以太币.
My Lenovo Miix 2 8" tablet, win8.1 (all up to date) will wait, my Dad's win8.0 (all up to date) will wait, but my friend's ASUS M80TA 8" win8.1 tablet (all up to date) will not. Another friend's win7 laptop (all up to date) does not wait ether.
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;
推荐答案
可能的解释如下:
- 您调用CreateProcess来创建一个新进程并返回该进程的句柄.
- 第一个新流程又开始一个不同的流程,并立即返回.第二个过程就是您看到的过程,并相信是您创建的过程.
- 您等待第一个进程句柄返回.
为了知道如何处理,您需要提供一些有关您尝试开始的过程的详细信息.至于为什么代码可以在某些机器上而不在其他机器上工作,则可能取决于目标应用程序(您正在启动的外部应用程序)的实现细节.大概因机器而异.
In order to know how to deal with this you'd need to supply some details about the process that you are attempting to start. As to why the code works on some machines and not others, that would likely be down to the implementation details of the target application, the external application that you are starting. Presumably it differs from machine to machine.
看代码,它总是泄漏aTPI.hThread
中返回的线程句柄.如果GetExitCodeProcess
失败,它将泄漏aTPI.hProcess
.
Looking at the code, it always leaks the thread handle returned in aTPI.hThread
. And it leaks aTPI.hProcess
if GetExitCodeProcess
fails.
您还需要确保传递给CreateProcess
的命令行参数的字符串是可编辑的字符串,而不是存储在只读存储器中的文字.
You also need to ensure that the string you pass to the command line argument of CreateProcess
is an editable string, and not a literal that is stored in read-only memory.
初始化ExitCode
然后立即覆盖它也是没有意义的.此外,您可以删除ExitCode
变量并将Result
直接传递给GetExitCodeProcess
.
It is also pointless to initialise ExitCode
and then immediately overwrite it. What's more you can remove the ExitCode
variable and pass Result
directly to GetExitCodeProcess
.
您的代码也无法确认等待函数返回的错误.
Your code also fails to acknowledge an error being returned by the wait function.
我可能会这样写:
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'
传递给此函数时,该函数在记事本进程关闭之前不会返回.
On my machine, when I pass 'notepad.exe'
to this function, the function does not return until the Notepad process is closed.
另一方面,如果将'explorer.exe'
传递给进程,则该函数立即返回.此处发生的是一个新的资源管理器进程启动,但是它检测到一个新的资源管理器进程已在运行,并要求该进程打开一个新窗口.新启动的资源管理器进程立即终止.
On the other hand, if I pass 'explorer.exe'
to the process, then the function returns immediately. What happens here is that a new explorer process starts, but it detects that one is already running, and asks that process to open a new window. The newly started explorer process immediately terminates.
这篇关于执行并等待有时不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!