Delphi 如何在同一cmd进程中执行来自cmd的不同命令?

Delphi 如何在同一cmd进程中执行来自cmd的不同命令?,delphi,Delphi,我想启动一个cmd进程,并继续向它提供一些不同的命令。我想在文本输出后立即获得所有文本cmd输出。到目前为止,我有: function GetDosOutput(const ACommandLine: string; AWorkDir: string = 'C:\'): string; var _SA: TSecurityAttributes; _SI: TStartupInfo; _PI: TProcessInformation; _StdOutPipeRead, StdO

我想启动一个
cmd
进程,并继续向它提供一些不同的命令。我想在文本输出后立即获得所有文本
cmd
输出。到目前为止,我有:

function GetDosOutput(const ACommandLine: string;
  AWorkDir: string = 'C:\'): string;
var
  _SA: TSecurityAttributes;
  _SI: TStartupInfo;
  _PI: TProcessInformation;
  _StdOutPipeRead, StdOutPipeWrite: THandle;
  _WasOK: boolean;
  _Buffer: array [0 .. 255] of AnsiChar;
  _BytesRead: Cardinal;
  _Handle: boolean;
begin
  Result := '';
  _SA.nLength := SizeOf(_SA);
  _SA.bInheritHandle := True;
  _SA.lpSecurityDescriptor := nil;

  CreatePipe(_StdOutPipeRead, StdOutPipeWrite, @_SA, 0);
  try
    FillChar(_SI, SizeOf(_SI), 0);
    _SI.cb := SizeOf(_SI);
    _SI.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    _SI.wShowWindow := SW_HIDE;
    _SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
    _SI.hStdOutput := StdOutPipeWrite;
    _SI.hStdError := StdOutPipeWrite;
    _Handle := CreateProcess(nil, PChar('cmd.exe /C ' + ACommandLine), nil, nil,
      True, 0, nil, PChar(AWorkDir), _SI, _PI);
    CloseHandle(StdOutPipeWrite);
    if _Handle then
      try
        repeat
          _WasOK := ReadFile(_StdOutPipeRead, _Buffer, 255, _BytesRead, nil);
          if _BytesRead > 0 then
          begin
            _Buffer[_BytesRead] := #0;
            Result := Result + string(_Buffer);
            Application.ProcessMessages;
          end;
        until not _WasOK or (_BytesRead = 0);
        WaitForSingleObject(_PI.hProcess, INFINITE);
      finally
        CloseHandle(_PI.hThread);
        CloseHandle(_PI.hProcess);
      end;
  finally
    CloseHandle(_StdOutPipeRead);
  end;
end;
如何保持相同的
cmd.exe
进程并为其提供不同的命令,例如。 1) ping stackoverflow.com,打印一行后立即查看其内容
2)
ipconfig/all

您需要使用
cmd.exe/K
而不是
cmd.exe/C
/C
执行1个命令,然后终止进程
/K
执行1个命令,然后保持进程运行。此外,响应不会以任何方式分隔,因此您无法确切知道响应何时完成。您需要在
ReadFile()
上超时,或者在使用
ReadFile()
读取数据之前,您可以使用
PeekNamedPipe()
检测数据。但是,为什么要使用
cmd.exe
?有很多Win32 API函数可用于您提到的操作类型,例如:
ping
->、
ipconfig
->等等。Remy,因为WinAPI试图愚弄我。我花了几个小时才发现VPN网络已重命名,但即使在电脑重新启动后,ConNetworkListManager+GetNetworkConnections仍然返回旧名称。顺便问一下,如何将新命令馈送到
cmd.exe/K
?那么为什么要使用delphi呢?我打赌制作一个powershell脚本来做你想做的事情要容易得多…@EdijsKolesnikovičs我严重怀疑这一点
ipconfig
在内部使用API,因此应该是相同的信息。
getAdapterAddresses()
ConNetworkListManager
相比报告了什么?至于
cmd.exe
,一旦进程运行,只需将
WriteFile()
写入
stdin
管道,然后从
stdout
/
stderr
管道读取