Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с CreateProcess и его убиением

71K
12 августа 2011 года
FlyerUA
14 / / 10.08.2011
Доброго времени суток. У меня тут небольшая проблема с CreateProcess. На кнопке стоит следующий код:
Код:
void __fastcall TForm1::Button13Click(TObject *Sender)
{
if(DirectoryExists(path.c_str())==false){
 CreateDirectoryA (path.c_str(), NULL);  }
 
    Gauge1->Progress=0;
    unsigned long exit=0;
    unsigned long bread;
    unsigned long avail;
 
    GetStartupInfoA(&si);
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout;
    CreateProcessA( "mencoder.exe", first_cmd.c_str(),   0,   0 ,   1,   CREATE_NEW_CONSOLE,     0,           0,           &si, &pi);
    bzero(buf);
    for(;;)
    {
            GetExitCodeProcess(pi.hProcess,&exit);
 
        if (exit != STILL_ACTIVE)
        break;
 
    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
    if (bread != 0)
    {
      bzero(buf);
      if (avail > 1023)
      {
      a=1;
        while (bread >= 1023)
        {
          ReadFile(read_stdout,buf,1023,&bread,NULL);
          Application->ProcessMessages();
          AnsiString str;
          str=buf;
        int pos1=str.Pos("f (");
        int pos2=str.Pos("%)");
        TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
        if(i>a && i>0)
        {
        Gauge1->Progress++;
        a=i;
        }
        bzero(buf);
        }
      }
      else
      {
 
        ReadFile(read_stdout,buf,1023,&bread,NULL);
        Application->ProcessMessages();
        AnsiString str;
        str=buf;
        int pos1=str.Pos("f (");
        int pos2=str.Pos("%)");
        TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
        if(i>a && i>0)
        {
        Gauge1->Progress++;
        a=i;
        }
 
      }
 
    }
 
 
  }
 
//-----------------------------------------------------------------------
 
  GetStartupInfoA(&si);
  si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  si.wShowWindow = SW_HIDE;
  si.hStdOutput = newstdout;
  si.hStdError = newstdout;
  CreateProcessA( "mencoder.exe", cmd2.c_str(),   0,   0 ,   1,   CREATE_NEW_CONSOLE,     0,           0,           &si, &pi);
  bzero(buf);
 
  for(;;)
  {
    GetExitCodeProcess(pi.hProcess,&exit);
 
    if (exit != STILL_ACTIVE)
      break;
 
    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
 
 
    if (bread != 0)
    {
      bzero(buf);
      if (avail > 1023)
      {
      a=1;
        while (bread >= 1023)
        {
          ReadFile(read_stdout,buf,1023,&bread,NULL);
          Application->ProcessMessages();
          AnsiString str;
          str=buf;
          int pos1=str.Pos("f (");
          int pos2=str.Pos("%)");
          TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
          if(i>a && i>0)
          {
            Gauge1->Progress++;
            a=i;
          }
          bzero(buf);
        }
      }
      else
      {
 
        ReadFile(read_stdout,buf,1023,&bread,NULL);
          Application->ProcessMessages();
          AnsiString str;
          str=buf;
          int pos1=str.Pos("f (");
          int pos2=str.Pos("%)");
          TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
          if(i>a && i>0)
          {
          Gauge1->Progress+=0.05;
          a=i;
          }
 
      }
 
    }
 
 
  }
  Gauge1->Progress=105;
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
 
// ----------------------------------------------------------
 
  GetStartupInfoA(&si);
 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
 si.wShowWindow = SW_HIDE;
 si.hStdOutput = newstdout;
 si.hStdError = newstdout;
  CreateProcessA( "mencoder.exe", cmd3.c_str(),   0,   0 ,   1,   CREATE_NEW_CONSOLE,     0,           0,           &si, &pi);
  bzero(buf);
  for(;;)
  {
    GetExitCodeProcess(pi.hProcess,&exit);
        if (exit != STILL_ACTIVE)
            break;
 
    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
    if (bread != 0)
    {
      bzero(buf);
      if (avail > 1023)
      {
      a=1;
        while (bread >= 1023)
        {
          ReadFile(read_stdout,buf,1023,&bread,NULL);
          Application->ProcessMessages();
          AnsiString str;
          str=buf;
            int pos1=str.Pos("f (");
            int pos2=str.Pos("%)");
            TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
                if(i>a && i>0)
                    {
                    Gauge1->Progress++;
                    a=i;
                    }
          bzero(buf);
        }
      }
      else
      {
        ReadFile(read_stdout,buf,1023,&bread,NULL);
        Application->ProcessMessages();
        AnsiString str;
        str=buf;
        int pos1=str.Pos("f (");
        int pos2=str.Pos("%)");
        TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
            if(i>a && i>0)
            {
            Gauge1->Progress+=0.05;
            a=i;
            }
 
      }
 
    }
 
 
  }
  Gauge1->Progress=110;
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
 
  // ----------------------------------------------------------
 
 GetStartupInfoA(&si);
 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
 si.wShowWindow = SW_HIDE;
 si.hStdOutput = newstdout;
 si.hStdError = newstdout;
 CreateProcessA( "MP4Box.exe", cmd4.c_str(),   0,   0 ,   1,   CREATE_NEW_CONSOLE,     0,           0,           &si, &pi);
 bzero(buf);
    for(;;)
    {
    GetExitCodeProcess(pi.hProcess,&exit);
        if (exit != STILL_ACTIVE)
            break;
 
    }
       Gauge1->Progress=112;
        AnsiString temp1=path+"Temp.264" ;
        AnsiString temp2=path+"Temp.aac" ;
        AnsiString temp3=path+"Temp.avi";
        remove( temp1.c_str() );
        remove( temp2.c_str() );
        remove( temp3.c_str() );
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
  }

