C-运行可执行文件并检索输出
我正在尝试创建一个程序,该程序在运行时将以“-exampleparmeter--exampleparmeter2”作为cli输入打开examplecliprogram.exe,等待examplecliprogram.exe终止,然后获取输出并对其执行一些有用的操作。我希望examplecliprogram.exe在后台运行(而不是在另一个窗口中打开),同时examplecliprogram.exe的输出显示在运行开销程序的窗口中 到目前为止,我已经探索了一些选项,如popen()、ShellExecute()和CreateProcess(),但我似乎无法让它们中的任何一个正常工作 首先,我希望这个程序能够在Windows环境中独立运行,与Linux的兼容性将是一个额外的好处C-运行可执行文件并检索输出,c,windows,C,Windows,我正在尝试创建一个程序,该程序在运行时将以“-exampleparmeter--exampleparmeter2”作为cli输入打开examplecliprogram.exe,等待examplecliprogram.exe终止,然后获取输出并对其执行一些有用的操作。我希望examplecliprogram.exe在后台运行(而不是在另一个窗口中打开),同时examplecliprogram.exe的输出显示在运行开销程序的窗口中 到目前为止,我已经探索了一些选项,如popen()、ShellEx
编辑:我通过调用系统(“参数”)找到了一个解决方案。我不知道这是否是一个很好的解决方案,可以很好地移植到gui,但至少它解决了基本问题。您可能想看看这个Microsoft示例代码。这对我很有用。
您可能需要查看此Microsoft示例代码。这对我很有用。
我使用了CreateProcess,不幸的是,除了“仔细阅读msdn”和“从简单开始,向复杂推进”之外,我不能向您推荐任何东西
至于可移植性——如果您到目前为止还不需要使用跨平台工具包,我不建议您仅仅因为这一点就开始使用跨平台工具包。我建议您编写一些“启动流程”包装,并以其固有的方式在每个平台上实现它。我使用了CreateProcess,不幸的是,除了“仔细阅读msdn”和“从简单开始,向复杂推进”之外,我不能向您推荐任何东西
至于可移植性——如果您到目前为止还不需要使用跨平台工具包,我不建议您仅仅因为这一点就开始使用跨平台工具包。我建议您编写一些“启动进程”包装器,并以其本机方式在每个平台上实现它。此代码在Windows和Unix上运行(我在Visual Studio中测试过,在Cygwin上测试过GCC,在Mac OS X上测试过GCC) 我必须根据平台使用宏来定义popen,因为在Windows上,函数名是
\u popen
,而在其他平台上,函数名是popen
(注意前面的下划线)
#包括
#包括
/*换成你想要的节目*/
//#定义程序“PROGRAM.exe--param1--param2”
#定义程序“dir”
#定义区块长度1024
#ifdef_WIN32
#定义popen\u popen
#定义pclose\u pclose
#恩迪夫
int main(int argc,字符**argv){
/*确保命令的输出不会干扰标准输出*/
fflush(stdin);
FILE*cmd_FILE=(FILE*)popen(程序,“r”);
如果(!cmd_文件){
printf(“调用popen时出错\n”);
}
char*buf=(char*)malloc(CHUNK_LEN);
长指令输出长度=0;
int bytes_read=0;
做{
bytes_read=fread(buf+cmd_output_len、sizeof(char)、CHUNK_len、cmd_file);
cmd_output_len+=字节数_read;
buf=(char*)realloc(buf,cmd\u output\u len+CHUNK\u len);
}while(bytes\u read==CHUNK\u LEN);
/*Nul终止字符串*/
*((char*)buf+cmd_output_len)='\0';
/*关闭文件指针*/
pclose(cmd_文件);
/*用缓冲区做东西*/
printf(“%s\n”,buf);
/*自由缓冲区*/
免费(buf);
返回0;
}
此代码在Windows和Unix上运行(我在Visual Studio中测试过,在Cygwin上测试过GCC,在Mac OS X上测试过GCC)
我必须根据平台使用宏来定义popen,因为在Windows上,函数名是\u popen
,而在其他平台上,函数名是popen
(注意前面的下划线)
#包括
#包括
/*换成你想要的节目*/
//#定义程序“PROGRAM.exe--param1--param2”
#定义程序“dir”
#定义区块长度1024
#ifdef_WIN32
#定义popen\u popen
#定义pclose\u pclose
#恩迪夫
int main(int argc,字符**argv){
/*确保命令的输出不会干扰标准输出*/
fflush(stdin);
FILE*cmd_FILE=(FILE*)popen(程序,“r”);
如果(!cmd_文件){
printf(“调用popen时出错\n”);
}
char*buf=(char*)malloc(CHUNK_LEN);
长指令输出长度=0;
int bytes_read=0;
做{
bytes_read=fread(buf+cmd_output_len、sizeof(char)、CHUNK_len、cmd_file);
cmd_output_len+=字节数_read;
buf=(char*)realloc(buf,cmd\u output\u len+CHUNK\u len);
}while(bytes\u read==CHUNK\u LEN);
/*Nul终止字符串*/
*((char*)buf+cmd_output_len)='\0';
/*关闭文件指针*/
pclose(cmd_文件);
/*用缓冲区做东西*/
printf(“%s\n”,buf);
/*自由缓冲区*/
免费(buf);
返回0;
}
最干净、最便携的方法是使用GLib的g\u spawn\u sync()
你可以找到这些文件
最干净、最便携的方法是使用GLib的
g\u spawn\u sync()
你可以找到这些文件
如果使用像Qt或Gtk这样的跨平台工具包,您将能够以可移植的方式实现这一点(例如Qt上的
QProcess
,Gtk上的g_spawn\u async_with_pipe
),发布一些代码,展示您的尝试popen
绝对是最简单的方法(而且是跨平台的),但它有局限性CreateProcess
是功能最全的,但它很重,使用起来也更复杂,而且不是跨平台的。如果使用像Qt或Gtk这样的跨平台工具包,您将拥有这样做的功能(例如Qt上的QProcess
,Gtk上的g_spawn_async_with_pipe
)以一种可移植的方式。发布一些代码,显示您尝试了什么popen
绝对是最简单的方法(而且是跨平台的),但它有局限性CreateProcess
是功能最全的,但它很重,使用起来更复杂,而且
#include <stdlib.h>
#include <stdio.h>
/* Change to whichever program you want */
//#define PROGRAM "program.exe --param1 --param2"
#define PROGRAM "dir"
#define CHUNK_LEN 1024
#ifdef _WIN32
#define popen _popen
#define pclose _pclose
#endif
int main(int argc, char **argv) {
/* Ensure that output of command does interfere with stdout */
fflush(stdin);
FILE *cmd_file = (FILE *) popen(PROGRAM, "r");
if (!cmd_file) {
printf("Error calling popen\n");
}
char *buf = (char *) malloc(CHUNK_LEN);
long cmd_output_len = 0;
int bytes_read = 0;
do {
bytes_read = fread(buf + cmd_output_len, sizeof(char), CHUNK_LEN, cmd_file);
cmd_output_len += bytes_read;
buf = (char *) realloc(buf, cmd_output_len + CHUNK_LEN);
} while (bytes_read == CHUNK_LEN);
/* Nul terminate string */
*((char *) buf + cmd_output_len) = '\0';
/* Close file pointer */
pclose(cmd_file);
/* Do stuff with buffer */
printf("%s\n", buf);
/* Free buffer */
free(buf);
return 0;
}
gchar * std_out = NULL;
gchar * std_err = NULL;
gint exit_stat = 0;
const char *argv[] = {"--foo", "123", "--bar", "22323", NULL};
if(!g_spawn_sync (NULL, argv, NULL, NULL, NULL, NULL, &std_out, &std_err, &exit_stat, NULL)){
fprintf(stderr, "Failed to spawn!\n");
};
/* std_out and std_err should now point to the respective output.*/