我想写一个控制台程序去对CVS的作一些简单的操控,在网上查了资源,说用ShellExecute这个功能还不够强大,因为CVS登录时要交互密码,
说要用CreateProcess结合CreatePipe,我在网上拷贝了代码修改如下:#include <stdio.h>
#include <windows.h>
#include "PROCESS.H"
#define BUFSIZE 4096 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hSaveStdin, hSaveStdout; TCHAR buffer[4096];
TCHAR curPath[512];
DWORD dwBuffer=sizeof(buffer);
DWORD main(int argc, char *argv[])
{
HANDLE hProcess=GetCurrentProcess();
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
HANDLE hStdinRd, hStdinWr, hStdinWrDup;
HANDLE hStdoutRd, hStdoutWr,hStdoutRdDup;
//** 创建读写管道
BOOL rc;
rc=CreatePipe(&hStdoutRd,&hStdoutWr,&sa,0);
if(!rc) return -1;
rc=CreatePipe(&hStdinRd,&hStdinWr,&sa,0);
if(!rc) return -1;
hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hSaveStdin = GetStdHandle(STD_INPUT_HANDLE); //** hStdout管道的读取端需保留在本进程,不能继承给子进程,需要复制出一个不可继承的句柄
rc=DuplicateHandle(hProcess, hStdoutRd, hProcess, &hStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
CloseHandle(hStdoutRd);
//** hStdin管道的写入端需保留在本进程,不能继承给子进程,需要复制出一个不可继承的句柄
rc=DuplicateHandle(hProcess, hStdinWr, hProcess, &hStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
CloseHandle(hStdinWr);
PROCESS_INFORMATION pi;
STARTUPINFO si;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
ZeroMemory( &si, sizeof(STARTUPINFO) );
si.cb = sizeof(STARTUPINFO);
si.dwFlags=STARTF_USESTDHANDLES;
si.hStdInput=hStdinRd;
si.hStdOutput=hStdoutWr;
si.hStdError=hStdoutWr;
GetCurrentDirectory(sizeof(curPath),curPath) ;
printf("curPath = %s\n",curPath); rc=CreateProcess("c:\\windows\\system32\\cmd.exe", NULL, NULL, 0, TRUE, 0, NULL, NULL, &si, &pi);
//**将所有命令存到一个字符串中,前后二个命令中间以\r\n分隔。
//我的修改代码,登录命令
TCHAR szCmds[4096]=TEXT("cvs -d :pserver:Joan@swan-rd:I:\\CVS\\project login\r\n"); //命令间以\r\n分隔
DWORD dwWrite=lstrlen(szCmds);
//** 从复制后的hstdinWrDup管道端写入dos命令
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
//执行以上命令如果用 ReadFile(hStdoutRdDup, buffer, 4096, &dwBuffer, NULL);,可以发现buffer内容是password: //以下输入我的用户登录密码abc,567
lstrcpy(szCmds,TEXT("abc,567\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
Sleep(50);
//执行以上操作后,可以确定CVS已经登录,因为我在CMD窗口进入TestCVS目录执行cvs update -P -r 1.2 abm.lib
//这条命令时成功
//下面代码,在我的程序里边执行 cvs update -P -r 1.2 abm.lib这条命令
//先定位到存有CVS文件夹的目录
lstrcpyn(szCmds,curPath,3);
lstrcat(szCmds,TEXT("\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
lstrcpy(szCmds,TEXT("cd "));
lstrcat(szCmds,curPath);
lstrcat(szCmds,TEXT("\r\n")); dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL); lstrcpy(szCmds,TEXT("cd TestCvs\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
//定位目录完毕后,我写入命令
lstrcpy(szCmds,TEXT("cvs update -P -r 1.2 abm.lib\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
Sleep(100);
//** 从复制后的hstdoutRdDup管道端读取输出结果
ReadFile(hStdoutRdDup, buffer, 4096, &dwBuffer, NULL);
SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
printf("buffer = %s\n",buffer);
CloseHandle(hStdinWrDup);
CloseHandle(hStdoutRdDup);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
} 以上代码中,只要我代码中执行了cvs -d :pserver:Joan@swan-rd:I:\\CVS\\project login这句后,
BUFFER中读了来的东西除了PASSWORD,就没有再输入了,
但没有执行cvs -d :pserver:Joan@swan-rd:I:\\CVS\\MTK login命令的话,这些代码 lstrcpyn(szCmds,curPath,3);
lstrcat(szCmds,TEXT("\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
lstrcpy(szCmds,TEXT("cd "));
lstrcat(szCmds,curPath);
lstrcat(szCmds,TEXT("\r\n")); dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL); lstrcpy(szCmds,TEXT("cd TestCvs\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL); 都可以写入管道,从
ReadFile(hStdoutRdDup, buffer, 4096, &dwBuffer, NULL);
SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
printf("buffer = %s\n",buffer);
可以看到结果,
现在我的程序要达到我的登录效果,同时下面的更新等操作的代码也要有用,请问要如何修改,
我怀疑执行了cvs -d :pserver:Joan@swan-rd:I:\\CVS\\project login这句命令后,
pipe就不起作用了,是不是被CVS服务程序共享了?要如何解决这个问题,小弟先先各位了
说要用CreateProcess结合CreatePipe,我在网上拷贝了代码修改如下:#include <stdio.h>
#include <windows.h>
#include "PROCESS.H"
#define BUFSIZE 4096 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hSaveStdin, hSaveStdout; TCHAR buffer[4096];
TCHAR curPath[512];
DWORD dwBuffer=sizeof(buffer);
DWORD main(int argc, char *argv[])
{
HANDLE hProcess=GetCurrentProcess();
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
HANDLE hStdinRd, hStdinWr, hStdinWrDup;
HANDLE hStdoutRd, hStdoutWr,hStdoutRdDup;
//** 创建读写管道
BOOL rc;
rc=CreatePipe(&hStdoutRd,&hStdoutWr,&sa,0);
if(!rc) return -1;
rc=CreatePipe(&hStdinRd,&hStdinWr,&sa,0);
if(!rc) return -1;
hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hSaveStdin = GetStdHandle(STD_INPUT_HANDLE); //** hStdout管道的读取端需保留在本进程,不能继承给子进程,需要复制出一个不可继承的句柄
rc=DuplicateHandle(hProcess, hStdoutRd, hProcess, &hStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
CloseHandle(hStdoutRd);
//** hStdin管道的写入端需保留在本进程,不能继承给子进程,需要复制出一个不可继承的句柄
rc=DuplicateHandle(hProcess, hStdinWr, hProcess, &hStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
CloseHandle(hStdinWr);
PROCESS_INFORMATION pi;
STARTUPINFO si;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
ZeroMemory( &si, sizeof(STARTUPINFO) );
si.cb = sizeof(STARTUPINFO);
si.dwFlags=STARTF_USESTDHANDLES;
si.hStdInput=hStdinRd;
si.hStdOutput=hStdoutWr;
si.hStdError=hStdoutWr;
GetCurrentDirectory(sizeof(curPath),curPath) ;
printf("curPath = %s\n",curPath); rc=CreateProcess("c:\\windows\\system32\\cmd.exe", NULL, NULL, 0, TRUE, 0, NULL, NULL, &si, &pi);
//**将所有命令存到一个字符串中,前后二个命令中间以\r\n分隔。
//我的修改代码,登录命令
TCHAR szCmds[4096]=TEXT("cvs -d :pserver:Joan@swan-rd:I:\\CVS\\project login\r\n"); //命令间以\r\n分隔
DWORD dwWrite=lstrlen(szCmds);
//** 从复制后的hstdinWrDup管道端写入dos命令
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
//执行以上命令如果用 ReadFile(hStdoutRdDup, buffer, 4096, &dwBuffer, NULL);,可以发现buffer内容是password: //以下输入我的用户登录密码abc,567
lstrcpy(szCmds,TEXT("abc,567\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
Sleep(50);
//执行以上操作后,可以确定CVS已经登录,因为我在CMD窗口进入TestCVS目录执行cvs update -P -r 1.2 abm.lib
//这条命令时成功
//下面代码,在我的程序里边执行 cvs update -P -r 1.2 abm.lib这条命令
//先定位到存有CVS文件夹的目录
lstrcpyn(szCmds,curPath,3);
lstrcat(szCmds,TEXT("\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
lstrcpy(szCmds,TEXT("cd "));
lstrcat(szCmds,curPath);
lstrcat(szCmds,TEXT("\r\n")); dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL); lstrcpy(szCmds,TEXT("cd TestCvs\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
//定位目录完毕后,我写入命令
lstrcpy(szCmds,TEXT("cvs update -P -r 1.2 abm.lib\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
Sleep(100);
//** 从复制后的hstdoutRdDup管道端读取输出结果
ReadFile(hStdoutRdDup, buffer, 4096, &dwBuffer, NULL);
SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
printf("buffer = %s\n",buffer);
CloseHandle(hStdinWrDup);
CloseHandle(hStdoutRdDup);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
} 以上代码中,只要我代码中执行了cvs -d :pserver:Joan@swan-rd:I:\\CVS\\project login这句后,
BUFFER中读了来的东西除了PASSWORD,就没有再输入了,
但没有执行cvs -d :pserver:Joan@swan-rd:I:\\CVS\\MTK login命令的话,这些代码 lstrcpyn(szCmds,curPath,3);
lstrcat(szCmds,TEXT("\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
lstrcpy(szCmds,TEXT("cd "));
lstrcat(szCmds,curPath);
lstrcat(szCmds,TEXT("\r\n")); dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL); lstrcpy(szCmds,TEXT("cd TestCvs\r\n"));
dwWrite=lstrlen(szCmds);
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL); 都可以写入管道,从
ReadFile(hStdoutRdDup, buffer, 4096, &dwBuffer, NULL);
SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
printf("buffer = %s\n",buffer);
可以看到结果,
现在我的程序要达到我的登录效果,同时下面的更新等操作的代码也要有用,请问要如何修改,
我怀疑执行了cvs -d :pserver:Joan@swan-rd:I:\\CVS\\project login这句命令后,
pipe就不起作用了,是不是被CVS服务程序共享了?要如何解决这个问题,小弟先先各位了
解决方案 »
- 关于文件发送的问题
- ADO中使用_ConnectionPtr修改数据出错
- 面对女同事的视觉骚扰,应该如何处理?
- 在线等,问一个聚合的问题,假如A聚合B,B聚合C,那么我在A里能访问C的接口函数吗?高手帮忙回答啊,顶着有分啊
- 讨论一下,怎样利用ARP欺骗的方法把别人的IP抢过来?
- Eclipse+CDT,怎么用?
- 高手帮忙!
- 求助关于MFC中树形控件的拖放
- 不知道WSAGetOverlappedResult的第三个参数lpcbTransfer能否每次都能获得客户端发过来字符串的长度?
- VC 2008 OpenGL太阳地球月亮模型运行后无效果
- 怎样用C或C++实现类似QQ聊天中联系人的树形模式?
- 如何用ComboBox和MonthCalendar配合设置日期
TCHAR szCmds[4096]=TEXT("cvs -d :pserver:Joan@swan-rd:I:\\CVS\\project login\r\n"); //命令间以\r\n分隔
DWORD dwWrite=lstrlen(szCmds);
//** 从复制后的hstdinWrDup管道端写入dos命令
WriteFile(hStdinWrDup, szCmds, dwWrite, &dwWrite, NULL);
后面加入sleep(50)也不行,//执行以上命令如果用 ReadFile(hStdoutRdDup, buffer, 4096, &dwBuffer, NULL);,可以发现buffer内容是password: 这样的话应该就返回了吧
你试一下把要输入的东西都编译到一个文本文件里,然后把输入重定向到这个文本文件,看看这样执行有没有问题。
#include "stdafx.h"
#include <stdio.h>#include "string.h"
#include <stdio.h>
#include <windows.h>
#define BUFSIZE 4096
HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hSaveStdin, hSaveStdout;
BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPTSTR);
VOID ErrMsg(LPTSTR, BOOL);
DWORD main(int argc, char *argv[])
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// The steps for redirecting child process's STDOUT:
// 1. Save current STDOUT, to be restored later.
// 2. Create anonymous pipe to be STDOUT for child process.
// 3. Set STDOUT of the parent process to be write handle to
// the pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the read handle and
// close the inheritable read handle.
// Save the handle to the current STDOUT.
hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// Create a pipe for the child process's STDOUT.
if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
ErrorExit("Stdout pipe creation failed\n");
// Set a write handle to the pipe to be STDOUT.
if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
ErrorExit("Redirecting STDOUT failed");
// Create noninheritable read handle and close the inheritable read
// handle. fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if( !fSuccess )
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdoutRd); // The steps for redirecting child process's STDIN:
// 1. Save current STDIN, to be restored later.
// 2. Create anonymous pipe to be STDIN for child process.
// 3. Set STDIN of the parent to be the read handle to the
// pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the write handle,
// and close the inheritable write handle.
// Save the handle to the current STDIN.
hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
// Create a pipe for the child process's STDIN.
if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
ErrorExit("Stdin pipe creation failed\n");
// Set a read handle to the pipe to be STDIN.
if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
ErrorExit("Redirecting Stdin failed");
// Duplicate the write handle to the pipe so it is not inherited.
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0,
FALSE, // not inherited
DUPLICATE_SAME_ACCESS);
if (! fSuccess)
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdinWr);
// Now create the child process.
if (! CreateChildProcess())
ErrorExit("Create process failed");
// After process creation, restore the saved STDIN and STDOUT.
if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
ErrorExit("Re-redirecting Stdin failed\n");
if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
ErrorExit("Re-redirecting Stdout failed\n");
// Get a handle to the parent's input file.
if (argc > 1)
hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
else
hInputFile = hSaveStdin;
if (hInputFile == INVALID_HANDLE_VALUE)
ErrorExit("no input file\n");
// Write to pipe that is the standard input for a child process.
WriteToPipe();
// Read from pipe that is the standard output for child process.
ReadFromPipe();
return 0;
}
BOOL CreateChildProcess()
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
// Create the child process.
return CreateProcess(NULL,
"c:\\windows\\system32\\cmd.exe", // command line //修改成CMD程序的路径
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
}
VOID WriteToPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
// Read from a file and write its contents to a pipe.
for (;;)
{
if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0) break;
if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
&dwWritten, NULL)) break;
}
// Close the pipe handle so the child process stops reading.
if (! CloseHandle(hChildStdinWrDup))
ErrorExit("Close pipe failed\n");
}
VOID ReadFromPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // Close the write end of the pipe before reading from the
// read end of the pipe.
if (!CloseHandle(hChildStdoutWr))
ErrorExit("Closing handle failed");
// Read output from the child process, and write to parent's STDOUT.
for (;;)
{
if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
NULL) || dwRead == 0) break;
if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
break;
}
}
VOID ErrorExit (LPTSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}
生成可执行文件后,我在DOS窗口执行 test.exe CVS_CMD.TXT
我的CVS_cmd.txt内容如下:
cvs -d :pserver:Joan@swan-rd:I:\CVS\project login
abc,567
cvs update -P -r 1.2 abm.lib
结果DOS窗口还是停在PASSWORD:里边,输入密码的******提示没有DOS窗口上显示,
CVS没有登录上
也谢谢scq2099yt 友情顶
#include "stdafx.h"
#include <stdio.h>#include "string.h"
#include <stdio.h>
#include <windows.h>
#define BUFSIZE 4096
HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hSaveStdin, hSaveStdout;
BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPTSTR);
VOID ErrMsg(LPTSTR, BOOL);
DWORD main(int argc, char *argv[])
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// The steps for redirecting child process's STDOUT:
// 1. Save current STDOUT, to be restored later.
// 2. Create anonymous pipe to be STDOUT for child process.
// 3. Set STDOUT of the parent process to be write handle to
// the pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the read handle and
// close the inheritable read handle.
// Save the handle to the current STDOUT.
hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// Create a pipe for the child process's STDOUT.
if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
ErrorExit("Stdout pipe creation failed\n");
// Set a write handle to the pipe to be STDOUT.
if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
ErrorExit("Redirecting STDOUT failed");
// Create noninheritable read handle and close the inheritable read
// handle. fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , 0,
FALSE,
DUPLICATE_SAME_ACCESS);
if( !fSuccess )
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdoutRd); // The steps for redirecting child process's STDIN:
// 1. Save current STDIN, to be restored later.
// 2. Create anonymous pipe to be STDIN for child process.
// 3. Set STDIN of the parent to be the read handle to the
// pipe, so it is inherited by the child process.
// 4. Create a noninheritable duplicate of the write handle,
// and close the inheritable write handle.
// Save the handle to the current STDIN.
hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
// Create a pipe for the child process's STDIN.
if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
ErrorExit("Stdin pipe creation failed\n");
// Set a read handle to the pipe to be STDIN.
if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
ErrorExit("Redirecting Stdin failed");
// Duplicate the write handle to the pipe so it is not inherited.
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0,
FALSE, // not inherited
DUPLICATE_SAME_ACCESS);
if (! fSuccess)
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdinWr);
// Now create the child process.
if (! CreateChildProcess())
ErrorExit("Create process failed");
// After process creation, restore the saved STDIN and STDOUT.
if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
ErrorExit("Re-redirecting Stdin failed\n");
if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
ErrorExit("Re-redirecting Stdout failed\n");
// Get a handle to the parent's input file.
if (argc > 1)
hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
else
hInputFile = hSaveStdin;
if (hInputFile == INVALID_HANDLE_VALUE)
ErrorExit("no input file\n");
// Write to pipe that is the standard input for a child process.
WriteToPipe();
// Read from pipe that is the standard output for child process.
ReadFromPipe();
return 0;
}
BOOL CreateChildProcess()
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
// Create the child process.
return CreateProcess(NULL,
"c:\\windows\\system32\\cmd.exe", // command line //修改成CMD程序的路径
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
}
VOID WriteToPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
// Read from a file and write its contents to a pipe.
for (;;)
{
if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
dwRead == 0) break;
if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
&dwWritten, NULL)) break;
}
// Close the pipe handle so the child process stops reading.
if (! CloseHandle(hChildStdinWrDup))
ErrorExit("Close pipe failed\n");
}
VOID ReadFromPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // Close the write end of the pipe before reading from the
// read end of the pipe.
if (!CloseHandle(hChildStdoutWr))
ErrorExit("Closing handle failed");
// Read output from the child process, and write to parent's STDOUT.
for (;;)
{
if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
NULL) || dwRead == 0) break;
if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
break;
}
}
VOID ErrorExit (LPTSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}
生成可执行文件后,我在DOS窗口执行 test.exe CVS_CMD.TXT
我的CVS_cmd.txt内容如下:
cvs -d :pserver:Joan@swan-rd:I:\CVS\project login
abc,567
cvs update -P -r 1.2 abm.lib
结果DOS窗口还是停在PASSWORD:里边,输入密码的******提示没有DOS窗口上显示,
CVS没有登录上
也谢谢scq2099yt 友情顶
Logging in to :pserver:Joan@swan-rd:I:\CVS\project login
CVS password:另此时去打开CVS_CMD.TXT的文件提示有另外的进程在使用