Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Проблемы с CreateProcess


Автор: нуп 31.5.2012, 19:48
Есть класс, который вызывает php скрипт(через createProcess), дожидается результата выполнения и закрывает процесс. Но иногда процесс закрывается до того, как php отработает. В чем может быть ошибка?
Код

bool TPhpManager::killProcess()
{
    bool res = false;
    if(proc_id)
    {
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, proc_id);
        TerminateProcess (hProcess, 0);
        CloseHandle(hProcess);
    }
    return res;
}

string TPhpManager::getOutput(HANDLE pipe_stdout_read)
{
    char buff[1024];
    string s = "";
    DWORD dwRead,tdwLeft, dwAvail;
    while (ReadFile(pipe_stdout_read, buff, sizeof(buff) - 1, &dwRead, NULL) && dwRead != 0 ) {
        buff[dwRead] = '\0';
        s += buff;
    }
    return s;
}

string TPhpManager::createProccess(wstring command)
{
    if(command.length() == 0)
    {
        command = php_command;
    }
    SECURITY_ATTRIBUTES saAttr;
    STARTUPINFO startup;
    PROCESS_INFORMATION process;
    string data = "";
    int result = 1;
    HANDLE pipe_stdout_write, pipe_stdout_read;

    saAttr.bInheritHandle = TRUE;
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.lpSecurityDescriptor = NULL;

    pipe_stdout_read = pipe_stdout_write = INVALID_HANDLE_VALUE;

    if (CreatePipe(&pipe_stdout_read, &pipe_stdout_write, &saAttr, 0))
    {
        result = 0;
    }

    memset(&startup, 0, sizeof(STARTUPINFO));
    startup.cb         = sizeof(STARTUPINFO);
    startup.dwFlags    = STARTF_USESTDHANDLES;
    startup.hStdOutput = pipe_stdout_write;
    try
    {
        result = CreateProcessW(
            NULL,
            (LPWSTR)command.c_str(),
            &saAttr, &saAttr,
            TRUE,
            DETACHED_PROCESS | CREATE_SUSPENDED,
            NULL,
            NULL,
            (LPSTARTUPINFOW)&startup,
            &process
        );
        proc_id = process.dwProcessId;
        CloseHandle(pipe_stdout_write);
        if(result)
        {
            WaitForSingleObject(process.hProcess, INFINITE);
            ResumeThread(process.hThread);
            data = this->getOutput(pipe_stdout_read);
        }
        CloseHandle(pipe_stdout_read);
    }
    catch(...)
    {
        logger->Add("TPhpManager::createProccess catch error");
    }
    this->killProcess();
    return data;
}

Автор: boostcoder 31.5.2012, 20:10
покажи что возвращает WaitForSingleObject() когда процесс досрочно валится.

Добавлено через 43 секунды
или прога сваливается в catch блок?

Автор: feodorv 31.5.2012, 20:14
Я чего-то не понимаю...

Цитата(нуп @  31.5.2012,  20:48 Найти цитируемый пост)
        result = CreateProcessW(
  ... CREATE_SUSPENDED...
        );


Цитата(нуп @  31.5.2012,  20:48 Найти цитируемый пост)
            WaitForSingleObject(process.hProcess, INFINITE);
            ResumeThread(process.hThread);

То есть сначала ожидается завершение подвешенного процесса, и лишь потом процесс (главный поток) возобновляется?

Автор: нуп 31.5.2012, 20:28
Вот такое 4294967295

Добавлено через 4 минуты и 10 секунд
Заменил на такое, тоже не помогает
Код

try
    {
        result = CreateProcessW(
            NULL,
            (LPWSTR)command.c_str(),
            &saAttr, 
            &saAttr,
            TRUE,
            DETACHED_PROCESS,// | CREATE_SUSPENDED,
            NULL,
            NULL,
            (LPSTARTUPINFOW)&startup,
            &process
        );
        CloseHandle(pipe_stdout_write);
        if(result)
        {
            DWORD d = WaitForSingleObject(&process.hProcess, INFINITE);
            stringstream ss;
            ss << "WaitForSingleObject result = " << d;
            logger->Add(ss.str());
            proc_id = process.dwProcessId;
            //ResumeThread(process.hThread);
            data = this->getOutput(pipe_stdout_read);
            CloseHandle(pipe_stdout_read);
        }
    }
    catch(...)
    {

    }

Автор: boostcoder 31.5.2012, 20:42
Цитата(нуп @  31.5.2012,  20:28 Найти цитируемый пост)
такое 4294967295

хм.. это же WAIT_FAILED...

Автор: нуп 31.5.2012, 20:46
А можете привести рабочий пример создания процесса и получения данных? Может я что-то в корне не правильно делаю

Автор: boostcoder 31.5.2012, 20:47
вставь на следующей строке после WaitForSingleObject(), GetLastError(). и покажи что она возвращает.

Добавлено через 41 секунду
Цитата(нуп @  31.5.2012,  20:46 Найти цитируемый пост)
можете привести рабочий пример создания процесса и получения данных?

для начала, покажи результат GetLastError().

Автор: нуп 31.5.2012, 20:54
WaitForSingleObject result = 4294967295, last error = 6

Автор: feodorv 31.5.2012, 21:58
Цитата(нуп @  31.5.2012,  21:28 Найти цитируемый пост)
WaitForSingleObject(&process.hProcess, INFINITE);

& зачем?

Автор: нуп 31.5.2012, 22:16
Без него вобще все висит всегда

Автор: feodorv 31.5.2012, 22:34
Цитата(нуп @  31.5.2012,  23:16 Найти цитируемый пост)
Без него вобще все висит всегда 

 smile Это метод тыка такой?

Виснет поток, ожидающий завершения процесса. Если процесс завершился, а поток всё висит и висит, то будем разбираться.
Процесс точно завершился?

Автор: нуп 31.5.2012, 23:32
Вообще прикол. php собирает несколько файлов в строку через file_get_contents. Если вставить стоку DWORD d = WaitForSingleObject(process.hProcess, INFINITE);, то php виснет намертво. В чем мои косяки?

Цитата(feodorv @  31.5.2012,  22:34 Найти цитируемый пост)
 Это метод тыка такой?

В примере где-то видел

Автор: feodorv 31.5.2012, 23:45
Цитата(нуп @  1.6.2012,  00:32 Найти цитируемый пост)
php виснет намертво

Ждёт ввода/вывода через пайп? Если без пайпа запускать и руками прибить созданный php-процесс, WaitFor отвисает?

Автор: нуп 1.6.2012, 00:04
Да php отрабатывает. Напишите нубу пример правильного создания процесса и получения данных. 2 дня уже бьюсь с этой фигней

Автор: feodorv 1.6.2012, 11:41
Цитата(нуп @  1.6.2012,  01:04 Найти цитируемый пост)
Да php отрабатывает

Не понял. php отрабатывает без пайпов? Тогда не нужны пайпы, судя по приведённому коду.

Автор: нуп 1.6.2012, 11:46
Да отрабатывает. Но мне нужно получить ответ от пхп, поэтому нужны пайпы

Автор: feodorv 1.6.2012, 12:48
Цитата(нуп @  1.6.2012,  12:46 Найти цитируемый пост)
Но мне нужно получить ответ от пхп, поэтому нужны пайпы 

Тогда нужно читать из пайпа до получения ошибки или какого-то признака, что php закончило вывод.

Добавлено через 9 минут и 6 секунд
Цитата(нуп @  1.6.2012,  01:04 Найти цитируемый пост)
Напишите нубу пример правильного создания процесса и получения данных.

Можно же в посковиках забить одновременно поиск по CreatePipe и CreateProcess и посмотреть примеры smile 

Автор: feodorv 1.6.2012, 13:06
Цитата(нуп @  31.5.2012,  20:48 Найти цитируемый пост)
    startup.dwFlags    = STARTF_USESTDHANDLES;
    startup.hStdOutput = pipe_stdout_write;

Что-то мне подсказывает, что тут не хватает ещё парочки стандартных хендлов...

Автор: нуп 1.6.2012, 17:11
Каких именно?

Автор: feodorv 1.6.2012, 17:51
Цитата(нуп @  1.6.2012,  18:11 Найти цитируемый пост)
Каких именно? 

Код

startup.hStdInput   = pipe_stdin_read; // another pipe
startup.hStdOutput  = pipe_stdout_write;
startup.hStdError   = pipe_stdout_write;

Автор: feodorv 1.6.2012, 19:33
Цитата(нуп @  1.6.2012,  00:32 Найти цитируемый пост)
В примере где-то видел

Я догадался))) Там был WaitForMultipleObjects)))

