关于DELPHI调用外部可执行程序的问题(Creatprocess)....急...再200分求答案 ( 积分: 200 )

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

yonge23

Unregistered / Unconfirmed
GUEST, unregistred user!
我有个&quot;001.C&quot;的文件:<br>#include &lt;stdio.h&gt;<br>#include &lt;math.h&gt;<br>const g=10;<br>main()<br>{<br>int a,b,c;<br>printf(&quot; &nbsp; A= &quot;);<br>scanf(&quot;%d&quot;,&amp;a);<br>printf(&quot; &nbsp; B= &quot;);<br>scanf(&quot;%d&quot;,&amp;b);<br>c=a+b;<br>printf(&quot; A+B = %d/n&quot;,c);<br>}<br><br>我现在想用DELPHI来测试该程序代码是否正确..<br><br>首先我先利用TURBOC的TCC.EXE对&quot;001.C&quot;进行编译.使之生成&quot;001.EXE&quot;可执行文件.我用如下方法:<br>ShellExecute(Handle, 'open', PChar('command.com'), PChar('/c C:/turboc2/tcc -e001 001.c &nbsp;&gt;p.txt'), nil, SW_SHOW);<br>这步可以成功解决了,也可以正确地生成可执行程序&quot;001.EXE&quot;.<br><br>接下来,我要调用&quot;001.EXE&quot;进行测试了.<br>我把测试数据:1 &nbsp;2 &nbsp;放在input.txt 文件中.想把测试结果的数据放在output.txt文件中.<br>我用如下方法:<br>ShellExecute(Handle, 'open', PChar('command.com'), PChar('/c 001 &nbsp;&lt;input.txt &gt;output.txt'), nil, SW_SHOW);<br>这样,测试数据就不用通过手动从键盘上输入.只要读取input.txt 文件中的测试数据就可以了.<br>但是用ShellExecute函数时,当001.EXE程序的代码如下时:<br>#include &lt;stdio.h&gt;<br>#include &lt;math.h&gt;<br>const g=10;<br>main()<br>{<br>int a,b,c;<br>printf(&quot; &nbsp; A= &quot;);<br>scanf(&quot;%d&quot;,&amp;a);<br>printf(&quot; &nbsp; B= &quot;);<br>scanf(&quot;%d&quot;,&amp;b);<br>while (g==10) ;<br>c=a+b;<br>printf(&quot; A+B = %d/n&quot;,c);<br>}<br>由于while (g==10) ;,发生逻辑错误,进入死循环.得用DELPHI程序在一段时间(如2秒)自动结果001.EXE程序.这时用ShellExecute函数就不大方便了.<br>所以我想用Creatprocess函数来代替<br>ShellExecute(Handle, 'open', PChar('command.com'), PChar('/c 001 &nbsp;&lt;input.txt &gt;output.txt'), nil, SW_SHOW);<br>实现同样的功能,并且能够结果001.EXE的死循环问题.<br><br>有哪位大哥有空能不能帮我实现这个功能,,,感谢万份.<br><br>不知道我能否把问题描述清楚...如果有不清楚的再说...
 
