1、
參考網址:http://www.cnblogs.com/cnarg/archive/2011/02/20/1959292.html
1 function TfrmMain.ExecDosCmd :boolean; 2 var sa :SECURITY_ATTRIBUTES; 3 si :STARTUPINFO; 4 pi :PROCESS_INFORMATION; 5 6 pcDosCmd :PChar; 7 hRead,hWrite :THandle; 8 cCommand :array[0..1023] of char; //長達1k的命令行,夠用了吧 9 pcCommand1 :PChar; 10 cBuffer :array[0..4095] of char; //用4k的空間來存儲輸出的內容,只要不是顯示文件內容,一般情況下是夠用了。 11 bytesRead :DWORD; 12 dwExitCode :DWORD; 13 14 buf01 :array[0..4095] of char; 15 iLen01 :integer; 16 begin 17 Result := false; 18 //pcDosCmd := 'dir c:\'; //可以換成你的命令 19 pcDosCmd := 'ping 192.168.2.1'; //可以換成你的命令 20 21 sa.nLength := sizeof(SECURITY_ATTRIBUTES); 22 sa.lpSecurityDescriptor := nil; 23 sa.bInheritHandle := true; 24 if (not CreatePipe(hRead, hWrite, @sa, 0)) then 25 Exit; 26 27 pcCommand1 := 'Cmd.exe /C '; 28 ZeroMemory(@cCommand[0], length(cCommand)); 29 CopyMemory(@cCommand[0], pcCommand1, strlen(pcCommand1)); 30 CopyMemory(@cCommand[strlen(pcCommand1)], pcDosCmd, strlen(pcDosCmd)); 31 cCommand[strlen(pcCommand1) + strlen(pcDosCmd)] := chr(0); 32 33 si.cb := sizeof(STARTUPINFO); 34 GetStartupInfo(si); 35 si.hStdError := hWrite; //把創建進程的標准錯誤輸出重定向到管道輸入 36 si.hStdOutput := hWrite; //把創建進程的標准輸出重定向到管道輸入 37 si.wShowWindow := SW_HIDE; 38 si.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; 39 //關鍵步驟,CreateProcess函數參數意義請查閱MSDN 40 if (not CreateProcess(nil, cCommand, nil, nil, true, 0, nil, nil, si, pi)) then 41 begin 42 CloseHandle(hWrite); 43 CloseHandle(hRead); 44 Exit; 45 end; 46 CloseHandle(hWrite); 47 48 iLen01 := 0; 49 while (true) do 50 begin 51 //ZeroMemory(@cBuffer[0], length(cBuffer)); 52 if (not ReadFile(hRead, cBuffer[0], 4095, bytesRead, nil)) then 53 break; 54 //cBuffer[bytesRead] := chr(0); 55 //cBuffer中就是執行的結果,可以保存到文本,也可以直接輸出 56 //Memo1.Lines.Add(cBuffer); //這里是彈出對話框顯示 57 CopyMemory(@buf01[iLen01], @cBuffer[0], bytesRead); 58 iLen01 := iLen01 + bytesRead; 59 end; 60 buf01[iLen01] := chr(0); 61 Memo1.Lines.Add(buf01); 62 63 CloseHandle(hRead); 64 Result := true; 65 66 dwExitCode := 0; 67 WaitForSingleObject(pi.hProcess, INFINITE); 68 Windows.GetExitCodeProcess(pi.hProcess, dwExitCode); 69 Memo1.Lines.Add('子進程 退出碼 : '+inttostr(dwExitCode)); 70 end;
PS:CreateProcess()輸出到文件 里面用到的 “HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE);”“SetStdHandle(STD_OUTPUT_HANDLE, hFile);// 設置標准輸出” ,應該是將本進程默認的標准輸入輸出都改變了,而非是“將子進程的標准輸出重定向到剛剛創建的文件句柄”。
ZC:由於 只執行“SetStdHandle(STD_OUTPUT_HANDLE, hFile);” 的話,本進程的標准輸出流是不會改變的,又∵作者在SetStdHandle之后才執行GetStartupInfo,因此子進程的 標准輸出被重定位了,而父進程的標准輸出沒有變化。
A