以下代码
function Run(exePath, cmdLine, currDir: string): Boolean;
var
si: TStartupInfo;
pinf: TProcessInformation;
hStdOut: THandle;
sa: TSecurityAttributes;
lastErr: LongWord;
begin
sa.nLength := SizeOf(TSecurityAttributes);
sa.bInheritHandle := True;
sa.lpSecurityDescriptor := nil;
si := default(TStartupInfo);
si.cb := SizeOf(si);
si.dwFlags := si.dwFlags; // or STARTF_USESTDHANDLES;
SetLastError(0);
Result := Createprocess(PWideChar(exePath), PWideChar(cmdLine), nil, nil,
True, 0 {CREATE_NEW_CONSOLE}, nil, PWideChar(currDir), si, pinf);
if Result then begin
WaitForSingleObject(pinf.hProcess, INFINITE);
lastErr := GetLastError(); // Here error 1812
if lastErr <> 0 then ShowError(lastErr);
CloseHandle(pinf.hProcess);
CloseHandle(pinf.hThread);
end
else begin
lastErr := GetLastError();
if lastErr <> 0 then ShowError(lastErr);
end;
end;
在各种可执行文件(git,cgrc,dcc32)上生成错误1812(指定的图像文件不包含资源部分)。
它是什么以及如何消除它?
P.S。这是我想知道的一段代码:
SetLastError(0);
ShowError(GetLastError()); // Here the error code is 0
Result := Createprocess(PWideChar(exePath), PWideChar(cmdLine), nil, nil, False, 0, nil, PWideChar(currDir), si, pinf);
ShowError(GetLastError()); // Here error 1812
我的逻辑如下:如果在CreateProcess
之前调用最后一个错误代码为0,并且之后不是0,那么设置值肯定是CreateProcess
。如果没有错误发生,为什么要设置错误代码?
这个逻辑似乎是假的,即使函数成功,也可以设置上一个错误代码。
答案 0 :(得分:5)
您的错误处理代码已损坏。你的功能应如下所示:
function Run(exePath, cmdLine, currDir: string): Boolean;
var
si: TStartupInfo;
pinf: TProcessInformation;
hStdOut: THandle;
sa: TSecurityAttributes;
waitResult: DWORD;
lastErr: LongWord;
begin
sa.nLength := SizeOf(TSecurityAttributes);
sa.bInheritHandle := True;
sa.lpSecurityDescriptor := nil;
si := default(TStartupInfo);
si.cb := SizeOf(si);
si.dwFlags := si.dwFlags; // or STARTF_USESTDHANDLES;
UniqueString(cmdLine);
Result := CreateProcess(PWideChar(exePath), PWideChar(cmdLine), nil, nil,
True, 0 {CREATE_NEW_CONSOLE}, nil, PWideChar(currDir), si, pinf);
if Result then begin
waitResult := WaitForSingleObject(pinf.hProcess, INFINITE);
if waitResult = WAIT_FAILED then begin
lastErr := GetLastError();
if lastErr <> 0 then ShowError(lastErr);
end else begin
Assert(waitResult = WAIT_OBJECT_0);
end;
CloseHandle(pinf.hProcess);
CloseHandle(pinf.hThread);
end
else begin
lastErr := GetLastError();
if lastErr <> 0 then ShowError(lastErr);
end;
end;
注意:
CreateProcess
的第二个参数必须是可写字符串。因此呼叫UniqueString
。WaitForSingleObject
中所述,失败由返回值表示。如果返回值指示失败,您应该只调用GetLastError
。SetLastError(0)
的调用,这是不必要的。ShowError
引发异常,则此函数将泄漏句柄。我希望发生的事情是CreateProcess
成功,但没有将最后一个错误设置为零,它没有义务这样做。请记住,返回值表示成功或失败,而不是错误代码。然后WaitForSingleObject
也成功了,并没有将错误代码设置为零,这也是它没有义务做的事情。或者可能是WaitForSingleObject
将错误代码设置为非零值。在任何情况下,哪个功能确实没有实际意义。修复错误检查代码后,您将无法查看此无意义的错误代码。
最后,您是否确定要让子进程继承句柄?