1,183
社区成员
发帖
与我相关
我的任务
分享
function RunCommand(const cmd: string; list: TStrings): string;
var
hReadPipe, hWritePipe: THandle;
si: STARTUPINFO;
lsa: SECURITY_ATTRIBUTES;
pi: PROCESS_INFORMATION;
cchReadBuffer: DWORD;
pOutStr: PAnsiChar; // or PChar;
res, strCMD: string;
fname: PChar;
begin
strCMD := cmd;
pOutStr := AllocMem(5000);
fname := AllocMem(255);
lsa.nLength := SizeOf(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor := nil;
lsa.bInheritHandle := True;
try
if not CreatePipe(hReadPipe, hWritePipe, @lsa, 0) then
Exit;
FillChar(si, SizeOf(STARTUPINFO), 0);
si.cb := SizeOf(STARTUPINFO);
si.dwFlags := (STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);
si.wShowWindow := SW_Hide;
si.hStdOutput := hWritePipe;
StrPCopy(fname, strCMD);
try
if not CreateProcess(nil, PChar(fname), nil, nil, True, 0, nil, nil,
si, pi) then
Exit;
try
while (True) do
begin
if not PeekNamedPipe(hReadPipe, pOutStr, 1, @cchReadBuffer, nil, nil)
then
break;
if cchReadBuffer <> 0 then
begin
if not ReadFile(hReadPipe, pOutStr^, 4096, cchReadBuffer, nil) then
break;
pOutStr[cchReadBuffer] := chr(0);
// if @Show <> nil then Show(pOutStr);
list.Add(pOutStr);
end
else if (WaitForSingleObject(pi.hProcess, 0) = WAIT_OBJECT_0) then
break;
Sleep(10);
Application.ProcessMessages;
end;
pOutStr[cchReadBuffer] := chr(0);
list.Add(pOutStr);
finally
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hWritePipe);
end;
finally
CloseHandle(hReadPipe);
end;
finally
FreeMem(pOutStr);
FreeMem(fname);
end;
Result := res;
end;
procedure TForm3.Button1Click(Sender: TObject);
var
cmd: string;
begin
cmd := 'ping baidu.com ';
RunCommand(cmd, Memo1.Lines);
end;
办法就是跳过cmd命令,自己用管道来显示程序输出。比如上面的代码将ping 命令输出到memo1上面。
多个命令就多跑几次RunCommand。
这个办法就不会有什么CMD窗口了,显示输出接管在自己的程序里面,更方便些 。