我试图使用delphi将命令发送到命令提示符.
但是,我无法这样做,因为我使用CreateProcess方法来做到这一点.
我试图更改StdOutPipeWrite,但是,在CreateProcess的初始命令传递之后,CreateProcess似乎不允许命令.
有没有办法利用句柄继续发送和接收来往命令提示符和delphi的命令和消息?

解决方法

我的同事Glenn9999来自tek-tips.com wrote a nice FAQ on this subject.
我不知道他是否在这样做,但他应该得到这一点.
我在这里复制了该页面的代码以供将来参考.他使用管道来进行控制台和delphi之间的通信.
unit mcunit;

{ written by Glenn9999 @ tek-tips.com.  Posted here 6/21/2011 }
interface

uses
  Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls;

type
  monitor = class(TThread)  // pipe monitoring thread for console output
  private
    TextString: String;
    procedure UpdateCaption;
  protected
    procedure Execute; override;
  end;
  TForm1 = class(TForm)
    CommandText: TMemo;
    CommandRun: TComboBox;
    Button2: TButton;
    SaveDialog1: TSaveDialog;
    procedure FormDestroy(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    cmdcount: integer;
  end;

var
  Form1: TForm1;
  InputPipeRead,InputPipeWrite: THandle;
  OutputPipeRead,OutputPipeWrite: THandle;
  ErrorPipeRead,ErrorPipeWrite: THandle;
  ProcessInfo : TProcessinformation;
  myThread: monitor;

implementation

{$R *.DFM}

procedure WritePipeOut(OutputPipe: THandle; InString: string);
// writes Instring to the pipe handle described by OutputPipe
  var
    byteswritten: DWord;
  begin
// most console programs require CR/LF after their input.
    InString := InString + #13#10;
    WriteFile(OutputPipe,Instring[1],Length(Instring),byteswritten,nil);
  end;

function ReadPipeInput(InputPipe: THandle; var BytesRem: Integer): String;
  {
    reads console output from InputPipe.  Returns the input in function
    result.  Returns bytes of remaining information to BytesRem
  }
  var
    TextBuffer: array[1..32767] of char;
    TextString: String;
    BytesRead: Integer;
    PipeSize: Integer;
  begin
    Result := '';
    PipeSize := Sizeof(TextBuffer);
    // check if there is something to read in pipe
    PeekNamedPipe(InputPipe,nil,PipeSize,@BytesRead,@PipeSize,@BytesRem);
    if bytesread > 0 then
      begin
        ReadFile(InputPipe,TextBuffer,pipesize,bytesread,nil);
        // a requirement for Windows OS system components
        Oemtochar(@TextBuffer,@TextBuffer);
        TextString := String(TextBuffer);
        SetLength(TextString,BytesRead);
        Result := TextString;
      end;
  end;

procedure monitor.Execute;
{ monitor thread execution for console output.  This must be threaded.
   checks the error and output pipes for information every 40 ms,pulls the
   data in and updates the memo on the form with the output }
var
  BytesRem: DWord;
begin
  while not Terminated do
    begin
      // read regular output stream and put on screen.
      TextString := ReadPipeInput(OutputPipeRead,BytesRem);
      if TextString <> '' then
         Synchronize(UpdateCaption);
      // Now read error stream and put that on screen.
      TextString := ReadPipeInput(ErrorPipeRead,BytesRem);
      if TextString <> '' then
         Synchronize(UpdateCaption);
      sleep(40);
    end;
end;

procedure monitor.UpdateCaption;
// synchronize procedure for monitor thread - updates memo on form.
begin
  With Form1.CommandText.Lines do
    Add(TextString);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  WritePipeOut(InputPipeWrite,'EXIT'); // quit the CMD we started
  MyThread.Terminate;
  // close process handles
  CloseHandle(ProcessInfo.hProcess);
  CloseHandle(ProcessInfo.hThread);
  // close pipe handles
  CloseHandle(InputPipeRead);
  CloseHandle(InputPipeWrite);
  CloseHandle(OutputPipeRead);
  CloseHandle(OutputPipeWrite);
  CloseHandle(ErrorPipeRead);
  CloseHandle(ErrorPipeWrite);
end;

procedure TForm1.Button2Click(Sender: TObject);
 { takes the input from the command edit Box and processes it }
  var
    UpText: String;
  begin
    UpText := UpperCase(CommandRun.Text);  // done to eliminate case-sensitivity
    if UpText = 'CLR' then        // clear the memo
      begin
        CommandText.Clear;
        WritePipeOut(InputPipeWrite,#13);
      end
    else
    if UpText = 'SAVELOG' then    // save the memo Box to a file.
      begin
        if SaveDialog1.Execute then
          begin
            CommandText.Lines.SavetoFile(SaveDialog1.FileName);
            CommandText.Lines.Add('Log file saved.');
          end
        else
          CommandText.Lines.Add('Log file not saved.');
      end
  // expand this,it needs to catch any variation where the command-interpreter
  // is called.  Any different ideas?
    else
    if UpText = 'CMD' then
       inc(cmdcount)
    else
    if UpText = 'COMMAND' then
       inc(cmdcount)
  // terminate app if user types exit,else let alone
    else
    if UpText = 'EXIT' then
      begin
        if cmdcount = 1 then
           Application.Terminate
        else
          dec(cmdcount);
      end
    else
      WritePipeOut(InputPipeWrite,CommandRun.Text);
    CommandRun.Items.Add(CommandRun.Text);
    CommandRun.Text := '';
    CommandRun.SetFocus;
  end;

procedure TForm1.FormCreate(Sender: TObject);
 { upon form creation,this calls the command-interpreter,sets up the three
   pipes to catch input and output,and starts a thread to monitor and show
   the output of the command-interpreter }
  var
    DosApp: String;
    DosSize: Integer;
    Security : TSecurityAttributes;
    start : TStartUpInfo;
  begin
    CommandText.Clear;
    // get COMSPEC variable,this is the path of the command-interpreter
    SetLength(Dosapp,255);
    DosSize := GetEnvironmentvariable('COMSPEC',@DosApp[1],255);
    SetLength(Dosapp,DosSize);

  // create pipes
    With Security do
      begin
        nlength := SizeOf(TSecurityAttributes) ;
        binherithandle := true;
        lpsecuritydescriptor := nil;
      end;
    CreatePipe(InputPipeRead,InputPipeWrite,@Security,0);
    CreatePipe(OutputPipeRead,OutputPipeWrite,0);
    CreatePipe(ErrorPipeRead,ErrorPipeWrite,0);

  // start command-interpreter
    FillChar(Start,Sizeof(Start),#0) ;
    start.cb := SizeOf(start) ;
    start.hStdInput := InputPipeRead;
    start.hStdOutput := OutputPipeWrite;
    start.hStdError :=  ErrorPipeWrite;
    start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
    start.wShowWindow := SW_HIDE;
    if CreateProcess(nil,PChar(DosApp),true,CREATE_NEW_CONSOLE or SYNCHRONIZE,start,ProcessInfo) then
      begin
        MyThread := monitor.Create(false);  // start monitor thread
        MyThread.Priority := tpHigher;
      end;
    Button2.Enabled := true;
    cmdcount := 1;
 end;

 end.

通过Delphi与命令提示符进行通信的更多相关文章

  1. 详解html5 postMessage解决跨域通信的问题

    这篇文章主要介绍了详解html5 postMessage解决跨域通信的问题的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. 详解使用postMessage解决iframe跨域通信问题

    这篇文章主要介绍了详解使用postMessage解决iframe跨域通信问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5 WebSocket实现点对点聊天的示例代码

    这篇文章主要介绍了HTML5 WebSocket实现点对点聊天的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. HTML5调用手机发短信和打电话功能

    这篇文章主要介绍了HTML5调用手机发短信和打电话功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

  6. 真正的iOS设备和Watch Simulator可以进行通信以进行测试

    我想为现有的iOS应用创建一个手表应用.但我处于一种情况,我没有苹果手表,我现有的iOS应用程序只能在不在模拟器上的真实设备上运行.是否可以在iPhone设备上运行应用程序并在手表模拟器中测试我的手表应用程序?解决方法至少在目前,不可能配对真正的iPhone和Watch模拟器.我得出这个结论有三个原因:>Watch模拟器在安装过程中自动与iPhone模拟器配对.>根本无法从界面取消配对Watch模拟器.>在模拟器上无法访问蓝牙以与真实设备进行通信.这是一个proof.

  7. ios – 在Swift中将输入字段字符串转换为Int

    所以我非常擅长制作APP广告Swift,我试图在文本字段中做一些非常简单的输入,取值,然后将它们用作Int进行某些计算.但是’vardistance’有些东西不正确它是导致错误的最后一行代码.它说致命错误:无法解开Optional.None解决方法在你的例子中,距离是一个Int?否则称为可选的Int..toInt()返回Int?因为从String到Int的转换可能失败.请参阅以下示例:

  8. 如何在iOS中检测文本(字符串)语言?

    例如,给定以下字符串:我想检测每个声明的字符串中使用的语言.让我们假设已实现函数的签名是:如果没有检测到语言,则返回可选字符串.因此,适当的结果将是:有一个简单的方法来实现它吗?

  9. xamarin – 崩溃在AccountStore.Create().保存(e.Account,“);

    在Xamarin.Forms示例TodoAwsAuth中https://developer.xamarin.com/guides/xamarin-forms/web-services/authentication/oauth/成功登录后,在aOnAuthenticationCompleted事件中,应用程序在尝试保存到Xamarin.Auth时崩溃错误说不能对钥匙串说期待着寻求帮助.解决方法看看你

  10. ios – 将视频分享到Facebook

    我正在编写一个简单的测试应用程序,用于将视频从iOS上传到Facebook.由于FacebookSDK的所有文档都在Objective-C中,因此我发现很难在线找到有关如何使用Swift执行此操作的示例/教程.到目前为止我有这个在我的UI上放置一个共享按钮,但它看起来已禁用,从我读到的这是因为没有内容设置,但我看不出这是怎么可能的.我的getVideoURL()函数返回一个NSURL,它肯定包含视

随机推荐

  1. delphi – 主窗口按进程名称处理

    DelphiXe,Win7x64如何从进程名称(exe文件的完整路径)获取主窗口句柄,或至少一个类或窗口名称(如果该进程只有一个窗口).例:解决方法我同意Petesh的说法,你需要枚举顶级窗口并检查创建它的进程的模块文件名.为了帮助您开始枚举顶级窗口,这是一个delphi实现.首先,当你回调给你时,你需要一些与EnumWindows方法通信的方式.为此声明一条记录,该记录将保存您要查找的模块的文件

  2. 如何在Delphi中纯粹通过RTTI信息(即不使用任何实际对象实例)获取TObjectList的子项类型?

    我正在使用RTTI实现用于流式传输任意Delphi对象的通用代码,并且为了使其工作(更具体地说,为了使加载部分工作),我需要以某种方式获得TObjectList的子项类型<T>不使用任何实际对象实例的字段.要求不使用任何实际对象实例的明显原因是,在从流加载对象的情况下(仅基于要加载的对象的类类型的知识),我将不会有任何实例在加载完成之前完全可用–我宁愿只能访问相关类的纯RTTI数据.我希望能

  3. inno-setup – Inno Setup – 安装程序背景图片

    图像作为安装程序背景如何用inno5.5.9做到这一点?

  4. inno-setup – Inno Setup – 如何添加多个arc文件进行解压缩?

    使用InnoSetup解压缩弧文件.我希望有可能解压缩多个arc文件以从组件选择中安装文件(例如).但仍然显示所有提取的整体进度条.这可能吗?的回答的修改预备是相同的,参考其他答案.在ExtractArc中,为要提取的每个存档调用AddArchive.

  5. delphi – 如何在DataSet的帮助下在TAdvStringGrid中显示数据库中的BLOB图像

    解决方法CreateBlobStream正在创建一个TStream对象,而不是TMemoryStream.由于您不想将JPG写入数据库,因此应使用bmRead而不是bmReadWrite.我不习惯sqlite,但你必须确保使用合适的二进制日期类型.为了确保存储的图像真的是JPG,您应该编写JPG以进行测试,例如:

  6. inno-setup – 在Inno Setup的Code部分下载程序后运行程序

    如何运行我通过Internet下载的应用程序,在代码部分中使用,并等待该应用程序完成运行.我有,使用InnoTools下载程序,下载这两个文件,我想,在第二个完成下载后运行该下载,或jdk-8u111-windows-x64.exe,然后继续安装.解决方法使用其他下载插件,而不是ITD(请参阅下面的原因).例如,InnoDownloadPlugin.当您包含idp.iss时,它定义了一个全局IDP

  7. progress-bar – Inno Setup Run部分的简单进度页面

    我的安装程序非常简单,它基本上是:>欢迎页面>进展页面>最终页面欢迎页面和最终页面是标准页面.在Progress页面,我正在静默安装一堆其他程序.实际的脚本是在[Run]部分中安装每个程序.问题是酒吧达到100%然后停留在那里.我只能更改消息文本.我想要实现的是使用Pascal脚本显示进度,例如:这样我就可以显示更准确的进度条.这就是我所拥有的:问题是,当我构建安装程序时,它不显示欢迎页面.我做错了什么?

  8. delphi – 如何使“显示/隐藏桌面图标”设置生效?

    下面的代码调用SHGetSetSettings函数来隐藏桌面图标但它只是从视图菜单中取消选中“显示桌面图标”.我打电话给SHChangeNotify;更新桌面,但这不起作用?解决方法isa,要刷新桌面,您可以将F5键发送到progman窗口隐藏桌面图标的另一种方法是再次显示

  9. inno-setup – Inno Setup – 避免显示子安装程序的文件名

    我试图使用InnoSetup–Howtohidecertainfilenameswhileinstalling?(FilenameLabel)的想法Theonlysuresolutionistoavoidinstallingthefiles,youdonotwanttoshow,usingthe[Files]section.Installthemusingacodeinstead.UsetheEx

  10. inno-setup – Inno Setup磁力链接下载实施

    我目前正在使用InnoDownloadPlugin为我的安装程序下载文件,这个问题最大的问题是faila正确下载文件.因为连接不良等诸多原因.我想添加一种替代方法来下载文件,因此用户可以选择是否需要常规方式或torrent方式.我知道我可以使用aria2c.exe应用程序(https://aria2.github.io/),有人可以帮我实现它的inno设置代码吗?我需要的是使用torrent(ar

返回
顶部