加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

将输出从shell/dos应用程序导入Delphi应用程序

发布时间:2020-12-15 20:05:40 所属栏目:安全 来源:网络整理
导读:我有一个命令行应用程序在delphi中编码,我需要从一个普通的桌面应用程序(也在delphi中编码)调用。简而言之,我想调用命令行应用程序,并在列表框中显示“live”输出的文本。 它已经老了,因为我玩了壳,但我清楚地记住,为了从命令行应用程序抓取文本 – 我
我有一个命令行应用程序在delphi中编码,我需要从一个普通的桌面应用程序(也在delphi中编码)调用。简而言之,我想调用命令行应用程序,并在列表框中显示“live”输出的文本。

它已经老了,因为我玩了壳,但我清楚地记住,为了从命令行应用程序抓取文本 – 我必须使用管道符号“>”。喜欢这个:

C:/mycmdapp.exe> c:/result.txt

这将使任何打印到shell(使用writeLn)的文本并将其转储到名为“result.txt”的文本文件。

但是..(这里来的pickle),我想要一个现场结果,而不是一个积压文件。一个典型的例子是Delphi编译器本身 – 它管理向IDE报告发生了什么。如果我的记忆正确地服务我,我似乎记得,我必须创建一个“管道”通道(?),然后将管道名称分配给shell调用。

我试图google这个,但我真的不知道如何制定它。希望社会上有人能指出我的方向正确。

预先感谢您的帮助

更新:这个问题可能等同于How do I run a command-line program in Delphi?.一些answeres适合什么im寻找,虽然标题和问题本身不相同。

像往常一样,Zarco Gajic有一个解决方案: Capture the output from a DOS (command/console) Window.这是他的文章的副本,供将来参考:

The example runs ‘chkdsk.exe c:’ and displays the output to Memo1.
Put a TMemo (Memo1) and a TButton (Button1) on your form. Put this code in the OnCLick event procedure for Button1:

procedure TForm1.Button1Click(Sender: TObject) ;

  procedure RunDosInMemo(DosApp:String;AMemo:TMemo) ;
  const
     ReadBuffer = 2400;
  var
   Security : TSecurityAttributes;
   ReadPipe,WritePipe : THandle;
   start : TStartUpInfo;
   ProcessInfo : TProcessInformation;
   Buffer : Pchar;
   BytesRead : DWord;
   Apprunning : DWord;
  begin
   With Security do begin
    nlength := SizeOf(TSecurityAttributes) ;
    binherithandle := true;
    lpsecuritydescriptor := nil;
   end;
   if Createpipe (ReadPipe,WritePipe,@Security,0) then begin
    Buffer := AllocMem(ReadBuffer + 1) ;
    FillChar(Start,Sizeof(Start),#0) ;
    start.cb := SizeOf(start) ;
    start.hStdOutput := WritePipe;
    start.hStdInput := ReadPipe;
    start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
    start.wShowWindow := SW_HIDE;

    if CreateProcess(nil,PChar(DosApp),true,NORMAL_PRIORITY_CLASS,nil,start,ProcessInfo)
    then
    begin
     repeat
      Apprunning := WaitForSingleObject
                   (ProcessInfo.hProcess,100) ;
      Application.ProcessMessages;
     until (Apprunning <> WAIT_TIMEOUT) ;
      Repeat
        BytesRead := 0;
        ReadFile(ReadPipe,Buffer[0],ReadBuffer,BytesRead,nil) ;
        Buffer[BytesRead]:= #0;
        OemToAnsi(Buffer,Buffer) ;
        AMemo.Text := AMemo.text + String(Buffer) ;
      until (BytesRead < ReadBuffer) ;
   end;
   FreeMem(Buffer) ;
   CloseHandle(ProcessInfo.hProcess) ;
   CloseHandle(ProcessInfo.hThread) ;
   CloseHandle(ReadPipe) ;
   CloseHandle(WritePipe) ;
   end;
  end;

  begin {button 1 code}
    RunDosInMemo('chkdsk.exe c:',Memo1) ;
  end;

更新:
上面的示例在一个步骤中读取输出。这里是从DelphiDabbler的另一个例子,显示在进程仍在运行时如何读取输出:

function GetDosOutput(CommandLine: string; Work: string = 'C:'): string;
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutPipeRead,StdOutPipeWrite: THandle;
  WasOK: Boolean;
  Buffer: array[0..255] of AnsiChar;
  BytesRead: Cardinal;
  WorkDir: string;
  Handle: Boolean;
begin
  Result := '';
  with SA do begin
    nLength := SizeOf(SA);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  CreatePipe(StdOutPipeRead,StdOutPipeWrite,@SA,0);
  try
    with SI do
    begin
      FillChar(SI,SizeOf(SI),0);
      cb := SizeOf(SI);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
    end;
    WorkDir := Work;
    Handle := CreateProcess(nil,PChar('cmd.exe /C ' + CommandLine),True,PChar(WorkDir),SI,PI);
    CloseHandle(StdOutPipeWrite);
    if Handle then
      try
        repeat
          WasOK := ReadFile(StdOutPipeRead,Buffer,255,nil);
          if BytesRead > 0 then
          begin
            Buffer[BytesRead] := #0;
            Result := Result + Buffer;
          end;
        until not WasOK or (BytesRead = 0);
        WaitForSingleObject(PI.hProcess,INFINITE);
      finally
        CloseHandle(PI.hThread);
        CloseHandle(PI.hProcess);
      end;
  finally
    CloseHandle(StdOutPipeRead);
  end;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读