CreateProcess 執行CMD命令,並重定向輸出


 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM