2016-03-16 3 views
0

Я работаю в C-проекте, окружении Windows, используя WinAPI. Моя функция выполняет команду (e.g. : "dir C:\Users"), полученную в качестве параметра, и возвращает свой вывод.
Он бежит от DLL, поэтому он не должен порождать окна cmd.exe, что означает, что я не могу использовать _popen. Поэтому я использую CreateProcessA и трубу, чтобы поймать stdout.Windows CreateProcess и перенаправление вывода

Вот код:

char *runExec(char *command, int *contentLen) { 
    char *ret=NULL,*tmp=NULL; 
    DWORD readBytes; 
    int size=0; 
    char buffer[128],cmdBuf[4096]; 
    HANDLE StdOutHandles[2]; 

    CreatePipe(&StdOutHandles[0], &StdOutHandles[1], NULL, 4096); 

    STARTUPINFOA si; 
    memset(&si, 0, sizeof(si)); 
    si.cb = sizeof(si); 
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; 
    si.wShowWindow = SW_HIDE; 
    si.hStdOutput = StdOutHandles[1]; 
    si.hStdError = StdOutHandles[1]; 
    PROCESS_INFORMATION pi; 

    snprintf(cmdBuf,4096,"cmd /C %s", command); 
    if (!CreateProcessA(NULL, cmdBuf, NULL, NULL, FALSE, CREATE_NO_WINDOW | DETACHED_PROCESS, NULL, NULL, &si, &pi)) { 
     printf("Error createProcess : %d\n",GetLastError()); 
     return NULL; 
    } 


    CloseHandle(StdOutHandles[1]); 
    printf("Before read\n"); 
    while (ReadFile(StdOutHandles[0], buffer, 127, &readBytes, NULL)){ 
     printf("IN WHILE\n"); 
     buffer[readBytes] = 0; 
     printf("read %d bytes\n", readBytes); 
     size += readBytes; 
     tmp = (char *)realloc(ret, size + 1); 
     if (tmp == NULL) { 
      free(ret); 
      return NULL; 
     } 
     ret = tmp; 
     strncpy(ret + (size - readBytes), buffer, readBytes); 
     ret[size] = 0; 
    } 
    printf("Readfile returned with %d, read %d\n", GetLastError(),readBytes); 

    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread); 
    CloseHandle(StdOutHandles[0]); 
    printf("#%s#\n", ret); 

    return ret; 
} 

И выход:

Before read 
Readfile returned with 109, read 0 
#(null)# 

Так от этого я понимаю, что:
- Мой цикл даже не выполненный один раз
- ReadFile ничего не читает и возвращает Brok ru Труба немедленно

Я прочитал различные страницы stackoverflow и MSDN, но я не могу заставить его работать.

+0

Из документации STARTUPINFO: * Если этот флаг указан при вызове одной из функций создания процесса, ручки должны быть наследуемыми, а параметр bInheritHandles функции должен быть установлен в значение ИСТИНА. Для получения дополнительной информации см. «Наследование на ручку». * Оба требования не выполняются вашим кодом. –

+0

Aaaaand Я не могу читать ... Спасибо за это! –

ответ

0

Как было отмечено в комментарии, ручки должны быть наследуемыми, что означает замену CreatePipe так:

SECURITY_ATTRIBUTES pipeAttrib; 
memset(&pipeAttrib, 0, sizeof(pipeAttrib)); 

pipeAttrib.nLength = sizeof(SECURITY_ATTRIBUTES); 
pipeAttrib.bInheritHandle = NULL; 
pipeAttrib.bInheritHandle = TRUE; 

if (!CreatePipe(&StdOutHandles[0], &StdOutHandles[1],&pipeAttrib, 4096)) { 
    printf("Create pipe error %d\n", GetLastError()); 
    return NULL; 
} 

и установка CreateProcess 5-й параметр (bInheritHandles) в TRUE вместо FALSE.

Смежные вопросы