我想从另一个delphi程序编译一个Delphi程序,为此,我使用ShellExecuteEx,以便该程序等待编译完成。
这工作正常,但我希望将.cmd输出放在.txt文件中,这不能正常工作。
StartAndWait('cmd', '/c c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild xyz.dproj /t:Build /p:Config=release >> log.txt');
StartAndWait使用ShellExecuteEx启动该函数,并等待程序完成,
IF ShellExecuteEx(@SEInfo) THEN
BEGIN
REPEAT
Application.ProcessMessages;
// Damit die Prozessorauslastung sinkt :-)
Sleep(100);
GetExitCodeProcess(SEInfo.hProcess, ExitCode);
UNTIL (ExitCode <> STILL_ACTIVE) OR Application.Terminated;
Result := True;
END;
谢谢!
最佳答案
我个人认为,通过调用CreateProcess
可以更轻松地完成此操作。您需要创建一个文件句柄,并将其传递给CreateProcess
用作标准输出。您需要注意一些细节,主要涉及句柄继承。您可以使用此功能完成所有操作:
procedure ExecuteCommandAndAppendToFile(
const Executable: string;
const Arguments: string;
const WorkingDir: string;
const OutputFile: string
);
const
sa: TSecurityAttributes = (nLength: SizeOf(sa); bInheritHandle: True);
var
hstdout: THandle;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
cmd: string;
begin
hstdout := CreateFile(PChar(OutputFile), GENERIC_WRITE, 0, @sa, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
Win32Check(hstdout<>INVALID_HANDLE_VALUE);
try
//move to end of file since we wish to append
SetFilePointer(hstdout, 0, nil, FILE_END);
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.hStdOutput := hstdout;
StartupInfo.hStdError := hstdout;
cmd := Executable + ' ' + Arguments;
UniqueString(cmd);//not needed but let's be explicit
if not CreateProcess(nil, PChar(cmd), nil, nil, True,
CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS, nil, PChar(WorkingDir),
StartupInfo, ProcessInfo) then
begin
RaiseLastOSError;
end;
try
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
finally
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
finally
CloseHandle(hstdout);
end;
end;
这使用
WaitForSingleObject
等待完成。那将阻塞运行该代码的线程。如果您有不想阻止的GUI,则可以将此代码移到另一个线程中。或者,您可以使用MsgWaitForMultipleObjects
。或者,如果需要的话,也可以使用基于Sleep
的循环(我不太关心Sleep
,但这是您的选择)。因此,您可能希望对此做些微调,但此处提供了所有基础知识。