常規調用外部程序或者CMD窗口一般都是用Win32 API類似:
1.ShellExecute命令用於外部調用Windows關聯應用程序打開某文件操作;
2.WinExec命令用於簡單的CMD作業。
但爲了實現介入CMD命令行窗口的敲指令一步一步的操作,就必須調用CreateProcess這個API來實現:
參考了別人寫的一個代碼段,作者未知。。。。
procedure CheckResult(b: Boolean);
begin
if not b then
raise Exception.Create(SysErrorMessage(GetLastError));
end;
function RunDOS(const CommandLine: string): string;
var
HRead, HWrite: THandle;
StartInfo: TStartupInfo;
ProceInfo: TProcessInformation;
b: Boolean;
sa: TSecurityAttributes;
inS: THandleStream;
sRet: TStrings;
begin
Result := '';
FillChar(sa, sizeof(sa), 0);
//設置允許繼承,否則在NT和2000下無法取得輸出結果
sa.nLength := sizeof(sa);
sa.bInheritHandle := True;
sa.lpSecurityDescriptor := nil;
b := CreatePipe(HRead, HWrite, @sa, 0);
CheckResult(b);
FillChar(StartInfo, SizeOf(StartInfo), 0);
StartInfo.cb := SizeOf(StartInfo);
StartInfo.wShowWindow := SW_HIDE;
//使用指定的句柄作爲標準輸入輸出的文件句柄,使用指定的顯示方式
StartInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
StartInfo.hStdError := HWrite;
StartInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE); //HRead;
StartInfo.hStdOutput := HWrite;
// ShellExecute和WinExec命令用於簡單的CMD作業。如果要完全控制一個新進程,就必須調用CreateProcess。
b := CreateProcess(nil, //lpApplicationName: PChar
PChar(CommandLine), //lpCommandLine: PChar
nil, //lpProcessAttributes: PSecurityAttributes
nil, //lpThreadAttributes: PSecurityAttributes
True, //bInheritHandles: BOOL
CREATE_NEW_CONSOLE,
nil,
nil,
StartInfo, //指向一個STARTUPINFO結構,該結構定義了新進程的主窗口將如何顯示。
ProceInfo); //指向PROCESS_INFORMATION結構,該結構接受關於新進程的表示信息。
//而真正感興趣的返回值發生於作爲參數傳送的結構中 (PROCESS_INFORMATION)。CreateProcess返回該結構中的進程ID及其句柄,以及初始線程ID及其句柄。
CheckResult(b);
WaitForSingleObject(ProceInfo.hProcess, INFINITE);
inS := THandleStream.Create(HRead);
if inS.Size > 0 then
begin
sRet := TStringList.Create;
sRet.LoadFromStream(inS);
Result := sRet.Text;
sRet.Free;
end;
inS.Free;
CloseHandle(HRead);
CloseHandle(HWrite);
end;
這個代碼能正常運行,但是對於ICD3的cmd操控程序會先憋很久突然爆出一堆字符串結果,不忍直視。所以我需要修改其線程等待和返回的方式:
未完待續。。。。。。。。。。
。。。
。。