C语言,如何向“被调用的外部EXE文件”传送数据
各位大侠,现遇到一个有关C的问题,在程序中要调用一个外部的test.EXE文件,该文件被启动后,要求向其输入字母U,然后回车;再输入X,然后回车;同时,检测输入字母是否为...
各位大侠,现遇到一个有关C的问题,在程序中要调用一个外部的test.EXE文件,该文件被启动后,要求向其输入字母U,然后回车;再输入X,然后回车;同时,检测输入字母是否为R,当为R时,关闭该test.EXE文件。自己写的程序如下:
#include <stdio.h>
#include <string.h>
#include <windows.h>
char Mp[40]={"test.exe"};
char path[50];
int main(void)
{
GetCurrentDirectory(200,path); //得到当前路径
SetCurrentDirectory(path); //进入程序所在的路径
printf("%s\n",path);
system(Mp);
putchar('U');
putchar('\n');
return 0;
}
结果是没有把字母U 和回车键输入到test.exe运行时显示的窗口中去。
我试过Sendmessage()函数,但是没有成功,可能是我没有用好Sendmessage(),
求哪位大侠帮忙解决这个问题。可以加分。
主要的目的,就是模拟键盘输入。因为我调用test.exe文件,需要人工键盘输入,现在改为自动输入。我第一次接触此类问题,如果可以,请帮调出具体程序。加了一次分,可以再加。谢谢! 展开
#include <stdio.h>
#include <string.h>
#include <windows.h>
char Mp[40]={"test.exe"};
char path[50];
int main(void)
{
GetCurrentDirectory(200,path); //得到当前路径
SetCurrentDirectory(path); //进入程序所在的路径
printf("%s\n",path);
system(Mp);
putchar('U');
putchar('\n');
return 0;
}
结果是没有把字母U 和回车键输入到test.exe运行时显示的窗口中去。
我试过Sendmessage()函数,但是没有成功,可能是我没有用好Sendmessage(),
求哪位大侠帮忙解决这个问题。可以加分。
主要的目的,就是模拟键盘输入。因为我调用test.exe文件,需要人工键盘输入,现在改为自动输入。我第一次接触此类问题,如果可以,请帮调出具体程序。加了一次分,可以再加。谢谢! 展开
展开全部
不知道你介不介意用(匿名)管道的方式来实现,通过它的转向功能,可以很容易得到调用程序的输出,并可进行交互。msdn中CreatePipe 函数提供了这方面的例子。还有一个例子,当年写bcb插件ddkbuild编译驱动程序时写的:
void __fastcall BuildAndMessage(AnsiString PathToBuild/*=NULL*/, AnsiString Set/*=NULL*/)
{
AnsiString CommandStr = MakeCommandStr(PathToBuild, Set);
//ShowMessage(CommandStr);
// 读管道
HANDLE hChildStdinWr/*父进程写*/, hChildStdinRd/*子进程读*/;
// 写管道
HANDLE hChildStdoutWr/*子进程写*/, hChildStdoutRd/*父进程读*/;
SECURITY_ATTRIBUTES sa;
_di_IOTAMessageServices MessageServices;
_di_IOTAMessageGroup MessageGroup;
if (BorlandIDEServices->Supports(MessageServices))
{
MessageServices->ClearToolMessages(NULL);
MessageGroup = MessageServices->AddMessageGroup("Ddkbuild");
MessageServices->ShowMessageView(MessageGroup);
}
else
{
ShowMessage("Create ddkbuild messageview failed");
return;
}
sa.bInheritHandle = true;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
// 创建子进程写管道
if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &sa, 0))
{
ShowMessage("Create Stdout pipe failed");
return;
}
SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0); // 该句柄子进程没用到,故取消继承性
// 创建子进程读管道
if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &sa,0))
{
ShowMessage("Create StdinRd pipe failed");
return;
}
SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0); // 该句柄子进程没用到,故取消继承性
//SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr);
//SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd);
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdInput = hChildStdinRd; // 重定向子进程输入
si.hStdOutput = hChildStdoutWr; // 重定向子进程输出
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
// 注意使用了true,这样创建子进程时,父进程的所有可继承的句柄就可以被继承下来了
// 我们也可以使用SetHandleInformation使句柄不可被继承,这样子进程就无法使用了
// 这样的例子可以看《Creating a Child Process with Redirected Input and Output.doc》
if (!CreateProcess(NULL, CommandStr.c_str(), NULL, NULL, true, 0, NULL, NULL, &si, &pi))
{
ShowMessage("Create process failed");
return;
}
// 将数据写入子进程,这里只是演示,本程序不需要写入
const char *strIn = " ";
DWORD dwBytes = 0;
WriteFile(hChildStdinWr, strIn, strlen(strIn), &dwBytes, NULL);
CloseHandle(hChildStdinWr); // 保证对端的ReadFile可返回
// 调用ReadFile前须关闭,否则因写管道写入端有未关闭的Write句柄,ReadFile最后无法返回0
CloseHandle(hChildStdoutWr);
// 从子进程中读出执行结果,不处理mbcs,需要的朋友请加上前导字符的判断
char strData[MAX_PATH * 2];
AnsiString MessageComplete, MessageCut;
char* pos;
char lf = '\n';
void* Unused = 0;
while (ReadFile(hChildStdoutRd, strData, sizeof(strData), &dwBytes, NULL))
{
strData[dwBytes] = 0;
if (pos = strrchr(strData, lf)) // 如果有换行,则显示
{
*(pos-1) = 0;
pos++;
MessageComplete = MessageCut + strData;
MessageCut = pos;
MessageServices->AddToolMessage(
"", MessageComplete, "Ddkbuild", 0, 0, NULL, Unused, MessageGroup);
}
else // 否则暂存
MessageCut = MessageCut + strData;
Application->ProcessMessages();
}
MessageServices->AddToolMessage(
"", MessageCut, "Ddkbuild", 0, 0, NULL, Unused, MessageGroup);
// 关闭句柄
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(hChildStdinRd);
CloseHandle(hChildStdoutRd);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
void __fastcall BuildAndMessage(AnsiString PathToBuild/*=NULL*/, AnsiString Set/*=NULL*/)
{
AnsiString CommandStr = MakeCommandStr(PathToBuild, Set);
//ShowMessage(CommandStr);
// 读管道
HANDLE hChildStdinWr/*父进程写*/, hChildStdinRd/*子进程读*/;
// 写管道
HANDLE hChildStdoutWr/*子进程写*/, hChildStdoutRd/*父进程读*/;
SECURITY_ATTRIBUTES sa;
_di_IOTAMessageServices MessageServices;
_di_IOTAMessageGroup MessageGroup;
if (BorlandIDEServices->Supports(MessageServices))
{
MessageServices->ClearToolMessages(NULL);
MessageGroup = MessageServices->AddMessageGroup("Ddkbuild");
MessageServices->ShowMessageView(MessageGroup);
}
else
{
ShowMessage("Create ddkbuild messageview failed");
return;
}
sa.bInheritHandle = true;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
// 创建子进程写管道
if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &sa, 0))
{
ShowMessage("Create Stdout pipe failed");
return;
}
SetHandleInformation(hChildStdoutRd, HANDLE_FLAG_INHERIT, 0); // 该句柄子进程没用到,故取消继承性
// 创建子进程读管道
if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &sa,0))
{
ShowMessage("Create StdinRd pipe failed");
return;
}
SetHandleInformation(hChildStdinWr, HANDLE_FLAG_INHERIT, 0); // 该句柄子进程没用到,故取消继承性
//SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr);
//SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd);
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdInput = hChildStdinRd; // 重定向子进程输入
si.hStdOutput = hChildStdoutWr; // 重定向子进程输出
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
// 注意使用了true,这样创建子进程时,父进程的所有可继承的句柄就可以被继承下来了
// 我们也可以使用SetHandleInformation使句柄不可被继承,这样子进程就无法使用了
// 这样的例子可以看《Creating a Child Process with Redirected Input and Output.doc》
if (!CreateProcess(NULL, CommandStr.c_str(), NULL, NULL, true, 0, NULL, NULL, &si, &pi))
{
ShowMessage("Create process failed");
return;
}
// 将数据写入子进程,这里只是演示,本程序不需要写入
const char *strIn = " ";
DWORD dwBytes = 0;
WriteFile(hChildStdinWr, strIn, strlen(strIn), &dwBytes, NULL);
CloseHandle(hChildStdinWr); // 保证对端的ReadFile可返回
// 调用ReadFile前须关闭,否则因写管道写入端有未关闭的Write句柄,ReadFile最后无法返回0
CloseHandle(hChildStdoutWr);
// 从子进程中读出执行结果,不处理mbcs,需要的朋友请加上前导字符的判断
char strData[MAX_PATH * 2];
AnsiString MessageComplete, MessageCut;
char* pos;
char lf = '\n';
void* Unused = 0;
while (ReadFile(hChildStdoutRd, strData, sizeof(strData), &dwBytes, NULL))
{
strData[dwBytes] = 0;
if (pos = strrchr(strData, lf)) // 如果有换行,则显示
{
*(pos-1) = 0;
pos++;
MessageComplete = MessageCut + strData;
MessageCut = pos;
MessageServices->AddToolMessage(
"", MessageComplete, "Ddkbuild", 0, 0, NULL, Unused, MessageGroup);
}
else // 否则暂存
MessageCut = MessageCut + strData;
Application->ProcessMessages();
}
MessageServices->AddToolMessage(
"", MessageCut, "Ddkbuild", 0, 0, NULL, Unused, MessageGroup);
// 关闭句柄
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(hChildStdinRd);
CloseHandle(hChildStdoutRd);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
追问
能否改精简点?第一次使用管道,看不明白。谢谢
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询