注册 登录
编程论坛 Delphi论坛

用delphi7怎么调用DOS并显示在label(标签)里??

lfkm 发布于 2008-04-19 19:35, 3841 次点击
我想在一个TEXT控件里输入dos命令 dir c\*.*. 然后按确定后,dos里显示的内容都转到label(标签)里显示,而不是在dos里显示..(界面上有TEXT、BUTTON、LABEL三个控件)
那位高手能帮帮忙写出一个完整的源代码吗?我看了几天网上介绍都看不懂,也不是我想要的结果.
14 回复
#2
yeye552008-04-19 20:11
第一:为什么要用label?用Memo不是更好?
第二:对于内部命令要写成cmd /c dir *.*的格式,Win98是command /c dir *.*,因为内部命令没有对应的可执行文件。

核心代码如下:

procedure TForm1.Button1Click(Sender: TObject);
var
    SecurityAttributes : TSecurityAttributes;
    hProcess           : TProcessInformation;
    StartupInfo        : TStartupInfo;
    hReadPipe,hWritePipe : THandle;
    Buff : array [0..256] of char;
    Num : DWORD;
    dwExit:DWORD;
    SendName : String;
    s : String;
begin
    SecurityAttributes.nLength:=Sizeof(SecurityAttributes);
    SecurityAttributes.lpSecurityDescriptor:=nil;
    SecurityAttributes.bInheritHandle:=true;
    CreatePipe(hReadPipe,hWritePipe,@SecurityAttributes,0);
    FillChar(StartupInfo,Sizeof(StartupInfo),#0);
    StartupInfo.cb:=Sizeof(StartupInfo);
    StartupInfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    StartupInfo.wShowWindow:=SW_HIDE;
    StartupInfo.hStdOutput:=hWritePipe;
    StartupInfo.hStdError:=hWritePipe;
    if CreateProcess(nil,PChar(self.Edit1.Text),
                     @SecurityAttributes,
                     @SecurityAttributes,
                     true,0,nil,nil,
                     StartupInfo,
                     hProcess) then
    begin
        CloseHandle(hProcess.hThread);
        WaitForSingleObject(hProcess.hProcess,INFINITE);
        GetExitCodeProcess(hProcess.hProcess,dwExit);
        CloseHandle(hProcess.hProcess);
        CloseHandle(hWritePipe);
        Num:=0; s:='';
        while ReadFile(hReadPipe,Buff,256,Num,nil) do
        begin
            Buff[Num]:=#0;
            s:=s+Buff;
        end;
        CloseHandle(hReadPipe);
        //
        self.Label1.Caption:=s;
    end
    else
        MessageBox(self.Handle,PChar('调用命令 '+self.Edit1.Text+' 失败!'),'调用失败',MB_OK or MB_ICONWARNING);
end;
#3
lfkm2008-04-19 20:45
谢谢楼上的高手.至于用LABEL还是MEMO,是个人喜欢,我是个新手只知道LABEL可以显示,还没有懂得别的控件可用呢.
那你就改用MEMO吧.
可是我在TEXT里输入DIR.结果是'调用DIR失败'
问题出在哪?
#4
DreamHK2008-04-19 21:45
设置label1的AutoSize属性为false,WordWrap属性为true.

procedure TForm1.Button1Click(Sender: TObject);
var
  cmd:string;
  tmp:integer;
  buffer:array [0..1000]of char;
begin
  cmd:=edit1.Text;
  winexec(pchar('cmd /c '+cmd+' >tmp.tmp'),sw_hide);
  sleep(100);//如果要执行的命令比较耗时,请设置一定的等待时间.(内部命令不必...)
  tmp:=fileopen('tmp.tmp',fmOpenReadWrite);
  fileread(tmp,buffer,sizeof(buffer));
  label1.Caption:=buffer;
  fileclose(tmp);
end;
#5
DreamHK2008-04-19 21:49
用memo控件的话更简单:
procedure TForm1.Button1Click(Sender: TObject);
var
  cmd:string;
begin
  cmd:=edit1.Text;
  winexec(pchar('cmd /c '+cmd+' >tmp.tmp'),sw_hide);
  sleep(100);
  memo1.Lines.LoadFromFile('tmp.tmp');
end;
#6
yeye552008-04-19 22:17
[bo]以下是引用 [un]lfkm[/un] 在 2008-4-19 20:45 的发言:[/bo]

谢谢楼上的高手.至于用LABEL还是MEMO,是个人喜欢,我是个新手只知道LABEL可以显示,还没有懂得别的控件可用呢.
那你就改用MEMO吧.
可是我在TEXT里输入DIR.结果是'调用DIR失败'
问题出在哪? ...


要输入:cmd /c dir
#7
lfkm2008-04-20 01:22
[bo]以下是引用 [un]yeye55[/un] 在 2008-4-19 22:17 的发言:[/bo]



要输入:cmd /c dir

好像只对存放delphi文件路径有用.我把CMD /C DIR改为CMD /F DIR就看存放该文件路径了.
CMD /C DIR中的/C是不是C盘?
#8
lfkm2008-04-20 01:31
[bo]以下是引用 [un]DreamHK[/un] 在 2008-4-19 21:45 的发言:[/bo]

设置label1的AutoSize属性为false,WordWrap属性为true.

procedure TForm1.Button1Click(Sender: TObject);
var
  cmd:string;
  tmp:integer;
  buffer:array [0..1000]of char;
begin
  cmd:=edit1.Text;
  winexe ...

这方法对用DIR很合我意思了..哈哈..只是我再用ipconfig想查下IP就要等好久和狂按按钮才看它一闪而过,为什么会这样呢?
#9
lfkm2008-04-20 01:46
[bo]以下是引用 [un]DreamHK[/un] 在 2008-4-19 21:49 的发言:[/bo]

用memo控件的话更简单:
procedure TForm1.Button1Click(Sender: TObject);
var
  cmd:string;
begin
  cmd:=edit1.Text;
  winexec(pchar('cmd /c '+cmd+' >tmp.tmp'),sw_hide);
  sleep(100);
  memo1.Lines.LoadFr ...

用这个使用ipconfig就直接报错.说有另一个程序在使用它之类的.
不过还是谢谢高手了..哈哈...解决一个又出来一个...
#10
yeye552008-04-20 09:28
[bo]以下是引用 [un]lfkm[/un] 在 2008-4-20 01:22 的发言:[/bo]


好像只对存放delphi文件路径有用.我把CMD /C DIR改为CMD /F DIR就看存放该文件路径了.
CMD /C DIR中的/C是不是C盘?


cmd 是启动命令行的意思,/c 的意思是启动命令行后执行随后的命令,dir 是一个内部命令,例如:查看F盘根目录就要输入 cmd /c dir f:\

ipconfig 是一个外部命令,外部命令是以一个单独的可执行文件形式存放,ipconfig.exe 位于C:\WINNT\system32文件夹下,调用外部命令可以直接输入命令,例如:输入 ipconfig /all
#11
lfkm2008-04-20 12:16
[bo]以下是引用 [un]yeye55[/un] 在 2008-4-20 09:28 的发言:[/bo]



cmd 是启动命令行的意思,/c 的意思是启动命令行后执行随后的命令,dir 是一个内部命令,例如:查看F盘根目录就要输入 cmd /c dir f:\

ipconfig 是一个外部命令,外部命令是以一个单独的可执行文件形式存放,ipconfig.exe 位 ...

谢谢了.辛苦了..哈哈...
#12
provoke2008-04-20 16:07
有和种更容易理解、更容易实现的方法,但要稍稍“绕”一下圈子:
把执行命令的结果,即原本在命令提示符里显示的,保存为文本文件,然后再将文本文件的内容加载到Memo,最后删除临时文件。

其中的关键操作都比较简单:
Command>filename:将执行命令的结果保存为文件,如dir C:>E:\temp.txt将执行“dir c:”的执行结果保存到“E:\temp.txt”;
Memo1.Lines.LoadFromFile('E:\temp.txt'):将文本文件的内容加载到Memo;
删除文件;
deletefile('E:\temp.txt'):删除文件。
都比较简单……

将执行结果保存在程序目录下,指定一个特殊一点的文件名以保存当前目录下不会有同名文件存在;
#13
DreamHK2008-04-20 17:22
[bo]以下是引用 [un]lfkm[/un] 在 2008-4-20 01:31 的发言:[/bo]


这方法对用DIR很合我意思了..哈哈..只是我再用ipconfig想查下IP就要等好久和狂按按钮才看它一闪而过,为什么会这样呢?


sleep(100);//如果要执行的命令比较耗时,请设置一定的等待时间.(内部命令不必...)
你没注意我这句话吧.ipconfig的执行是比较耗时的...所以会导致执行结果还未完全写入文件就被读取了... 而管道操作又是以独占方式打开文件的,在文件关闭之前再想打开,就会出现第二个程序中的错误了.你可以用try.except.catch来捕获这个错误,如果出错,则sleep(10),否则加载文件的内容.

[[it] 本帖最后由 DreamHK 于 2008-4-20 17:24 编辑 [/it]]
#14
lfkm2008-04-20 20:52
[bo]以下是引用 [un]provoke[/un] 在 2008-4-20 16:07 的发言:[/bo]

有和种更容易理解、更容易实现的方法,但要稍稍“绕”一下圈子:
把执行命令的结果,即原本在命令提示符里显示的,保存为文本文件,然后再将文本文件的内容加载到Memo,最后删除临时文件。

其中的关键操作都比较简单:
Command>fi ...

你说的这种方法应该就是批处理文件方法吧.不过我连它的格式都不会写呢.
#15
lfkm2008-04-20 20:57
[bo]以下是引用 [un]DreamHK[/un] 在 2008-4-20 17:22 的发言:[/bo]



sleep(100);//如果要执行的命令比较耗时,请设置一定的等待时间.(内部命令不必...)
你没注意我这句话吧.ipconfig的执行是比较耗时的...所以会导致执行结果还未完全写入文件就被读取了... 而管道操作又是以独占方式 ...

我是没明白你的那个注释而不是没有看到..哈哈...
是不是现在把它改为SLEEP(10)就出现快了(不管对错).
1