Автор: нуп 2.6.2012, 10:59
Ошибку пишет 183.
Код

    memset(&startup, 0, sizeof(STARTUPINFO));
    startup.cb         = sizeof(STARTUPINFO);
    startup.dwFlags    = STARTF_USESTDHANDLES;
    startup.hStdOutput = pipe_stdout_read;
    startup.hStdInput = pipe_stdout_write;
    startup.hStdError = pipe_stdout_write;
    try
    {
        result = CreateProcessW(
            NULL,
            (LPWSTR)command.c_str(),
            &saAttr, 
            &saAttr,
            TRUE,
            DETACHED_PROCESS,// | CREATE_SUSPENDED,
            NULL,
            NULL,
            (LPSTARTUPINFOW)&startup,
            &process
        );
        CloseHandle(pipe_stdout_write);
        if(result)
        {
            DWORD d = WaitForSingleObject(process.hProcess, INFINITE);
            DWORD lerror = GetLastError();
            stringstream ss;

            ss << "WaitForSingleObject result = " << d << ", last error = " << lerror;
            logger->Add(ss.str());
            proc_id = process.dwProcessId;
            ResumeThread(process.hThread);
            data = "AAAA";
            data = this->getOutput(pipe_stdout_read);
            CloseHandle(pipe_stdout_read);
        }
    }
    catch(...)
    {

    }
    TerminateProcess(process.hProcess, 0);

Автор: xvr 2.6.2012, 18:40
WaitForSingleObject - выкинуть
ResumeThread(process.hThread); - выкинуть
TerminateProcess(process.hProcess, 0); - выкинуть
И не брать к себе в сорцы текст, смысла которого не понимаете  smile 

Автор: feodorv 2.6.2012, 21:34
Цитата(нуп @  2.6.2012,  11:59 Найти цитируемый пост)
Ошибку пишет 183.

Цитата(нуп @  2.6.2012,  11:59 Найти цитируемый пост)
    startup.hStdOutput = pipe_stdout_read;

Цитата(feodorv @  1.6.2012,  18:51 Найти цитируемый пост)
startup.hStdInput   = pipe_stdin_read; // another pipe



Цитата(feodorv @  1.6.2012,  13:48 Найти цитируемый пост)
Можно же в посковиках забить одновременно поиск по CreatePipe и CreateProcess и посмотреть примеры

Код

/*
  This sample program demonstrates STDIN/STDOUT redirection of a child
  16-bit process.
 
  The program starts an utility, that just reverses all characters in the
  lines (extracted from STDIN) and writes "reversed" content to STDOUT.
 
  I redirect STDIN by anonymous pipe and pass several lines to the child
  process, simulating usual input.
  I redirect STDOUT by anonuymous pipe and grab all output generated by
  child process.
 
  й Kid_Deceiver
*/
#include <windows.h>
#include <stdio.h>
 
char  sysmsg[512];
 
/* GetSysMsg retruns text description of given error code */
char* GetSysMsg( DWORD errcode )
{
    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM
                 | FORMAT_MESSAGE_IGNORE_INSERTS, // don't use arguments
                   NULL,                          // don't use format string
                   errcode,                       // error code
                   0,                             // any language
                   sysmsg, sizeof(sysmsg),        // message buffer
                   NULL);                         // no additional arguments
    return( sysmsg );
}
 
int main()
{
  int                 i;
  DWORD               written, read, err;
  SECURITY_ATTRIBUTES sa;
  STARTUPINFO         si;
  PROCESS_INFORMATION pi;
  HANDLE              hReadOut;   // pipe handles for redirecting STDOUT
  HANDLE              hWriteOut;
  HANDLE              hReadIn;    // pipe handles for redirecting STDIN
  HANDLE              hWriteIn;
  char                buf[255];
  char                *a[] = { ",tnemom dna hctip taerg fo sesirpretne dnA\n",
                               ",yrwa nrut stnerruc rieht drager siht htiW\n",
                               ".noitca fo eman eht esol dnA\n",
                               "\n" };
 
  // Prepare security attributes for pipes.
  // Note - inheritance flag is ON!
  memset( &sa, 0, sizeof(sa) );
  sa.nLength              = sizeof( sa );
  sa.bInheritHandle       = TRUE;
  sa.lpSecurityDescriptor = NULL;
 
  // Create pipe for output redirection
  if (!CreatePipe( &hReadOut,     // read end of the pipr
                   &hWriteOut,    // write end of the pipe
                   &sa,           // security attributes
                   0) ) {         // bytes reserved - default 0
      err = GetLastError();
      fprintf( stderr, "output pipe creation failed (%d) - %s\n",
               err, GetSysMsg( err ) );
      exit( 1 );
  }
 
  // Create pipe for input redirection.
  if (!CreatePipe( &hReadIn,
                   &hWriteIn,
                   &sa,
                   0 ) ) {
      err = GetLastError();
      fprintf( stderr, "input pipe creation failed (%d) - %s\n",
               err, GetSysMsg( err ) );
      CloseHandle( hReadOut );
      CloseHandle( hWriteOut );
      exit( 1 );
  }
 
  // Prepare child process startup data
  // Force child process to use hWriteOut as stdout and hReadIn as stdin
  memset( &si, 0, sizeof(si) );
  si.cb          = sizeof(si);
  si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  si.wShowWindow = SW_HIDE;
  si.hStdInput   = hReadIn;
  si.hStdOutput  = hWriteOut;
  si.hStdError   = hWriteOut;
 
  // Spawn child process.
  if (!CreateProcess( NULL,
                      "util.exe",               // command line
                      NULL, NULL,               // security
                      TRUE,                     // inherit parent handles
                      0, NULL, NULL,            // flags, env, curr. dir
                      &si, &pi )) {             // startup and result
      err = GetLastError();
      fprintf( stderr, "CreateFile failed (%d) - %s\n",
               err, GetSysMsg( err ) );
      CloseHandle( hReadOut );
      CloseHandle( hWriteOut );
      CloseHandle( hReadIn );
      CloseHandle( hWriteIn );
      exit( 1 );
  }
 
  // Close pipe ends, which we're not going to use
  CloseHandle( hWriteOut );  // child process will write here
  CloseHandle( hReadIn );    // child process will read here
 
 
  // Write some input data for the child process
  for (i = 0; i < (sizeof(a)/sizeof(a[0])); i++) {
      WriteFile( hWriteIn, a[i], strlen(a[i]), &written, NULL );
  }
 
  // Read process output.
  while( TRUE ) {
      if ( !ReadFile( hReadOut,      // handle of the read end of our pipe
                      buf,           // address of buffer that receives data
                      sizeof(buf)-1, // number of bytes to read
                      &read,         // number of bytes really read
                      NULL ) ) {     // non-overlapped.
         err = GetLastError();
         fprintf( stderr, "output pipe read error (%d) - %s\n",
                  err, GetSysMsg( err ) );
         // It might be "normal" error. Spawned app just closed the
         // stdout, and in this case ReadFile returned FALSE.
         break;
      }
 
      // Test for the "normal" end of the output
      if (0 == read) {
         break;   // nothing to read, child processs has closed the output
      }
 
      // Write all data from redirected stdout to our own stdout.
      buf[ read ] = 0;
      fprintf( stdout, "%s", buf );
  }
 
  //  Close all remaining handles
  CloseHandle (pi.hProcess);
  CloseHandle (pi.hThread );
  CloseHandle( hReadOut );
  CloseHandle( hWriteIn );
  return 0;
}
 
/*
  This program reads lines from standard input,
  changes characters of each line to reverse order,
  then writes the "reversed" line to stdandard output.
 
  The program terminates if:
    a) EOF occurs in stdin;
    b) empty line (not counting newline character) found.
 
  Built by TC 3.0, 16-bit, small memory model. 
  Executable file UTIL.EXE.
*/
 
#include <stdio.h>
#include <string.h>
 
int main()
{
   char *pc, line[16384];
 
   while( pc = fgets( line, sizeof(line), stdin ) ) {
      strrev( pc );
      if ('\n' == pc[0])
    pc++;
      if (0 == strlen(pc))
    break;
      fprintf( stdout, "%s\n", pc );
   }
   return 0;
}

Код

//------------Пример использования CreateProcess и Anonymous Pipes-----------
// childspawn.cpp
// Приложение запускает shell и перехватывает его ввод/вывод
//---------------------use freely--------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#pragma hdrstop
#include <condefs.h>

#define bzero(a) memset(a,0,sizeof(a)) //для сокращения писанины

bool IsWinNT()  //проверка запуска под NT
{
  OSVERSIONINFO osv;
  osv.dwOSVersionInfoSize = sizeof(osv);
  GetVersionEx(&osv);
  return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}

