C-运行可执行文件并检索输出

C-运行可执行文件并检索输出,c,windows,C,Windows,我正在尝试创建一个程序,该程序在运行时将以“-exampleparmeter--exampleparmeter2”作为cli输入打开examplecliprogram.exe,等待examplecliprogram.exe终止,然后获取输出并对其执行一些有用的操作。我希望examplecliprogram.exe在后台运行(而不是在另一个窗口中打开),同时examplecliprogram.exe的输出显示在运行开销程序的窗口中 到目前为止,我已经探索了一些选项,如popen()、ShellEx

我正在尝试创建一个程序,该程序在运行时将以“-exampleparmeter--exampleparmeter2”作为cli输入打开examplecliprogram.exe,等待examplecliprogram.exe终止,然后获取输出并对其执行一些有用的操作。我希望examplecliprogram.exe在后台运行(而不是在另一个窗口中打开),同时examplecliprogram.exe的输出显示在运行开销程序的窗口中

到目前为止,我已经探索了一些选项,如popen()、ShellExecute()和CreateProcess(),但我似乎无法让它们中的任何一个正常工作

首先,我希望这个程序能够在Windows环境中独立运行,与Linux的兼容性将是一个额外的好处


编辑:我通过调用系统(“参数”)找到了一个解决方案。我不知道这是否是一个很好的解决方案,可以很好地移植到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.*/