2012-08-02 102 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.*/ 
相關問題