То что он делает:
1. Конвертирует входной файл в ави
2. Конвертирует видео поток в х264
3. Извлекает звук
4. Склеивает звук и х264 видео в мп4

А теперь проблема. При первом нажатии кнопки все идет нормально, родительское приложение не подвисает, нормально заполняется шкала. Теперь, если захотим вдруг сконвертировать другой файл или тот самый опять, не суть, родительское приложение подвиснет до того времени, пока все 4 выше перечисленные действия не будут выполнены. Почему такое случается и как это исправить?

И второй вопрос, о убиении процесса.
TerminateProcess(pi.hProcess,0);
Убьет только 1 процесс, а остальные 3 (если кнопка нажата пока выполняется 1ый из 4 процесс) ( с кода сверху) будут выполнены. Собственно вопрос, как убить текущий процесс и сделать чтобы остальные 3 уже не запускались? (если кнопка нажата пока выполняется 1ый из 4 процесс) .
И как убрать за собой после этих процессов, чтобы память освободилась.[/QUOTE]
14
13 августа 2011 года
Phodopus
3.3K / / 19.06.2008
Меня привели в замешательство эти повторяющиеся идентичные строки кода. Надо что-то делать.
71K
13 августа 2011 года
FlyerUA
14 / / 10.08.2011
Есть предложения что делать? :)
14
13 августа 2011 года
Phodopus
3.3K / / 19.06.2008
Рефакторить и отдавать на суд публике отрефакторенный код :)
71K
14 августа 2011 года
FlyerUA
14 / / 10.08.2011
Было бы хорошо, если бы я понял что ты имел ввиду :o
412
14 августа 2011 года
grgdvo
323 / / 04.07.2007
Расставьте для начала комментарии хотя бы... Ну и как-то на блоки что ли разбейте... А то читать эту, извините, портянку ну совсем неудобно. Пока до конца текста дойдешь, забываешь, что было в начале. Чужой код - всегда читать тяжелее.

Полагаю висеть начинает, так как обработчик кнопки не закончил выполнять предыдущее нажатие, а тут поступило следующее...

цитирую википедию:
Цитата:
Рефакторинг (англ. refactoring) — процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы



Наверно вам надо написать отдельную процедуру, которая обрабатывает вывод mencoder'а, далее параметризовать ее, чтобы удовлетворить вашим пунктам 1,2,3 и 4.... ну и потом все пункты выполнять (делать вызовы процедуры) в отдельном потоке, которые запускается искомой кнопкой... не забыть добавить управление этим потоком (завершение, прерывание, и т.п.).

