`
hulunberbus
  • 浏览: 858683 次
文章分类
社区版块
存档分类
最新评论

执行命令并从与控制台进行交互

 
阅读更多

unit uConsole;

interface

uses windows;

type
TOnData = procedure(Sender: TObject; Data: String) of object;
TOnRun = procedure(Sender: TObject) of object;
TRedirectedConsole = Class(TObject)
private
fStdInRead, fStdInWrite: THandle;
fStdOutRead, fStdOutWrite: THandle;
fStdErrRead, fStdErrWrite: THandle;
fSA: TSecurityAttributes;
fPI: TProcessInformation;
fSI: TStartupInfo;
fCmdLine: String;
fOnStdOut, fOnStdErr: TOnData;
fOnRun, fOnEnd: TOnRun;
fIsRunning: Boolean;
fHidden: boolean;
fTerminate: boolean;
function ReadHandle(h: THandle; var s: string): integer;
protected
public
constructor Create(CommandLine: String);
destructor Destroy; override;
procedure Run;
procedure SendData(s: String);
property OnStdOut: TOnData read fOnStdOut write fOnStdOut;
property OnStdErr: TOnData read fOnStdErr write fOnStdErr;
property OnRun: TOnRun read fOnRun write fOnRun;
property OnEnd: TOnRun read fOnEnd write fOnEnd;
property IsRunning: boolean read fIsRunning;
property HideWindow: boolean read fHidden write fHidden;
end;

implementation

const BufSize = 1024;

constructor TRedirectedConsole.Create(CommandLine: String);
begin
inherited Create;
fCmdLine := CommandLine;
fIsRunning := False;
fHidden := True;
FillChar(fSA, SizeOf(fSA), 0);
fSA.nLength := SizeOf(fSA);
fSA.lpSecurityDescriptor := nil;
fSA.bInheritHandle := True;
CreatePipe(fStdInRead, fStdInWrite, @fSA, BufSize);
CreatePipe(fStdOutRead, fStdOutWrite, @fSA, BufSize);
CreatePipe(fStdErrRead, fStdErrWrite, @fSA, BufSize);
end;

destructor TRedirectedConsole.Destroy;
begin
if fIsRunning then
begin
fTerminate := True;
end;
CloseHandle(fStdInWrite);
CloseHandle(fStdOutRead);
CloseHandle(fStdErrRead);
inherited;
end;

function TRedirectedConsole.ReadHandle(h: THandle; var s: String): integer;
var
BytesWaiting: Cardinal;
Buf: Array[1..BufSize] of char;
{$IFDEF VER100}
BytesRead: Integer;
{$ELSE}
BytesRead: Cardinal;
{$ENDIF}
begin
Result := 0;
PeekNamedPipe(h, nil, 0, nil, @BytesWaiting, nil);
if BytesWaiting > 0 then
begin
if BytesWaiting > BufSize then
BytesWaiting := BufSize;
ReadFile(h, Buf[1], BytesWaiting, BytesRead, nil);
s := Copy(Buf, 1, BytesRead);
Result := BytesRead;
end;
end;

procedure TRedirectedConsole.SendData(s: String);
var
{$IFDEF VER100}
BytesWritten: Integer;
{$ELSE}
BytesWritten: Cardinal;
{$ENDIF}
begin
if fIsRunning then
begin
WriteFile(fStdInWrite, s[1], Length(s), BytesWritten, nil);
end;
end;

procedure TRedirectedConsole.Run;
var
s: String;
begin
fTerminate := False;
FillChar(fSI, SizeOf(fSI), 0);
fSI.cb := SizeOf(fSI);
if fHidden then
fSI.wShowWindow := SW_HIDE
else
fSI.wShowWindow := SW_SHOWDEFAULT;
fSI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
fSI.hStdInput := fStdInRead;
fSI.hStdOutput := fStdOutWrite;
fSI.hStdError := fStdErrWrite;
if CreateProcess(nil, PChar(fCmdLine), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, fSI, fPI) then
begin
fIsRunning := True;
CloseHandle(fStdOutWrite);
CloseHandle(fStdErrWrite);
CloseHandle(fStdInRead);
CloseHandle(fPI.hThread);
While WaitForSingleObject(fPI.hProcess, 10) = WAIT_TIMEOUT do
begin
if fTerminate then
begin
TerminateProcess(fPi.hProcess, 0);
end;
if ReadHandle(fStdOutRead, s) > 0 then
if Assigned(fOnStdOut) then
fOnStdOut(Self, s);
if ReadHandle(fStdErrRead, s) > 0 then
if Assigned(fOnStdErr) then
fOnStdErr(Self, s);
if Assigned(fOnRun) then
fOnRun(Self);
end;
if ReadHandle(fStdOutRead, s) > 0 then
if Assigned(fOnStdOut) then
fOnStdOut(Self, s);
if ReadHandle(fStdErrRead, s) > 0 then
if Assigned(fOnStdErr) then
fOnStdErr(Self, s);
CloseHandle(fPI.hProcess);
fIsRunning := False;
if Assigned(fOnEnd) then
fOnEnd(Self);
end;
end;

end.

分享到:
评论

相关推荐

    Python控制台实现交互式环境执行

    Python控制台打开之后,会直接进入交互式环境,显示提示符“>>>”。 而命令行程序则会显示DOS的命令提示符,我们需要输入“Python”或者“Python3”进入交互式环境。 一般来说,顺利安装Python之后,有两种方式可以...

    Jsch批量执行多条命令,包含切换用户输入密码

    参考expect4j的交互式操作方式控制输入输出流实现批量执行多条shell命令同时支持切换用户输入密码提权执行命令输入密码等操作 有完整的测试用例,便于理解 模板化执行命令示例 [$]send[su - root] [Password:]...

    基于java socket使用tcp udp进行简易控制台命令与文件传输

    4) 服务器启动后,开启TCP:2021端口,UDP:2020端口,其中,TCP连接负责与用户交互,UDP负责传送文件; 5) 客户端启动后,连接指定服务器的TCP 2021端口,成功后,服务器端回复信息:“客户端IP地址:客户端端口号>...

    pstools 远程命令执行工具

    PsExec 是一个轻型的 telnet 替代工具,它使您无需手动安装客户端软件即可执行其他系统上的进程,并且可以获得与控制台应用程序相当的完全交互性。PsExec 最强大的功能之一是在远程系统和远程支持工具(如 IpConfig...

    nosh:交互式基于文本的控制台,带有用于 Java 应用程序的可插入命令

    它只能执行使用 Nash API 实现并与相应应用程序捆绑在一起的命令。 外部可执行文件或脚本文件无法从 Nosh 启动。 如果没有相应应用程序的源代码级修改和重新构建,则无法启用其他命令。 特征 本地可访问 给定 Nash ...

    GDB调试流程及命令大全

    一旦连接成功,您就可以使用一系列GDB命令来与程序进行交互,如: - `break` 设置断点 - `run` 运行程序 - `step` 单步执行程序 - `print` 打印变量值 - `backtrace` 回溯当前函数调用堆栈 - `continue` 继续程序的...

    cmd操作命令和linux命令大全收集

    start 程序名或命令 /max 或/min 新开一个新窗口并最大化(最小化)运行某程序或命令 mem 查看cpu使用情况 attrib 文件名(目录名) 查看某文件(目录)的属性 attrib 文件名 -A -R -S -H 或 +A +R +S +H 去掉...

    如何使用labview操作CMD窗口,

    如何使用labview操作CMD窗口,比如关闭windows窗口,关闭windows后台应用程序,调用cmd,事实上,我们需要的很多系统操作方面,的功能在DOS命令中都能找到,每一个DOS命令都是针对操作系统的,凡是涉及到系统调用,而用...

    ObjectARX 人机交互技术原型程序介绍

    通过研读头文件,仔细阅读帮助文档,终于明白这个技术可以称为人机交互技术的组成部分,也是 ObjectARX for AutoCAD 隐藏的技术之一,这些技术就隐藏在 ObjectARX 应用程序同 AutoCAD 作用并进行用户输入的许多个...

    lapis-console:用于Lapis的交互式控制台

    青金石控制台 Web框架的交互式控制台。 -- app.moonlapis = require " lapis "console = require " lapis.console "class extends lapis . Application " /console " : console . make!$ lapis server development ...

    CUDLR::no_entry:[已弃用]控制台,用于远程进行Unity调试和记录

    为此,CUDLR在目标设备上启动一个Web服务器来托管静态文件,并公开一个HTTP API以执行可以与您的项目交互的命令。 我们编写了CUDLR以便在即将推出的游戏。 有关我们编写它的原因以及我们发布的其他工具的更多信息,

    浅谈Pycharm中的Python Console与Terminal

    Python交互式模式可以直接输入代码,然后执行,并立刻得到结果,因此Python交互模式主要是为了调试Python代码用的。 命令行模式与系统的CMD(命令提示符)一样,可以运行各种系统命令。 以上这篇浅谈Pycharm中...

    dos命令大全.pdf

    ASSOC 显示或修改文件扩展名关联。 ATTRIB 显示或更改文件属性。 BREAK 设置或清除扩展式 CTRL+C 检查。 BCDEDIT 设置启动数据库中的属性以控制启动加载。...WMIC 在交互式命令 shell 中显示 WMI 信息。

    QPowerShell:通过 Qt C++ 与 Windows PowerShell 交互的简单模块

    QPowerShell 为 Qt C++ 开发人员提供了一种与 Windows PowerShell CLI 交互的简单方法。 它仅在 PS 2.0 上进行过测试,但也应在较新的版本上进行测试。 这是我向公众发布的第一个项目。 请随时提交错误、建议或功能...

    一个用c#实现飞信的例子

    这是一个飞信精灵或者机器人一类的软件,可以用你的飞信帐号登陆,发短信或者用飞信IM与之交互,执行精灵命令或计划任务. 并用短信或飞信IM消息的方式反馈执行结果的软件 二.功能 目前只有三个插件,如果你喜欢你可以...

    入门学习Linux常用必会60个命令实例详解doc/txt

    这是因为Linux和许多版本的Unix一样,提供了虚拟控制台的访问方式,允许用户在同一时间从控制台(系统的控制台是与系统直接相连的监视器和键盘)进行多次登录。每个虚拟控制台可以看作是一个独立的工作站,工作台...

    Admin-bot:小型Discord机器人,可与IW4M Admin的api交互并执行Discord中的命令

    先决条件或更高版本版本2021.1.18.2或更高版本安装视窗安装Node.js 解压Admin-bot.zip 编辑config.js (添加您的令牌,前缀,webfronturl和adminid) 在管理bot的目录内打开控制台,输入npm i并按Enter键在命令提示...

    基于C++的K-V数据库File based K-V Database.zip

    循环内输出交互内容,交互内容包括但不限于数据库支持输入类型以及数据库支持的命令列表,在一次循环结束清空控制台内容; 输入命令;若为不支持的命令则输出error command并进入下一循环,若为支持的命令则利用if…...

    HP MP卡使用

    管理处理器是服务器的独立支持系统。使用它可以连接到服务器并执行服务器 硬件的管理或监视任务。管理处理器可以管理电源、重置和控制转移 (TOC) 功能,并可用于访问...多个用户可以同时与管理处理器进行交互操作

    multiplex:使用交互式TUI在控制台中并行查看多个进程的输出

    并行执行命令 mp \ ' ./some-long-running-process.py --zone z1 ' \ ' ./some-long-running-process.py --zone z2 ' \ ' ./some-long-running-process.py --zone z3 ' 您可以像这样使用Python API达到相同的效果...

Global site tag (gtag.js) - Google Analytics