首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

怎么在一个程序中调用另一个命令行程序,并重定向输入的有关问题。分太多,解决立即结贴

2012-01-16 
如何在一个程序中调用另一个命令行程序,并重定向输入的问题。分太多,解决立即结贴现有一个命令行程序contes

如何在一个程序中调用另一个命令行程序,并重定向输入的问题。分太多,解决立即结贴
现有一个命令行程序contest.exe,它读取标准输入,并将结果写入到一个文件中。
现在要实现在一个界面程序(wintest.exe)中调用contest.exe,并向它的标准输入发一些数据。
我根据MSDN文档,利用CreatePipe和CreateProcess来实现,但是结果老是不对,contest.exe没有接收到数据,非常郁闷。
请各位看看代码,帮忙改正!

下面是contest.exe的源代码,不能修改:
#include   "stdafx.h "
#include   <stdlib.h>
#include   <stdio.h>
#include   <string.h>

int   main(int   argc,   char*   argv[])
{
char   *command   =   NULL;
command=argv[1];

if(   !strcmp(   command,   "stdin "   ))
{
FILE   *input,*output;
input=stdin;
if   (input   !=   NULL)  
{
output=fopen(argv[2],   "wb ");

char   buf[1024];
int   readRet=0;
while   (!feof(input))
{
readRet   =   fread(buf,   sizeof(char),   1024,   input);
buf[readRet]= '\0 ';
fwrite(buf,sizeof(char),readRet,output);
printf( "%s ",buf);
}
fflush(output);
}
}

return   0;
}

以上代码编辑后,我在命令行下运行它,命令格式为:contest.exe   std   result.txt,可以得到正确结果:

下面是我写的另外一个程序中调用contest.exe的代码:
                int   ret;
SECURITY_ATTRIBUTES   sa1,sa2;
sa1.nLength   =   sizeof(SECURITY_ATTRIBUTES);
sa1.lpSecurityDescriptor   =   NULL;
sa1.bInheritHandle   =   TRUE;
sa2.nLength   =   sizeof(SECURITY_ATTRIBUTES);
sa2.lpSecurityDescriptor   =   NULL;
sa2.bInheritHandle   =   TRUE;

HANDLE   hReadPipe2,hWritePipe2,hReadPipe1,hWritePipe1;

CreatePipe(   &hReadPipe1,   &hWritePipe1,   &sa1,   0   );
CreatePipe(   &hReadPipe2,   &hWritePipe2,   &sa2,   0   );

STARTUPINFO   si;
::ZeroMemory(&si,sizeof(si));
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.hStdInput=hReadPipe2;
si.hStdOutput=si.hStdError=hWritePipe1;
si.cb=sizeof(si);
PROCESS_INFORMATION   processInfo;
char   cmdLine[]   =   "contest.exe   stdin   result.txt ";
ZeroMemory(   &processInfo   ,   sizeof(PROCESS_INFORMATION)   );
ret=CreateProcess(NULL,   cmdLine,   NULL,NULL,1,0,NULL,NULL,&si,&processInfo);
if(   !ret   )   return;


char   buff[]= "this   is   a   test   string. ";
DWORD   bytesRead=1024;

ret   =   WriteFile(   hWritePipe2,   buff,   bytesRead,   &bytesRead,   0   );
if(   !ret   )   return;
CloseHandle(   hWritePipe2   );

Sleep(1000);
TerminateProcess(   processInfo.hProcess,   0   );
CloseHandle(   hReadPipe1   );
CloseHandle(   hReadPipe2   );
CloseHandle(   hWritePipe1   );




[解决办法]
参考
http://community.csdn.net/Expert/topic/5225/5225434.xml?temp=.570904
[解决办法]
CreateProcess跟操作系统有点关系的,你是2000系统还是xp?
[解决办法]
// 只做了STDIN的重定向, STDOUT的类似, child process中是用MessageBox将收到的字符串显示出来的, 读是用fread()
//



#include "stdafx.h "
#include "windows.h "

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// child process path, 这里你要变一下.
TCHAR szChildPath[MAX_PATH] = TEXT( ".\\child\\debug\\child.exe ");

// message to be passed
const TCHAR msg[] = TEXT( "Hello! Child Console ");
DWORD dwSize = sizeof( msg );

// retrieve the stdin console handle
HANDLE hStdin = ::GetStdHandle( STD_INPUT_HANDLE );
if( hStdin == INVALID_HANDLE_VALUE )
{
::MessageBox(NULL, TEXT( "Can not retrieve stdin "), TEXT( "Error "), MB_OK);
return 0;
}

// create a anonymous pipe to redirect the stdin
SECURITY_ATTRIBUTES sa = {0, 0, TRUE};
HANDLE hReadPipe = NULL, hWritePipe = NULL;
if( !::CreatePipe(&hReadPipe, &hWritePipe, &sa, 0) )
{
::MessageBox(NULL, TEXT( "Can not create pip "), TEXT( "Error "), MB_OK);
::CloseHandle( hStdin );
return 0;
}

// redirect stdin
if( !::SetStdHandle(STD_INPUT_HANDLE, hReadPipe) )
{
::MessageBox(NULL, TEXT( "Can not redirect stdin "), TEXT( "Error "), MB_OK);
::CloseHandle( hReadPipe );
::CloseHandle( hWritePipe );
return 0;
}

// duplicate a non-inheritable handle used to push
// msg into the pipe
HANDLE hWritePipeNonInheritable;

if( ::DuplicateHandle(
GetCurrentProcess(), hWritePipe,
GetCurrentProcess(), &hWritePipeNonInheritable,
0, FALSE, DUPLICATE_SAME_ACCESS ) )
{
::CloseHandle( hWritePipe );
hWritePipe = NULL;
}
else
{
::MessageBox(NULL, TEXT( "Can not duplicate handle "), TEXT( "Error "), MB_OK);
::CloseHandle( hReadPipe );
::CloseHandle( hWritePipe );
::SetStdHandle(STD_INPUT_HANDLE, hStdin);
return 0;
}

// spawn child process
PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { sizeof(si) };
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hReadPipe;

if( !::CreateProcess(
NULL, szChildPath, NULL, NULL, TRUE,
0, NULL, NULL, &si, &pi) )
{
::MessageBox(NULL, TEXT( "Can not spawn child process "), TEXT( "Error "), MB_OK);
::CloseHandle( hReadPipe );
::CloseHandle( hWritePipeNonInheritable );
::SetStdHandle(STD_INPUT_HANDLE, hStdin);
return 0;
}

::CloseHandle( hReadPipe );
hReadPipe = NULL;

// restore stdin
if( !::SetStdHandle(STD_INPUT_HANDLE, hStdin) )
{
::MessageBox(NULL, TEXT( "Can not restore stdin "), TEXT( "Error "), MB_OK);
::CloseHandle( hWritePipeNonInheritable );
return 0;
}

// write to redirected stdin
DWORD dwBytesRead;
::WriteFile(hWritePipeNonInheritable, msg, dwSize, &dwBytesRead, NULL);
::CloseHandle( hWritePipeNonInheritable );

return 0;
}


热点排行