我有个&quot;001.C&quot;的文件:<br>#include &lt;stdio.h&gt;<br>#include &lt;math.h&gt;<br>const g=10;<br>main()<br>{<br>int a,b,c;<br>printf(&quot; &nbsp; A= &quot;);<br>scanf(&quot;%d&quot;,&amp;a);<br>printf(&quot; &nbsp; B= &quot;);<br>scanf(&quot;%d&quot;,&amp;b);<br>c=a+b;<br>printf(&quot; A+B = %d/n&quot;,c);<br>}<br><br>我现在想用DELPHI来测试该程序代码是否正确..<br><br>首先我先利用TURBOC的TCC.EXE对&quot;001.C&quot;进行编译.使之生成&quot;001.EXE&quot;可执行文件.我用如下方法:<br>ShellExecute(Handle, 'open', PChar('command.com'), PChar('/c C:/turboc2/tcc -e001 001.c &nbsp;&gt;p.txt'), nil, SW_SHOW);<br>这步可以成功解决了,也可以正确地生成可执行程序&quot;001.EXE&quot;.<br><br>接下来,我要调用&quot;001.EXE&quot;进行测试了.<br>我把测试数据:1 &nbsp;2 &nbsp;放在input.txt 文件中.想把测试结果的数据放在output.txt文件中.<br>我用如下方法:<br>ShellExecute(Handle, 'open', PChar('command.com'), PChar('/c 001 &nbsp;&lt;input.txt &gt;output.txt'), nil, SW_SHOW);<br>这样,测试数据就不用通过手动从键盘上输入.只要读取input.txt 文件中的测试数据就可以了.<br>但是用ShellExecute函数时,当001.EXE程序的代码如下时:<br>#include &lt;stdio.h&gt;<br>#include &lt;math.h&gt;<br>const g=10;<br>main()<br>{<br>int a,b,c;<br>printf(&quot; &nbsp; A= &quot;);<br>scanf(&quot;%d&quot;,&amp;a);<br>printf(&quot; &nbsp; B= &quot;);<br>scanf(&quot;%d&quot;,&amp;b);<br>while (g==10) ;<br>c=a+b;<br>printf(&quot; A+B = %d/n&quot;,c);<br>}<br>由于while (g==10) ;,发生逻辑错误,进入死循环.得用DELPHI程序在一段时间(如2秒)自动结果001.EXE程序.这时用ShellExecute函数就不大方便了.<br>所以我想用Creatprocess函数来代替<br>ShellExecute(Handle, 'open', PChar('command.com'), PChar('/c 001 &nbsp;&lt;input.txt &gt;output.txt'), nil, SW_SHOW);<br>实现同样的功能,并且能够结果001.EXE的死循环问题.<br><br>有哪位大哥有空能不能帮我实现这个功能,,,感谢万份.<br><br>不知道我能否把问题描述清楚...如果有不清楚的再说...
 
有人帮忙吗!?<br><br>没人有空!?
 
参考<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=618422
 
看你的原贴,我刚刚更改了你的程序,对超时是能够处理,而且也不会出错了<br><br>输入输出给你了一个参考页面,我还没试,试完先...
 
// 测试C语言可执行程序.<br>procedure TForm1.Button2Click(Sender: TObject);<br>var i:integer;<br> &nbsp; &nbsp;sinfo:TSTARTUPINFO;<br> &nbsp; &nbsp;pinfo:TProcessInformation;<br> &nbsp; &nbsp;ct,et,kt,ut:Tfiletime;<br> &nbsp; &nbsp;hinputfile,houtputfile:THandle;<br> &nbsp; &nbsp;security:TSecurityAttributes;<br>begin<br> &nbsp;try<br> &nbsp;deletefile('output.txt');<br> &nbsp;hInputfile := FileOpen('input.txt', fmOpenRead);<br> &nbsp;hOutputFile:= FileCreate('output.txt');<br> &nbsp;FillChar(sInfo,sizeof(sInfo),#0);<br> &nbsp;sInfo.cb := SizeOf(sInfo);<br> &nbsp;sinfo.dwFlags:=STARTF_USESTDHANDLES;<br> &nbsp;SINFO.wShowWindow := SW_SHOW;<br> &nbsp;sinfo.hStdInput:=hInputFile;<br> &nbsp;sinfo.hStdOutput:=houtputFile;<br> &nbsp;sinfo.hStdError:=houtputfile;<br> &nbsp;if not CreateProcess(pchar('xxx.exe'),nil,nil,nil,false,NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo) then<br> // IF NOT CreateProcess(nil, PChar('XXX.EXE'), nil, nil, True, 0, nil, &nbsp;NIL, SINFO, PINFO) &nbsp; &nbsp;THEN<br> &nbsp; &nbsp;MessageBox(Application.handle,'指定程序启动失败!','错误',MB_OK or MB_ICONSTOP)<br> &nbsp;else<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;WaitForSingleObject(pInfo.hProcess,INFINITE);<br> &nbsp; &nbsp; &nbsp;CloseHandle( pinfo.hThread );<br> &nbsp; &nbsp; &nbsp;CloseHandle( pinfo.hProcess );<br> &nbsp; &nbsp; &nbsp;TerminateProcess(pinfo.hProcess,1);<br> &nbsp; &nbsp; &nbsp;showmessage('进程创建成功');<br> &nbsp; &nbsp; &nbsp;FileClose(hInputfile);<br> &nbsp; &nbsp; &nbsp;FileClose(hOutputfile);<br> &nbsp; &nbsp;end;<br> &nbsp;except<br> &nbsp; &nbsp;showmessage('测试失败');<br> &nbsp;end;<br>end;<br><br><br>我这样做.INPUT.TXT中是有测试数据的.测试也可以顺利进行.<br>但是测试结果却没有输出到OUTPUT.TXT中.这是为什么,帮忙看一下哪错了.!?
 
