永发信息网

求教cmd和delphi互相传递变量以及交互的好办法?

答案:3  悬赏:0  手机版
解决时间 2021-03-25 19:12
求教cmd和delphi互相传递变量以及交互的好办法?
最佳答案
貌似很难。用Delphi模拟CMD容易,要从cmd窗口读取返回信息很难。在网上给你搜索到一个例子,未证实,你可以自行验证一下:

测试目标: 设计一个虚拟的Dos控制台,包含一个Memo和一个ComboBox,要求可以在ComboBox中输入Dos命令,然后由系统捕获命令输出的结果显示在Memo中.

程序设计思路:
首先,利用WIN API函数 Createpipe 建立两个管道(Pipe),然后建立利用CreateProcess函数创建一个控制台程序的进程(这里使用的是Win2000的Dos控制台 cmd.exe),并且在StartUpInfo参数中指定用刚才建立的三个管道替换标准的输入hStdOutput、输出hStdInput以及错误输出设备hStdError。
代码如下:
procedure TForm1.InitConsole;
var
Security: TSecurityAttributes;
start: TStartUpInfo;
begin
with Security do begin
nlength := SizeOf(TSecurityAttributes);
binherithandle := true;
lpsecuritydescriptor := nil;
end;
Createpipe(ReadOut, WriteOut, @Security, 0);
Createpipe(ReadIn, WriteIn, @Security, 0);
with Security do begin
nlength := SizeOf(TSecurityAttributes);
binherithandle := true;
lpsecuritydescriptor := nil;
end;
FillChar(Start, Sizeof(Start), #0);
start.cb := SizeOf(start);
start.hStdOutput := WriteOut;
start.hStdInput := ReadIn;
start.hStdError := WriteOut;
start.dwFlags := STARTF_USESTDHANDLES +
STARTF_USESHOWWINDOW;
start.wShowWindow := SW_HIDE;
CreateProcess(nil,
PChar('cmd'),
@Security,
@Security,
true,
NORMAL_PRIORITY_CLASS,
nil,
nil,
start,
ProcessInfo)
end;
然后利用一个定时器,从对应输出设备的管道中读取控制台返回的信息,并显示。
代码如下:
function TForm1.ReadFromPipe(Pipe: THandle): string;
var
Buffer: PChar;
BytesRead: DWord;
begin
Result := '';
if GetFileSize(Pipe, nil) = 0 then Exit;
Buffer := AllocMem(ReadBuffer + 1);
repeat
BytesRead := 0;
ReadFile(Pipe, Buffer[0],
ReadBuffer, BytesRead, nil);
if BytesRead > 0 then begin
Buffer[BytesRead] := #0;
OemToAnsi(Buffer, Buffer);
Result := string(Buffer);
end;
until (BytesRead < ReadBuffer);
FreeMem(Buffer);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
s: string;
begin
s := ReadFromPipe(ReadOut);
if s <> '' then begin
Memo1.Lines.Text := Memo1.Lines.Text + s;
Memo1.SelStart := Length(Memo1.Lines.Text);
Memo1.SelLength := 0;
end;
end;
在下方的输入框内输入命令之后,则通过向输入设备对应的管道发送命令来实现命令行的输入,代码如下:
procedure TForm1.WriteToPipe(Pipe: THandle; Value: string);
var
len: integer;
BytesWrite: DWord;
Buffer: PChar;
begin
len := Length(Value) + 1;
Buffer := PChar(Value + #10);
WriteFile(Pipe, Buffer[0], len, BytesWrite, nil);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if Trim(cbCmd.Text) <> '' then begin
WriteToPipe(WriteIn, cbCmd.Text);
if cbCMD.ItemIndex > -1 then
cbCMD.Items.Delete(cbCMD.ItemIndex);
cbcmd.Items.Insert(0, cbCmd.Text);
cbCmd.Text:='';
end;
end;
这里要注意的是发送命令行的时候必须添加换行字符#10,才能被Dos控制台接受并执行
全部回答
用.txt去把result传回去这样应该是ok的..
我之前的做法是善用bat的功能
例如:我要做ping这个动作, 再用delphi看ping是否成功
function ping(pingTarget : string) : boolean;
var
BATRun : TStringList;
ResultText : TStringList;
begin
BATRun := TStringList.Create;
BATRun.add('ping pingTarget > result.txt');
BATRun.add('copy NUL flag');
BATRun.SaveToFile('run.bat');
WinExec('run.bat', 0);
repeat
sleep(100);
until FileExists('flag');
ResultText := TStringList.create;
ResultText.LoadFromFile('result.txt');
result := true;
DeleteFile('flag');
DeleteFile('run.bat');
DeleteFile('result.txt');
end;
这样写的话就可以把在cmd执行的ping结果放进一个StringList里面了
要给控制台命令行传输参数是很容易的。
但是要获取控制台命令行运行的状态就没那么容易了。这个和是否使用Delphi没什么关系,你需要参考MSDN上相关的内容。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
方钢300x300x14x14每米重量
自从前几个星期开始几乎每天都会被至少一个老
是选择94年的CB400还是选择99年的ZZR400
老兵台球地址在哪,我要去那里办事
太极拳这么多版本,学习哪个好?强身健体最有
电脑i5四核 120g 500g 4g独显是什么意思
英特尔酷睿i3 双核 i3-530和英特尔G2030哪个
C语言问题 输出四个数的第二大
求下列图形的表面积和体积.
雍正别称有什么例:自称“天下第一闲人雍正也
情浓诗百篇 意陌笔生寒 缘似流水去 痴琴对谁
穿衣服时男士T恤上肩膀处那条线应该在那个地
衢州鸭头做法
为什么二战初期法国空军不强
iphoneX 打不进电话和打不出电话
推荐资讯
请问各位奥运金玉笔现在值多少钱了?
秋天一件快乐的事作文怎么写
网名浅夏初凉有情侣
人嘴吹气压力多大 记得是0.07mpa对吗
校园网中某应用服务器的IP地址是172.16.1.18
qq飞车4月宝箱4月钥匙怎么得有什么用 qq飞
我想要回答搜搜问问里面关于手机的问题,因为
苹果手机有那些优点
春雨和冬,夏,秋雨有什么不同,详细
买黄金石买老凤祥的好还是买周大金的好?
我的电脑里面DEF盘其实是主机里面的一个硬盘
求校内刷人气软件
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?