Пайпы
Создаем процесс
Код:
CreateProcess(L"mencoder",L" mencoder C:/Users/Flyer_/Desktop/Test/Temp.avi -ovc copy -nosound -of rawvideo -o C:/Users/Flyer_/Desktop/Test/Temp.264",NULL,NULL,TRUE,CREATE_NEW_CONSOLE, NULL,NULL,&si,&pi))
//тут сразу вопрос, если нужно сформировать командную строку в зависимости например, от имени файла или путя , как это сделать, что бы не ругалось, что хочет wchar ?
//тут сразу вопрос, если нужно сформировать командную строку в зависимости например, от имени файла или путя , как это сделать, что бы не ругалось, что хочет wchar ?
Вот то, что выводит консольное приложение. Выводит оно довольно таки часто кстати.
Как организовать пайп, чтобы программа считывала то, что выводит консольное приложение и выводила, ну например на лэйбл?
Буду очень признателен, если кто сможет объяснить мне . Заранее спасибо
этой статьи заработал.
Ну и поиск по форуму по CreatePipe много чего полезного выдаст ;)
Сначала добейся того, чтобы у тебя пример из
Ну и поиск по форуму по CreatePipe много чего полезного выдаст ;)
В родительском добавь printf("luke i am your father");
фраза однако :) Ну, тогда значит работы примера я добился. Но вопрос, почему дочерний процесс не закрывается по закрытию родительского?
Job Objetcs думаю то что тебе нужно, создаёшь задачу, ассоциируешь с ней процесс и при убивании родительского процесса дочерний тоже прибьётся (вроде должен, сам не проверял).
И ещё попробуй вместо CREATE_NEW_CONSOLE указать CREATE_NO_WINDOW, тогда вроде второго окна консоли не будет.
Ну когда на MFC будешь делать, то на WM_QUIT закрывать все дескрипторы дочернего процесса и прибивать его, но это не спасёт от убивания процесса в диспетчере задач))
И ещё попробуй вместо CREATE_NEW_CONSOLE указать CREATE_NO_WINDOW, тогда вроде второго окна консоли не будет.
Спасибо за помощь. И еще вопрос, можно перехватывать там например, только каждые скажем 3 сообщения от дочернего процесса? А то их, много и обработка каждого тормозит работу.
Лучше оптимизировать процесс обработки, а то вдруг пропустишь чтонибудь важное :) Ну и посмотри в справку по параметру -msglevel ;)
И последний вопрос ( надеюсь) . Как закрыть дочерний процесс, но так чтобы и память освободилась?
TerminateProcess, ну и естественно закрыть все дескрипторы, используемые совместно с дочерним процессом. (CloseHandle из примера)
Почему не ExitProcess? И что за параметры? Можешь пожалуйста написать код на закрытие процессана примере процесса созданого в примере статьи?
Пример прост до безобразия:
Было:
Код:
bzero(buf);
for(;;) //основной цикл программы
{
GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс
// не закрыт
if (exit != STILL_ACTIVE)
break;
for(;;) //основной цикл программы
{
GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс
// не закрыт
if (exit != STILL_ACTIVE)
break;
Стало:
Код:
int exit = 0;
bzero(buf);
for(;;) //основной цикл программы
{
GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс
// не закрыт
if (exit != STILL_ACTIVE)
break;
if(++exit>10)
if(!TerminateProcess(pi.hProcess,0))
printf("Error terminating process. GetLastError: %X", (unsigned int)GetLastError());
else
break;
bzero(buf);
for(;;) //основной цикл программы
{
GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс
// не закрыт
if (exit != STILL_ACTIVE)
break;
if(++exit>10)
if(!TerminateProcess(pi.hProcess,0))
printf("Error terminating process. GetLastError: %X", (unsigned int)GetLastError());
else
break;
А так да. просто до безобразия
Код:
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);
}
{
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. Склеивает звук и видео в мп4
А теперь проблема. При первом нажатии кнопки все идет нормально, родительское приложение не подвисает, нормально заполняется шкала. После окончания, при нажатии кнопки опять, родительское приложение зависает до тех пор, пока 4 выше перечисленных действия не будут выполнены. Почему и как исправить ? :)