void ErrorMessage(char *str)  //вывод подробной информации об ошибке
{
  LPVOID msg;
  FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // язык по умолчанию
    (LPTSTR) &msg,
    0,
    NULL
  );
  printf("%s: %s\n",str,msg);
  LocalFree(msg);
}

//---------------------------------------------------------------------------
void main()
{
  char buf[1024];           //буфер ввода/вывода

  STARTUPINFO si;
  SECURITY_ATTRIBUTES sa;
  SECURITY_DESCRIPTOR sd;               //структура security для пайпов
  PROCESS_INFORMATION pi;
  HANDLE newstdin,newstdout,read_stdout,write_stdin;  //дескрипторы пайпов

  if (IsWinNT())        //инициализация security для Windows NT
  {
    InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, true, NULL, false);
    sa.lpSecurityDescriptor = &sd;
  }
  else sa.lpSecurityDescriptor = NULL;
  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle = true;         //разрешаем наследование дескрипторов

  if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) //создаем пайп для stdin
  {
    ErrorMessage("CreatePipe");
    getch();
    return;
  }
  if (!CreatePipe(&read_stdout,&newstdout,&sa,0))  //создаем пайп для stdout
  {
    ErrorMessage("CreatePipe");
    getch();
    CloseHandle(newstdin);
    CloseHandle(write_stdin);
    return;
  }

  GetStartupInfo(&si);      //создаем startupinfo для дочернего процесса
  /*
  Параметр dwFlags сообщает функции CreateProcess как именно надо создать процесс.
  STARTF_USESTDHANDLES управляет полями hStd*.
  STARTF_USESHOWWINDOW управляет полем wShowWindow.
  */
  si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  si.wShowWindow = SW_HIDE;
  si.hStdOutput = newstdout;
  si.hStdError = newstdout;   //подменяем дескрипторы для дочернего процесса
  si.hStdInput = newstdin;
  char app_spawn[] = "d:\\winnt\\system32\\cmd.exe"; //это просто пример,
                                                     //замените на то, что вам нужно

  //создаем дочерний процесс
  if (!CreateProcess(app_spawn,NULL,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,
                     NULL,NULL,&si,&pi))
  {
    ErrorMessage("CreateProcess");
    getch();
    CloseHandle(newstdin);
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    CloseHandle(write_stdin);
    return;
  }

  unsigned long exit=0;  //код завершения процесса
  unsigned long bread;   //кол-во прочитанных байт
  unsigned long avail;   //кол-во доступных байт

  bzero(buf);
  for(;;)      //основной цикл программы
  {
    GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс не закрыт
    if (exit != STILL_ACTIVE)
      break;
    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
    //Проверяем, есть ли данные для чтения в stdout
    if (bread != 0)
    {
      bzero(buf);
      if (avail > 1023)
      {
        while (bread >= 1023)
        {
          ReadFile(read_stdout,buf,1023,&bread,NULL);  //читаем из пайпа stdout
          printf("%s",buf);
          bzero(buf);
        }
      }
      else {
        ReadFile(read_stdout,buf,1023,&bread,NULL);
        printf("%s",buf);
      }
    }
    if (kbhit())      //проверяем, введено ли что-нибудь с клавиатуры
    {
      bzero(buf);
      *buf = (char)getche();
      //printf("%c",*buf);
      WriteFile(write_stdin,buf,1,&bread,NULL); //отправляем это в stdin
      if (*buf == '\r') {
        *buf = '\n';
        printf("%c",*buf);
        WriteFile(write_stdin,buf,1,&bread,NULL); //формирум конец строки,
                                                  //если нужно
      }
    }
  }
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdin);            //небольшая уборка за собой
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
  CloseHandle(write_stdin);
}
//----------------------------EOF--------------------------------------------
//---------------------------------------------------------------------------



Цитата(xvr @  2.6.2012,  19:40 Найти цитируемый пост)
WaitForSingleObject - выкинуть

Цитата(feodorv @  1.6.2012,  13:48 Найти цитируемый пост)
Тогда нужно читать из пайпа до получения ошибки или какого-то признака, что php закончило вывод.


Автор: нуп 3.6.2012, 10:14
Чуть переделал код, всё равно иногда процесс закрывается, до того как пхп выполнится smile 
Код

string TPhpManager::createProccess(wstring command)
{
    string data;
    if(command.length() == 0)
    {
        command = php_command;
    }
    int                 i;
    DWORD               written, read, err;
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO         si;
    PROCESS_INFORMATION pi;
    HANDLE              hReadOut;   // pipe handles for redirecting STDOUT
    HANDLE              hWriteOut;
    HANDLE              hReadIn;    // pipe handles for redirecting STDIN
    HANDLE              hWriteIn;
    char                buf[255];
    char                *a[] = { ",tnemom dna hctip taerg fo sesirpretne dnA\n",
        ",yrwa nrut stnerruc rieht drager siht htiW\n",
        ".noitca fo eman eht esol dnA\n",
        "\n" };

    // Prepare security attributes for pipes.
    // Note - inheritance flag is ON!
    memset( &sa, 0, sizeof(sa) );
    sa.nLength              = sizeof( sa );
    sa.bInheritHandle       = TRUE;
    sa.lpSecurityDescriptor = NULL;

    // Create pipe for output redirection
    if (!CreatePipe( &hReadOut,     // read end of the pipr
        &hWriteOut,    // write end of the pipe
        &sa,           // security attributes
        0) ) {         // bytes reserved - default 0
            err = GetLastError();
            fprintf( stderr, "output pipe creation failed (%d) - %s\n",
                err, "" );
            exit( 1 );
    }

    // Create pipe for input redirection.
    if (!CreatePipe( &hReadIn,
        &hWriteIn,
        &sa,
        0 ) ) {
            err = GetLastError();
            fprintf( stderr, "input pipe creation failed (%d) - %s\n",
                err, "" );
            CloseHandle( hReadOut );
            CloseHandle( hWriteOut );
            return data;
    }

    // Prepare child process startup data
    // Force child process to use hWriteOut as stdout and hReadIn as stdin
    memset( &si, 0, sizeof(si) );
    si.cb          = sizeof(si);
    si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput   = hReadIn;
    si.hStdOutput  = hWriteOut;
    si.hStdError   = hWriteOut;

    //string command_cmd = TUtility::UnicodeToAnsi(command);
    // Spawn child process.
    if (!CreateProcessW( NULL,
        (LPWSTR)command.c_str(),               // command line
        NULL, NULL,               // security
        TRUE,                     // inherit parent handles
        0, NULL, NULL,            // flags, env, curr. dir
        (LPSTARTUPINFOW)&si, &pi )) {             // startup and result
            err = GetLastError();
            fprintf( stderr, "CreateFile failed (%d) - %s\n",
                err,"" );
            CloseHandle( hReadOut );
            CloseHandle( hWriteOut );
            CloseHandle( hReadIn );
            CloseHandle( hWriteIn );
            return data;
    }

    // Close pipe ends, which we're not going to use
    CloseHandle( hWriteOut );  // child process will write here
    CloseHandle( hReadIn );    // child process will read here


    // Write some input data for the child process
    for (i = 0; i < (sizeof(a)/sizeof(a[0])); i++) {
        WriteFile( hWriteIn, a[i], strlen(a[i]), &written, NULL );
    }

    // Read process output.
    while( TRUE ) {
        if ( !ReadFile( hReadOut,      // handle of the read end of our pipe
            buf,           // address of buffer that receives data
            sizeof(buf)-1, // number of bytes to read
            &read,         // number of bytes really read
            NULL ) ) {     // non-overlapped.
                err = GetLastError();
                fprintf( stderr, "output pipe read error (%d) - %s\n",
                    err, "" );
                // It might be "normal" error. Spawned app just closed the
                // stdout, and in this case ReadFile returned FALSE.
                break;
        }

        // Test for the "normal" end of the output
        if (0 == read) {
            break;   // nothing to read, child processs has closed the output
        }

        // Write all data from redirected stdout to our own stdout.
        buf[ read ] = 0;
        data += buf;
        //fprintf( stdout, "%s", buf );
    }

    //  Close all remaining handles
    CloseHandle (pi.hProcess);
    CloseHandle (pi.hThread );
    CloseHandle( hReadOut );
    CloseHandle( hWriteIn );
    return data;
}



Добавлено через 10 минут и 22 секунды
Пхп отсылает запросы через curl, это занимает 5 секунд примерно. В логе выводится такое: 
1) создан процесс php
2) процесс php закрыт
3) php прислал запрос на сервер
В чём может быть дело?   smile 

Автор: feodorv 3.6.2012, 12:45
Цитата(нуп @  3.6.2012,  11:14 Найти цитируемый пост)
В логе выводится такое