71K
14 августа 2011 года
FlyerUA
14 / / 10.08.2011
Ну, тогда попытка с комментами. Если нужно больше , дайте знать. Я попробую обьяснить
Код:
void __fastcall TForm1::Button13Click(TObject *Sender)
{
if(DirectoryExists(path.c_str())==false){ // проверка на существование папки в которую конвертирует, ну и если нету то создаем
 CreateDirectoryA (path.c_str(), NULL);  }
 
    Gauge1->Progress=0; // устанавливаем шкалу на 0
    unsigned long exit=0;
    unsigned long bread;
    unsigned long avail;
 
    GetStartupInfoA(&si);
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout;
    CreateProcessA( "mencoder.exe", first_cmd.c_str(),   0,   0 ,   1,   CREATE_NEW_CONSOLE,     0,           0,           &si, &pi); // первый процесс, конвертирование видео в ави
    bzero(buf);
    for(;;)
    {
            GetExitCodeProcess(pi.hProcess,&exit);
 
        if (exit != STILL_ACTIVE)
        break;
 
    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
    if (bread != 0)
    {
      bzero(buf);
        ReadFile(read_stdout,buf,1023,&bread,NULL);  // менкодер выводит % выполнения задания. Получаем процент и заполняем шкалу
        Application->ProcessMessages();
        str=buf;
        int pos1=str.Pos("f (");
        int pos2=str.Pos("%)");
        TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
        if(i>a && i>0)
        {
        Gauge1->Progress++;
        a=i;
        }
    }
  }
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
 
//-----------------------------------------------------------------------
 
  GetStartupInfoA(&si);
  si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
  si.wShowWindow = SW_HIDE;
  si.hStdOutput = newstdout;
  si.hStdError = newstdout;
  CreateProcessA( "mencoder.exe", cmd2.c_str(),   0,   0 ,   1,   CREATE_NEW_CONSOLE,     0,           0,           &si, &pi); // конвертирует видео  поток из ави в h264
  bzero(buf);
 
  for(;;)
  {
    GetExitCodeProcess(pi.hProcess,&exit);
 
    if (exit != STILL_ACTIVE)
      break;
 
    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
    if (bread != 0)
    {
      bzero(buf);
        ReadFile(read_stdout,buf,1023,&bread,NULL);
          Application->ProcessMessages(); // аналогично как и с 1 процессом
          str=buf;
          int pos1=str.Pos("f (");
          int pos2=str.Pos("%)");
          TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
          if(i>a && i>0)
          {
          Gauge1->Progress+=0.05;
          a=i;
          }
    }
  }
  Gauge1->Progress=105;
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
 
// ----------------------------------------------------------
 
  GetStartupInfoA(&si);
 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
 si.wShowWindow = SW_HIDE;
 si.hStdOutput = newstdout;
 si.hStdError = newstdout;
  CreateProcessA( "mencoder.exe", cmd3.c_str(),   0,   0 ,   1,   CREATE_NEW_CONSOLE,     0,           0,           &si, &pi); // вырезает аудио поток из ави из 1 процесса
  bzero(buf);
  for(;;)
  {
    GetExitCodeProcess(pi.hProcess,&exit);
        if (exit != STILL_ACTIVE)
            break;
 
    PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
    if (bread != 0)
    {
      bzero(buf);
        ReadFile(read_stdout,buf,1023,&bread,NULL);
        Application->ProcessMessages();  //аналогично
        str=buf;
        int pos1=str.Pos("f (");
        int pos2=str.Pos("%)");
        TryStrToInt(str.SubString(pos1+3,pos2-pos1-3),i)   ;
            if(i>a && i>0)
            {
            Gauge1->Progress+=0.05;
            a=i;
            }
 
     
 
    }
 
 
  }
  Gauge1->Progress=110;
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
 
  // ----------------------------------------------------------
 
 GetStartupInfoA(&si);
 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
 si.wShowWindow = SW_HIDE;
 si.hStdOutput = newstdout;
 si.hStdError = newstdout;
 CreateProcessA( "MP4Box.exe", cmd4.c_str(),   0,   0 ,   1,   CREATE_NEW_CONSOLE,     0,           0,           &si, &pi); //склеивает h264 и аудио в мп4
 bzero(buf);
    for(;;)
    {
    GetExitCodeProcess(pi.hProcess,&exit);
        if (exit != STILL_ACTIVE)
            break;
 
    }
       Gauge1->Progress=112;
        AnsiString temp1=path+"Temp.264" ; // удаляет временные файлы
        AnsiString temp2=path+"Temp.aac" ;
        AnsiString temp3=path+"Temp.avi";
        remove( temp1.c_str() );
        remove( temp2.c_str() );
        remove( temp3.c_str() );
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  CloseHandle(newstdout);
  CloseHandle(read_stdout);
  }
14
14 августа 2011 года
Phodopus
3.3K / / 19.06.2008
почему у вас 3 аналогичных куска программы идут подряд? Вы можете оформить это в функцию?
71K
15 августа 2011 года
FlyerUA
14 / / 10.08.2011
Не уверен честно говоря
14
15 августа 2011 года
Phodopus
3.3K / / 19.06.2008
Ну тогда нет смысла искать ошибку. Дублирование кода есть распространенная причина кучи ошибок..
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог