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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求教cmd和delphi互相传递变量以及交互的好办法?相关的知识,希望对你有一定的参考价值。

各位,请问大家有没有cmd和delphi互相传递变量以及交互的好办法?用delphi winexec('cmd /c echo jjww>test.txt') ,然后配合sleep读取test.txt虽然可以,但是要考虑到时间上的问题。,比如有些机器快一些,有些机器慢一些,。。比较麻烦。。
因为我个人比较熟悉批处理,感觉里面的很多东西比较方便,比如获取计算机名称,echo %computername%就出来了,又比如有时候想把delphi的一些变量附加到一段cmd语句中,或者说delphi想获取上一条cmd命令的执行结果,%errorlevel%变量,所以希望能学到一个好的办法能在cmd和delphi之间互相传递变量。
本人delphi很烂。。。各位高手,请给出完成的函数或者过程,以及要uses的东西,尽量把所需的东西都说完整,谢谢!

貌似很难。用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控制台接受并执行
参考技术A 要给控制台命令行传输参数是很容易的。
但是要获取控制台命令行运行的状态就没那么容易了。这个和是否使用Delphi没什么关系,你需要参考MSDN上相关的内容。
参考技术B 用.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里面了

以上是关于求教cmd和delphi互相传递变量以及交互的好办法?的主要内容,如果未能解决你的问题,请参考以下文章

delphi 求教

全局变量和环境变量的区别

求教json的有关问题,google库gson的bug有关问题

automapper在ORM中的作用,求教?

求教delphi 中fastreport报表的问题

数据库操作语句中变量的使用 - Delphi