2012-08-02 99 views
2

我想要做的是创建一个程序,在运行时,用“--exampleparameter --exampleparameter2”作为cli输入打开examplecliprogram.exe,等待examplecliprogram.exe终止,然后拿出输出并做一些有用的事情。我希望examplecliprogram.exe在后台运行(而不是在另一个窗口中打开),而在运行开销程序的窗口中显示examplecliprogram.exe的输出。C - 运行一个可执行文件并检索输出

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

首先,我希望这个程序能够在Windows环境中独立运行,并且与Linux的兼容性将是一项奖励。

编辑:我找到了一个通过调用系统(“参数”)的解决方案。我不知道这是否是一个很好的解决方案,可以很好地传递给gui,但至少可以解决基本问题。

+1

如果使用的跨平台工具包一样的Qt或GTK,你会在一个可移植的方式有(Qt的,在GTK'g_spawn_async_with_pipe'例如'QProcess')的功能来做到这一点。 – 2012-08-02 17:41:02

+1

发布一些代码,显示你的尝试。 'popen'绝对是最简单的方法(它是跨平台的),但它有局限性。 'CreateProcess'是功能最全面的,但重量更大,使用更复杂,并且不是跨平台的。 – 2012-08-02 17:41:47

回答

0

此代码在Windows和Unix上运行(我在Visual Studio中测试,Cygwin上的GCC和Mac OS X上的GCC)。

我不得不使用宏来定义POPEN根据不同的平台,因为在Windows上,功能_popen,而在其他平台上的功能名称是popen(注意前一个下划线)。

#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; 
} 
0

我用CreateProcess,不幸的是,除了'仔细阅读msdn'和'从简单和进度到复杂'之外,我不能推荐任何东西。至于可移植性 - 如果你到现在还没有需要使用一些跨平台的工具包,我不会建议你仅仅因为这个而开始使用一个。我建议你编写一些'启动过程'包装并以其原生方式在每个平台上实现它。

0

这样做最清洁和最便携的方式是使用GLib的g_spawn_sync()

你可以找到文档online

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.*/ 
相关问题