Кто кидает эти логи? 

Что считывается в hReadOut, если оно Вам так нужно?
Не может ли php запустить ещё один процесс, если происходит такое:
Цитата(нуп @  3.6.2012,  11:14 Найти цитируемый пост)
2) процесс php закрыт
3) php прислал запрос на сервер


Автор: нуп 3.6.2012, 13:40
В моем примере есть вывод в лог начала и завершения пхп, и ещё один вывод в другом месте. Пхп работает только с curl и собирает несколько файлов в один(новые процессы не создаются ). 
Цитата(feodorv @  3.6.2012,  12:45 Найти цитируемый пост)
Что считывается в hReadOut, если оно Вам так нужно?

Пхп возращает данные, которые сервер передает клиенту

Автор: feodorv 3.6.2012, 14:56
Цитата(нуп @  3.6.2012,  14:40 Найти цитируемый пост)
В моем примере есть вывод в лог начала и завершения пхп

Поискал в приведённом коде, не нашёл...
Кто создаёт лог, кто и когда в него пишет - вопросы, остающиеся без ответа(((

Цитата(нуп @  3.6.2012,  14:40 Найти цитируемый пост)
Пхп возращает данные, которые сервер передает клиенту

Это действительно так? Данные реально возвращаются? Какой же тогда запрос php посылает на сервер после своей предполагаемой кончины? 

Автор: нуп 3.6.2012, 15:16
Цитата(feodorv @  3.6.2012,  14:56 Найти цитируемый пост)
Поискал в приведённом коде, не нашёл...

Код

logger->Add("php created");
...
logger->Add("php die");

Так вот и я не знаю в чем дело. Я ставлю спамера для теста, проходит запросов 20 и 1 из них завершается неудачно. Логер показывает что процес закрылся до того как пхп выполнил запрос.  Может чего то нехватает всетаки в коде?

Автор: feodorv 3.6.2012, 16:42
Цитата(нуп @  3.6.2012,  16:16 Найти цитируемый пост)
Может чего то нехватает всетаки в коде? 

Тогда вместо break при неудаче или 0 при чтении из пайпа вставить GetExitCodeProcess, и если STILL_ACTIVE, то задержку на полсекунды, потом продолжить чтение из пайпа.

Добавлено через 1 минуту и 5 секунд
В тестовых целях можно в php-скрипт вставить задержки после запроса к серверу, но перед печатью результатов запроса...

Добавлено через 4 минуты и 37 секунд
Цитата(нуп @  3.6.2012,  16:16 Найти цитируемый пост)
logger->Add("php created");
...
logger->Add("php die");

Всё равно, не понятно, так как в приведённом коде я этих строчек не нашёл. Не нашёл и "php прислал запрос на сервер".
Нельзя ли точнее сформулировать, кто что кому посылает и в какой момент логится.

Автор: нуп 4.6.2012, 15:56
Код

while( TRUE ) {
        if ( !ReadFile( hReadOut,      // handle of the read end of our pipe
            buf,           // address of buffer that receives data
            sizeof(buf)-1, // number of bytes to read
            &read,         // number of bytes really read
            NULL ) ) {     // non-overlapped.
                err = GetLastError();
                fprintf( stderr, "output pipe read error (%d) - %s\n",
                    err, "" );
                // It might be "normal" error. Spawned app just closed the
                // stdout, and in this case ReadFile returned FALSE.
                DWORD exitCode;
                GetExitCodeProcess(pi.hProcess, &exitCode);
                if(STILL_ACTIVE == exitCode)
                {
                    Sleep(500);
                }
                else
                {
                    break;
                }

        }

Всегда попадает на sleep. Сейчас буду тестировать php без запросов, а просто через sleep

Автор: нуп 4.6.2012, 17:54
Да уж, если php не посылает запросы, то всё нормально. Хотя и заходит в это условие
Код

GetExitCodeProcess(pi.hProcess, &exitCode);
                if(STILL_ACTIVE == exitCode)
                {
                    Sleep(500);
                }

Автор: нуп 5.6.2012, 14:38
Вообщем проблема в пхп, curl иногда падает по таймауту. Всем спс за помощь

Автор: feodorv 5.6.2012, 20:00
Цитата(нуп @  5.6.2012,  15:38 Найти цитируемый пост)
Вообщем проблема в пхп, curl иногда падает по таймауту.

Печально...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)