再线等待:如何在程序中获取正在运行的 do S 命令行,并将命令、参数传给命令行,并将命令运行??(50分)

  • 主题发起人 主题发起人 AsStone
  • 开始时间 开始时间
A

AsStone

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在程序中获取正在运行的 DOS 命令行,并将命令、参数传给命令行,并将命令运行??
 
findwindow('','MS-DOS 方式')

 
procedure TForm1.Button1Click(Sender: TObject);
var
wnd: HWND;
cmd: string;
i: integer;
begin
cmd := 'nbtstat -a 192.168.0.1';
wnd := findwindow('ConsoleWindowClass',nil);
if wnd<>0 then
begin
SetForegroundWindow(wnd);
SetActiveWindow(wnd);
for i := 1 to Length(cmd) do SendMessage(wnd,WM_CHAR,Ord(cmd),1);
keybd_event(VK_RETURN, $45, KEYEVENTF_EXTENDEDKEY or 0, 0);
keybd_event(VK_RETURN, $45, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
end
else ShowMessage('无DOS窗口');
end;
 
to zw84611:
谢谢回答,只能切到 DOs 界面,但是命令行和参数并不能到提示符号下,并且不能运行
 
我这儿可以,我用的是Win2k,98没试过。
 
谢谢:如果行的话,待会给你加分。
98 可以吗?
 
可能要通过DOS程序的输入流进行操作:
以下供参考
20. 为DOS程序做WINDOWS外壳程序
有时会在程序中调用DOS程序,并且要求得到程序的返回值,这应该如何实现呢?通常在WINDOWS程序中调用外部程序,可以使用ShellExecute或者WinExecute这些API函数,但这些函数并不能得到程序的返回值,今天我们来介绍CreateProcess这个API函数。
函数介绍如下:
BOOL CreateProcess(
LPCTSTR lpApplicationName, // 可执行文件名
LPTSTR lpCommandLine, // 执行命令
LPSECURITY_ATTRIBUTES lpProcessAttributes,
// 指向SECURITY_ATTRIBUTES结构,通常为NULL(nil)
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 同上
BOOL bInheritHandles, // 是否能继承现在的句柄
DWORD dwCreationFlags, // 新进程的参数设定
LPVOID lpEnvironment, // 新进程的环境参数
LPCTSTR lpCurrentDirectory, // 当前目录名
LPSTARTUPINFO lpStartupInfo, // 指向 STARTUPINFO 结构,用于设定一些参数
LPPROCESS_INFORMATION lpProcessInformation
//指向 PROCESS_INFORMATION 结构,用于返回新进程的信息
);

重要结构介绍
STARTUPINFO
(
DWORD cb; //结构大小
LPTSTR lpReserved; //保留,必须为nil
LPTSTR lpDesktop; //进程所在的桌面名,仅NT有效
LPTSTR lpTitle; //进程标题
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags; //显示那些参数有效
WORD wShowWindow; //是否显示窗口
WORD cbReserved2; //保留,必须为0
LPBYTE lpReserved2; //保留,必须为nil
HANDLE hStdInput; //新进程的标准输入句柄
HANDLE hStdOutput; //新进程的标准输出句柄
HANDLE hStdError; //新进程的标准错误句柄
)
程序分析,程序源码下载(ProcessTest.zip)
procedure TMainForm.Button2Click(Sender: TObject);
var
 OutHandle:THandle;
 sinfo:_STARTUPINFOA;
 processinfo:_PROCESS_INFORMATION;
 CurFileName:string;
 ExitCode:Cardinal;
 nCount:integer;
begin
CurFileName:=CurDir+'/temp.txt';
//临时文件名
//create the output file 's handle
OutHandle:=CreateFile(pchar(CurFileName),GENERIC_WRITE,
FILE_SHARE_WRITE,nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
//set the start information property
sinfo.cb:=sizeof(sinfo);
sinfo.lpReserved:=nil; //set all reserved property to the defined property
sinfo.lpDesktop:=nil;
sinfo.lpTitle:=nil;
sinfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES ;
sinfo.wShowWindow:=SW_HIDE;
sinfo.cbReserved2:=0;
sinfo.lpReserved2:=nil;
sinfo.hStdOutput:=OutHandle;//set the output handle
sinfo.hStdInput:=STD_INPUT_HANDLE ;//set to default
sinfo.hStdError:=STD_ERROR_HANDLE ;
if not(CreateProcess(nil,pchar(Edit1.Text),nil,nil,true,
CREATE_NEW_CONSOLE,nil,nil,sinfo,processinfo))
then
  begin
ShowMessage('Process can not be created');
CloseHandle(OutHandle);
  end;

nCount:=0;
//set the time out
//wait for process stop
while (GetExitCodeProcess(processinfo.hProcess,ExitCode))and
(ExitCode=STILL_ACTIVE)and(nCount<MaxCount) do
begin
Sleep(500);
inc(nCount);
end;
if not(GetExitCodeProcess(processinfo.hProcess,ExitCode)) or
(ExitCode=STILL_ACTIVE) then //time out , mannualy close process
TerminateProcess(processinfo.hProcess,0); 
CloseHandle(OutHandle);

//load the output to the memo
memo1.Lines.LoadFromFile(CurFileName);
end;



123. 获得Dos程序的输出屏幕内容
在Delphi程序中如何获得Dos程序的输出屏幕内容(像Delphi编译器 后台执行Dos编译程序,而在IDE界面下给处系统的编译器输出信息)
利用DOS程序的输出重定向功能 dir >> aa.txt 将DOS程序的输出内容生成临时文件aa.txt,使用DELPHI的FileOpen、FileRead等函数取得aa.txt文件的内容,即可。
Delphi6 Win2k:
procedure TForm1.btnRunClick(Sender: TObject);
var
hReadPipe,hWritePipe:THandle;
si:STARTUPINFO;
lsa:SECURITY_ATTRIBUTES;
pi:PROCESS_INFORMATION;
mDosScreen:String;
cchReadBuffer:DWORD;
ph:PChar;
fname:PChar;
i,j:integer;
begin
fname:=allocmem(255);
ph:=AllocMem(5000);
lsa.nLength :=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor :=nil;
lsa.bInheritHandle :=True;

if CreatePipe(hReadPipe,hWritePipe,@lsa,0)=false then
begin
ShowMessage('Can not create pipe!');
exit;
end;
fillchar(si,sizeof(STARTUPINFO),0);
si.cb :=sizeof(STARTUPINFO);
si.dwFlags :=(STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);
si.wShowWindow :=SW_HIDE;
si.hStdOutput :=hWritePipe;
StrPCopy(fname,'CMD.EXE /c dir/w');

if CreateProcess( nil, fname, nil, nil, true, 0, nil, nil, si, pi) = False then
begin
ShowMessage('can not create process');
FreeMem(ph);
FreeMem(fname);
Exit;
end;

while(true) do
begin
if not PeekNamedPipe(hReadPipe,ph,1,@cchReadBuffer,nil,nil) then break;
if cchReadBuffer<>0 then
begin
if ReadFile(hReadPipe,ph^,4096,cchReadBuffer,nil)=false then break;
ph[cchReadbuffer]:=chr(0);
Memo1.Lines.Add(ph);
end
else if(WaitForSingleObject(pi.hProcess ,0)=WAIT_OBJECT_0) then break;
Sleep(100);
end;
ph[cchReadBuffer]:=chr(0);
Memo1.Lines.Add(ph);
CloseHandle(hReadPipe);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hWritePipe);
FreeMem(ph);
FreeMem(fname);
end;



 
to jsxjd:
这个方法是等待运行结束后才能得到结果的
有没可即时交流的方法?
 
后退
顶部