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