如何控制DOS程序的输入?(300分)

  • 主题发起人 主题发起人 Yhhe
  • 开始时间 开始时间
Y

Yhhe

Unregistered / Unconfirmed
GUEST, unregistred user!
在自己的程序中如何控制DOS程序的输入?<br>&nbsp;如在自己的程序中启动 "Foxpro For DOS"并由程序自己输入命令如"Quit"?<br>请大家帮帮忙吧,只要问题解决300分奉送
 
也许写个bat吧
 
参考<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=618422
 
cmd.exe&lt;a.txt
 
tseug,你的是传一个文件过去,能传字符吗?
 
可以, 那个例子是临时写的, 我正在写一个在GUI下运行DOS程序并可以输入输出<br>的例子, 估计明天能贴上来...
 
tseug,拜托写好给我发一份,yhhe_zhr@163.net<br>我研究了几天都没搞定。搞定分全给你
 
www.torry.net 上面能找到捕捉Console程序输出的例子<br>输出能捕捉,输入也一样的
 
沒想過耶
 
没有人发言了吗?请大家知无不言!
 
写了个小例子, 不是很完善, 没有注释, 大家先凑合着看, 有时间再改进...<br>&nbsp;1 需要增加错误处理, <br>&nbsp;2 有关管道的读写方式上还可以优化..<br>&nbsp;3 进程结束的判断方式不是很可靠<br><br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>const<br>&nbsp; WM_INPUT &nbsp;= WM_USER + 1;<br>&nbsp; WM_OUTPUT = WM_USER + 2;<br>&nbsp; <br>type<br>&nbsp; TExecThread = class(TThread)<br>&nbsp; private<br>&nbsp; &nbsp; FWnd &nbsp; &nbsp; : HWND;<br>&nbsp; &nbsp; FCmdLine : String;<br>&nbsp; &nbsp; FInRead &nbsp;: THandle;<br>&nbsp; &nbsp; FInWrite : THandle;<br>&nbsp; &nbsp; FOutRead : THandle;<br>&nbsp; &nbsp; FOutWrite: THandle;<br><br>&nbsp; protected<br>&nbsp; &nbsp; procedure Execute; override;<br>&nbsp; public<br>&nbsp; &nbsp; constructor Create(aWnd: HWND; const aCmdLine: String);<br>&nbsp; &nbsp; destructor Destroy; override;<br>&nbsp; end;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Memo1: TMemo;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Memo2: TMemo;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Memo2KeyPress(Sender: TObject; var Key: Char);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; FExec : TExecThread;<br>&nbsp; &nbsp; procedure WMOUTPUT(var Msg: TMessage); message WM_OUTPUT;<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>constructor TExecThread.Create(aWnd: HWND; const aCmdLine: String);<br>begin<br>&nbsp; inherited Create(False);<br>&nbsp; FreeOnTerminate := True;<br><br>&nbsp; CreatePipe(FInRead, FInWrite, nil, 0);<br>&nbsp; CreatePipe(FOutRead, FOutWrite, nil, 0);<br><br>&nbsp; FCmdLine := aCmdLine;<br>&nbsp; FWnd := aWnd;<br>end;<br><br>destructor TExecThread.Destroy;<br>begin<br>&nbsp; CloseHandle(FInWrite);<br>&nbsp; CloseHandle(FInRead);<br>&nbsp; CloseHandle(FOutWrite);<br>&nbsp; CloseHandle(FOutRead);<br><br>&nbsp; inherited Destroy;<br>end;<br><br>procedure TExecThread.Execute;<br>var<br>&nbsp; SI : TStartupInfo;<br>&nbsp; PI : TProcessInformation;<br>&nbsp; EC : Cardinal;<br>&nbsp; Msg: TMsg;<br>&nbsp; C &nbsp;: Char;<br>&nbsp; N &nbsp;: Cardinal;<br>&nbsp; T &nbsp;: Cardinal;<br>&nbsp; I &nbsp;: Cardinal;<br>&nbsp; Buf: array[0..1023] of Byte;<br><br>begin<br>&nbsp; FillChar(SI, SizeOf(TStartupInfo), 0);<br>&nbsp; SI.cb &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= SizeOf(TStartupInfo);<br>&nbsp; SI.dwFlags &nbsp; &nbsp; := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;<br>&nbsp; SI.hStdInput &nbsp; := FInRead;<br>&nbsp; SI.hStdOutput &nbsp;:= FOutWrite;<br>&nbsp; SI.hStdError &nbsp; := FOutWrite;<br>&nbsp; SI.wShowWindow := SW_Hide;<br><br>&nbsp; if CreateProcess(nil, PChar(FCmdLine), nil, nil, False, 0, nil, nil, SI, PI) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; repeat<br>&nbsp; &nbsp; &nbsp; Sleep(10);<br>&nbsp; &nbsp; &nbsp; PeekNamedPipe(FOutRead, @Buf, SizeOf(Buf), @N, @T, nil);<br>&nbsp; &nbsp; &nbsp; for I := 1 to T do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; ReadFile(FOutRead, C, SizeOf(C), N, nil);<br>&nbsp; &nbsp; &nbsp; &nbsp; if N &lt;&gt; 0 then PostMessage(FWnd, WM_OUTPUT, Ord(C), 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; TranslateMessage(Msg);<br>&nbsp; &nbsp; &nbsp; &nbsp; DispatchMessage(Msg);<br>&nbsp; &nbsp; &nbsp; &nbsp; if WM_INPUT = Msg.message then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; C := Chr(Msg.wParam);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WriteFile(FInWrite, C, SizeOf(C), N, nil);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; GetExitCodeProcess(PI.hProcess, EC);<br>&nbsp; &nbsp; until EC &lt;&gt; STILL_ACTIVE;<br><br>&nbsp; &nbsp; CloseHandle(PI.hProcess);<br>&nbsp; &nbsp; end;<br>end;<br><br>procedure TForm1.WMOUTPUT(var Msg: TMessage);<br>begin<br>&nbsp; Memo1.Text := Memo1.Text + Chr(Msg.WParam);<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; FExec := TExecThread.Create(Handle, 'C:/COMMAND.COM');<br>end;<br><br>procedure TForm1.Memo2KeyPress(Sender: TObject; var Key: Char);<br>begin<br>&nbsp; PostThreadMessage(FExec.ThreadID, WM_INPUT, Ord(Key), 0);<br>end;<br><br>end.
 
怎么什么都不执行啊?
 
期待高人指点
 
PeekNamedPipe(FOutRead, @Buf, SizeOf(Buf), @N, @T, nil) &nbsp;这句 N &amp; T 为 0 。<br>
 
罗西岛主 能说详细点吗?
 
不会吧, 我试验过, 应该没问题, 不过这个代码在NT/2000下要稍微修改一下<br>等我出差回来完善....
 
做了个小小的修改, 主要是解决了NT/2000下的问题, 有2000/NT的帮忙试一下...<br><br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls;<br><br>const<br>&nbsp; WM_INPUT &nbsp;= WM_USER + 1;<br>&nbsp; WM_OUTPUT = WM_USER + 2;<br>&nbsp; <br>type<br>&nbsp; TExecThread = class(TThread)<br>&nbsp; private<br>&nbsp; &nbsp; FWnd &nbsp; &nbsp; : HWND;<br>&nbsp; &nbsp; FCmdLine : String;<br><br>&nbsp; &nbsp; FInRead &nbsp;: THandle;<br>&nbsp; &nbsp; FInWrite : THandle;<br>&nbsp; &nbsp; FOutRead : THandle;<br>&nbsp; &nbsp; FOutWrite: THandle;<br><br>&nbsp; &nbsp; function isNT: Boolean;<br><br>&nbsp; protected<br>&nbsp; &nbsp; procedure Execute; override;<br>&nbsp; public<br>&nbsp; &nbsp; constructor Create(aWnd: HWND; const aCmdLine: String);<br>&nbsp; &nbsp; destructor Destroy; override;<br>&nbsp; end;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Memo1: TMemo;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Memo2: TMemo;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Memo2KeyPress(Sender: TObject; var Key: Char);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; FExec : TExecThread;<br>&nbsp; &nbsp; procedure WMOUTPUT(var Msg: TMessage); message WM_OUTPUT;<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br><br>constructor TExecThread.Create(aWnd: HWND; const aCmdLine: String);<br>var<br>&nbsp; SA &nbsp; &nbsp; &nbsp;: TSecurityAttributes;<br>&nbsp; SD &nbsp; &nbsp; &nbsp;: TSecurityDescriptor;<br>begin<br>&nbsp; inherited Create(False);<br>&nbsp; FreeOnTerminate := True;<br><br>&nbsp; FillChar(SA, SizeOf(TSecurityAttributes), 0);<br>&nbsp; SA.nLength := SizeOf(TSecurityAttributes);<br>&nbsp; SA.bInheritHandle := True;<br><br>&nbsp; if isNT then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION);<br>&nbsp; &nbsp; SetSecurityDescriptorDacl(@SD, True, nil, False);<br>&nbsp; &nbsp; SA.lpSecurityDescriptor := @SD;<br>&nbsp; &nbsp; end;<br><br>&nbsp; CreatePipe(FInRead, FInWrite, &nbsp;@SA, 0);<br>&nbsp; CreatePipe(FOutRead, FOutWrite, @SA, 0);<br><br>&nbsp; FCmdLine := aCmdLine;<br>&nbsp; FWnd := aWnd;<br>end;<br><br>destructor TExecThread.Destroy;<br>begin<br>&nbsp; CloseHandle(FInWrite);<br>&nbsp; CloseHandle(FInRead);<br>&nbsp; CloseHandle(FOutWrite);<br>&nbsp; CloseHandle(FOutRead);<br><br>&nbsp; inherited Destroy;<br>end;<br><br>function TExecThread.isNT: Boolean;<br>var<br>&nbsp; V : TOSVersionInfo;<br>begin<br>&nbsp; V.dwOSVersionInfoSize := SizeOf(V);<br>&nbsp; GetVersionEx(V);<br>&nbsp; Result := (V.dwPlatformId = VER_PLATFORM_WIN32_NT);<br>end;<br><br>procedure TExecThread.Execute;<br>var<br>&nbsp; SI : TStartupInfo;<br>&nbsp; PI : TProcessInformation;<br>&nbsp; EC : Cardinal;<br>&nbsp; Msg: TMsg;<br>&nbsp; C &nbsp;: Char;<br>&nbsp; N &nbsp;: Cardinal;<br>&nbsp; T &nbsp;: Cardinal;<br>&nbsp; I &nbsp;: Cardinal;<br>&nbsp; Buf: array[0..1023] of Byte;<br><br>begin<br>&nbsp; GetStartupInfo(SI);<br>&nbsp; SI.dwFlags &nbsp; &nbsp; := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;<br>&nbsp; SI.hStdInput &nbsp; := FInRead;<br>&nbsp; SI.hStdOutput &nbsp;:= FOutWrite;<br>&nbsp; SI.hStdError &nbsp; := FOutWrite;<br>&nbsp; SI.wShowWindow := SW_HIDE;<br><br>&nbsp; if CreateProcess(nil, PChar(FCmdLine), nil, nil, True, 0, nil, nil, SI, PI) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; repeat<br>&nbsp; &nbsp; &nbsp; Sleep(10);<br>&nbsp; &nbsp; &nbsp; PeekNamedPipe(FOutRead, @Buf, SizeOf(Buf), @N, @T, nil);<br>&nbsp; &nbsp; &nbsp; for I := 1 to T do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; ReadFile(FOutRead, C, SizeOf(C), N, nil);<br>&nbsp; &nbsp; &nbsp; &nbsp; if N &lt;&gt; 0 then PostMessage(FWnd, WM_OUTPUT, Ord(C), 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; TranslateMessage(Msg);<br>&nbsp; &nbsp; &nbsp; &nbsp; DispatchMessage(Msg);<br>&nbsp; &nbsp; &nbsp; &nbsp; if WM_INPUT = Msg.message then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; C := Chr(Msg.wParam);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WriteFile(FInWrite, C, SizeOf(C), N, nil);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; GetExitCodeProcess(PI.hProcess, EC);<br>&nbsp; &nbsp; until EC &lt;&gt; STILL_ACTIVE;<br><br>&nbsp; &nbsp; CloseHandle(PI.hThread);<br>&nbsp; &nbsp; CloseHandle(PI.hProcess);<br>&nbsp; &nbsp; end;<br>end;<br><br>procedure TForm1.WMOUTPUT(var Msg: TMessage);<br>begin<br>&nbsp; Memo1.Text := Memo1.Text + Chr(Msg.WParam);<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; FExec := TExecThread.Create(Handle, 'C:/COMMAND.COM');<br>end;<br><br>procedure TForm1.Memo2KeyPress(Sender: TObject; var Key: Char);<br>begin<br>&nbsp; PostThreadMessage(FExec.ThreadID, WM_INPUT, Ord(Key), 0);<br>end;<br><br>end.<br>
 
在2000下还是没什么反应
 
winexec你试过没有?
 
后退
顶部