我的代码是在98上写的,如果在2000或者XP上要修改一下,是因为安全性的问题<br>代码里增加下面的内容<br> &nbsp; &nbsp;security.nLength := sizeof(security);<br> &nbsp; &nbsp;security.bInheritHandle := true;<br> &nbsp; &nbsp;security.lpSecurityDescriptor := nil;<br>CreateProcess那段代码改为<br> if not CreateProcess(pchar('xxx.exe'),nil,@security,,@security,false,NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo) then<br>....
 
还是不行...狂晕....<br><br>加了.还是无法把测试结果输出到OUTPUT.TXT文件中...
 
是因为创建文件的SecurityAttributes的问题,你可以用CreateFile来创建文件<br>如果还有问题给我发邮件tseug@263.net, 你也可以参考<br>http://www.codecomments.com/archive279-2004-7-232528.html
 
procedure TForm1.Button1Click(Sender: TObject);<br>var<br> &nbsp;SI: TStartupInfo;<br> &nbsp;PI: TProcessInformation;<br> &nbsp;SA: TSecurityAttributes;<br><br> &nbsp;hInputFile,hOutputfile:THandle;<br>begin<br> &nbsp;sa.nLength := SizeOf(SA);<br> &nbsp;sa.bInheritHandle := True;<br> &nbsp;sa.lpSecurityDescriptor := nil;<br><br> &nbsp;hInputFile :=CreateFile('Input.txt', GENERIC_READ,FILE_SHARE_READ,@SA,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);<br> &nbsp;houtputFile:=CreateFile('Output.txt',GENERIC_WRITE,FILE_SHARE_WRITE,@SA,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);<br><br> &nbsp;ZeroMemory(@SI, SizeOf(SI));<br> &nbsp;SI.cb := SizeOf(SI);<br> &nbsp;SI.dwFlags:=STARTF_USESTDHANDLES;<br> &nbsp;SI.wShowWindow := SW_SHOW;<br> &nbsp;SI.hStdInput &nbsp; &nbsp;:=hInputFile;<br> &nbsp;SI.hStdOutput &nbsp; :=houtputFile;<br> &nbsp;SI.hStdError &nbsp; &nbsp;:=houtputfile;<br><br> &nbsp;if not CreateProcess(nil, 'Project2.EXE', &nbsp;@SA, @SA, True,<br> &nbsp; &nbsp;NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then<br> &nbsp; &nbsp;MessageBox(Application.handle,'&amp;Ouml;&amp;cedil;&amp;para;¨&amp;sup3;&amp;Igrave;&amp;ETH;ò&amp;AElig;&amp;ocirc;&amp;para;&amp;macr;&amp;Ecirc;§°&amp;Uuml;!','&amp;acute;í&amp;Icirc;ó',MB_OK or MB_ICONSTOP)<br> &nbsp;else<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp;if WaitForSingleObject(PI.hProcess, 5000) = WAIT_TIMEOUT then<br> &nbsp; &nbsp; &nbsp; &nbsp; TerminateProcess(PI.hProcess, 1);<br><br> &nbsp; &nbsp;CloseHandle(PI.hThread );<br> &nbsp; &nbsp;CloseHandle(PI.hProcess );<br> &nbsp; &nbsp;FileClose(hInputfile);<br> &nbsp; &nbsp;FileClose(hOutputfile);<br> &nbsp; &nbsp;end;<br>end;
 
还是不行.老问题.INPUT.TXT中是有测试数据的.测试也可以顺利进行.<br>但是测试结果却没有输出到OUTPUT.TXT中.<br>会不会是.&quot;001.C&quot;的文件:<br>#include &lt;stdio.h&gt;<br>#include &lt;math.h&gt;<br>const g=10;<br>main()<br>{<br>int a,b,c;<br>printf(&quot; &nbsp; A= &quot;);<br>scanf(&quot;%d&quot;,&amp;a);<br>printf(&quot; &nbsp; B= &quot;);<br>scanf(&quot;%d&quot;,&amp;b);<br>c=a+b;<br>printf(&quot; A+B = %d/n&quot;,c);<br>}<br>用scanf(&quot;%d&quot;,&amp;a);<br>scanf(&quot;%d&quot;,&amp;b);<br>读取数据..而这个数据是从INPUT.TXT中取得的.这过程会不会出现什么问题啊!?
 
把你的001.C的exe文件和input.txt发给我,我试试
 
input.txt<br>-----------<br>1<br>2<br>===========<br>pipeTest.c<br>-----------<br>main()<br>{<br> int a,b;<br> printf(&quot;/n &nbsp;a =&quot;);<br> scanf(&quot;%d&quot;,&amp;a);<br> if(a==1){<br> &nbsp; sound(1000);<br> &nbsp; delay(10 *10 *1000);<br> }<br> printf(&quot;/n &nbsp;b =&quot;);<br> scanf(&quot;%d&quot;,&amp;b);<br> printf(&quot;/n &nbsp;a+b=%d&quot;,a+b);<br> nosound();<br> while(1){<br> &nbsp; printf(&quot;/n%x&quot;,b++);<br> }<br>}<br>===========<br>没有听到Sound声音,那么Input.txt还是不起作用,看来 重定向输入 也没有对<br>===========<br>继续学习这个帖子http://www.codecomments.com/archive279-2004-7-232528.html
 
真是怪了,我用Delphi写的命令行程序就没问题,这个C程序就不对,看样子要研究一下了
 
谢谢tseug大哥...
 
还有人没,怎么没人回答了!?
 
问题已经解决,原因在这里:<br>我的机器是WinXp Pro,故运行dos程序有时会Crash,即Ntvdm的事<br>解决办法也很简单:<br><br>//关键就在这里,不用向16位兼容的Ntvdm虚拟机,而用32位的cmd.exe<br> &nbsp;if not CreateProcess(nil, 'cmd.exe /c xxx.EXE', nil, nil, True,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CREATE_NEW_CONSOLE, nil,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PChar(ExtractFilePath(Application.ExeName)),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SI, PI) then<br><br>下面是我找到的原因(http://kb.indiana.edu/data/alin.html?cust=609814.52646.30)<br>-------------------------------------------------------------------------------<br>Windows NT 4.0, 2000, XP, and 2003 recognize scripts that end with .cmd as well as .bat extensions. However, the .cmd extension is the better choice for an all-Windows NT/2000/XP/2003 environment. In these operating systems, the .cmd extension is associated with the cmd.exe program, which uses a native 32-bit command environment.<br><br>Scripts with .bat extensions will run on all Windows operating systems. Because .bat scripts are associated with the 16-bit program command.exe, they will not run as fast as those with .cmd extensions. Also, they are more prone to errors, because they run in the NT Virtual DOS Machine (NTVDM) instead of the native 32-bit cmd.exe program.<br>------------------------------------------------------------------------------<br>下面是更改后可以正确运行的语句:<br>procedure TForm1.btnMEClick(Sender: TObject);<br>var<br> &nbsp;SI: TStartupInfo;<br> &nbsp;PI: TProcessInformation;<br> &nbsp;SA: TSecurityAttributes;<br> &nbsp;hInputFile,hOutputfile:THandle;<br> &nbsp;tmpStr :string;<br>begin<br> &nbsp;sa.nLength := SizeOf(SA);<br> &nbsp;sa.bInheritHandle := True;<br> &nbsp;sa.lpSecurityDescriptor := nil;<br><br> &nbsp;hInputFile :=CreateFile('Input.txt', GENERIC_READ,FILE_SHARE_READ,@SA,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);<br> &nbsp;houtputFile:=CreateFile('Output.txt',GENERIC_WRITE,FILE_SHARE_WRITE,@SA,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);<br><br> &nbsp;ZeroMemory(@SI, SizeOf(SI));<br> &nbsp;SI.cb := SizeOf(SI);<br> &nbsp;SI.dwFlags:=STARTF_USESTDHANDLES;<br> &nbsp;SI.wShowWindow := SW_SHOW;<br> &nbsp;SI.hStdInput &nbsp; &nbsp;:=hInputFile;<br> &nbsp;SI.hStdOutput &nbsp; :=houtputFile;<br> &nbsp;SI.hStdError &nbsp; &nbsp;:=houtputfile;<br> &nbsp;//关键就在这里,不用向16位兼容的Ntvdm虚拟机,而用32位的cmd.exe &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp;if not CreateProcess(nil, 'cmd.exe /c xxx.EXE', nil, nil, True,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CREATE_NEW_CONSOLE, nil,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PChar(ExtractFilePath(Application.ExeName)),<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SI, PI) then<br> &nbsp; &nbsp;MessageBox(Application.handle,'error load ','error',MB_OK or MB_ICONSTOP)<br> &nbsp;else<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp;if WaitForSingleObject(PI.hProcess, 5000) = WAIT_TIMEOUT then<br> &nbsp; &nbsp; &nbsp; &nbsp; TerminateProcess(PI.hProcess, 1);<br><br> &nbsp; &nbsp;CloseHandle(PI.hThread );<br> &nbsp; &nbsp;CloseHandle(PI.hProcess );<br> &nbsp; &nbsp;FileClose(hInputfile);<br> &nbsp; &nbsp;FlushFileBuffers(hOutputfile);<br> &nbsp; &nbsp;FileClose(hOutputfile);<br> &nbsp; &nbsp;end;<br>end;
 
呵呵,为这个问题我也是郁闷了一天,把那个CreateProcess搬过来搬过去的研究,还有http://www.codecomments.com/archive279-2004-7-232528.html这个帖子的程序,读了一遍又一遍,直到想起兼容的事,查了资料后,竟会轻松解决。<br><br>呵呵,在这之前,从http://support.microsoft.com/kb/q196453/帮助里面,我的Path都被我该过来改过去,config.nt、autoexec.nt、还有用sysedit等,系统文件也差点儿改的不成样子,郁闷了一天[:(],也看不到还有其他高手来回答,最后还是从http://kb.indiana.edu/data/alin.html?cust=609814.52646.30这里了解到了ntvdm和cmd.exe的不同,问题终于解决了,也长进了一点儿[:)]
 
并且可以看到这么运行程序,点击那个按钮后,系统进程中并没有自动运行ntvdm.exe和wowexec.exe(原先的程序都会这样自动调用虚拟机,即ntvdm和wowexe.exe),而且程序也正常工作了,能够从文件接收输入,并输出到指定文件。<br><br>算是有了这么一点儿经验:<br>虚拟机和cmd.exe还是很不同啊
 
dawnsong大虾精神可嘉,学习,收藏..
 
后退
顶部