Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« : 13-08-2010 07:01 » |
|
Вопрос вот такой. (Сразу оговорюсь, что с потоками ввода/вывода не приходилось работать - опыта нет в этом)
Основной процесс запускает дочерний процесс через WinAPI::CreateProcess. Дочерний процесс что-то делает и ведёт текстовый лог. Сейчас лог скидывается в текстовый файл, а вот как бы сделать так, чтобы через стандартный поток лог шёл сразу в основной процесс и там уже обрабатывался? И будет ли это дело тормозить основной процесс?
|
|
|
Записан
|
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 15-08-2010 17:32 » |
|
А для чего делается вот это // Ensure the read handle to the pipe for STDOUT is not inherited. if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) ) ErrorExit(TEXT("Stdout SetHandleInformation")); ... ...
// Ensure the write handle to the pipe for STDIN is not inherited. if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) ) ErrorExit(TEXT("Stdin SetHandleInformation"));
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #4 : 15-08-2010 17:53 » |
|
Трубы как правило на одном конце затыкают. Тот ктго будет принимать, затыкает запись. И наоборот.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #5 : 15-08-2010 17:59 » |
|
Имя константы - HANDLE_FLAG_INHERIT - наводит на мысль, что в винде тоже можно управлять наследованием открытых файлов для дочернего процесса. Стоит обратиться в MSDN за деталями по SetHandleInformation(). В POSIX-системах по умолчанию все открытые файлы наследуются и можно пометить нужные через fcntl(), чтобы они не наследовались. Думаю тут аналогичный процесс показан.
|
|
« Последнее редактирование: 15-08-2010 18:01 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 15-08-2010 18:04 » |
|
HANDLE_FLAG_INHERIT - If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the object handle.
а, ну, то есть, это "затыкание" выражается в том, что хендл не передаётся программистом дочернему процессу. А если случайно всё-таки он передал, то хендл будет там недействителен
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #7 : 15-08-2010 18:37 » |
|
Да, кстати, всё никак не могу победить такую штуку - когда запускаю дочерний процесс (у него своё окно есть, правда скрытое - задаю это ещё в структуре STARTUPINFO), то фокус теряется с главного процесса.
Никакие SetFocus и обработка WM_KILLFOCUS для главного окна родительского процесса не спасают. Что тут сделать нужно, чтоб фокус оставался на окне главного процесса?
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #8 : 15-08-2010 20:16 » |
|
1. Дождаться окончания загрузки дочернего процесса. 2. Вызвать ShowWindow SW_SHOW, затем SetFocus для родительского процесса.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #9 : 15-08-2010 20:34 » |
|
А если сделать также, как делает обычный пользователь? Установи фокус на другое окно и потом верни на свое. Может есть более гуманные способы...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 16-08-2010 03:38 » |
|
zubr, RXL, всё это пробовал раньше и попробовал на всякий случай сейчас ещё раз - не помогает.
Делал даже тупо Sleep(5000) (процесс запускается за это время уж точно на 100%) - потом фокус на рабочий стол, потом на главное окно. И нифига, всё равно фокус потерян
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #11 : 16-08-2010 08:52 » |
|
Ну а чего spy++ говорит? какие сообщения приходят окну (как родительскому, так и дочернему)? Речь конечно о сообщения, которые как-то влияют на отображение окон и потерю+захват фокуса.
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 16-08-2010 09:02 » |
|
lapulya, для главного окна происходит следующее (из состояния "в фокусе"+ "дочерний ещё не запущен"): а для дочернего не могу посмотреть по техническим причинам
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 16-08-2010 09:02 » |
|
Делать ActivateWindow для главного окна я пробовал - нет реакции
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #14 : 16-08-2010 12:04 » |
|
В какой момент открыто окно дочернего процесса (это я про лог сообщений)? А обойти эти технические причмны нельзя, чтобы посмотреть чтож там у дочки то?
|
|
|
Записан
|
С уважением Lapulya
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 16-08-2010 13:28 » |
|
lapulya, окно дочернего процесса вообще всегда невидимо, а лог записывался в текстовый файл на диске
А как обойти то ? Разве что записать все сообщения в оконной процедуре. Но это долго возиться
Да оно не так уж важно, так как у меня при запуске программы дочерние создаются, но всё равно неприятно )
Я , как руки дойдут, попробую тестовый проект сделать - может быть, у меня какая-то особенность вкралась
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #16 : 16-08-2010 18:22 » |
|
А нет апишки для побайтового сравнения двух файлов (на предмет одинаковые/разные)? Не смог найти в MSDN
Или же придётся вручную делать маппинг обоих файлов, а потом memcmp()==0 ?
А зачем - так у меня дочерний процесс формируется копированием исходного экзешника, а потом переименовывается и запускается Хочется избежать лишнего копирования
|
|
« Последнее редактирование: 16-08-2010 18:24 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 16-08-2010 19:47 » |
|
оть //тест на необходимость копирования //const char* pSrcModulePath //const char* pDstModulePath bool bNeedCopy=true; { HANDLE H1=0; HANDLE H2=0; HANDLE M1=0; HANDLE M2=0; void* pf1=0; void* pf2=0; for(;;) { H1=::CreateFile(pSrcModulePath,GENERIC_READ,0,0,OPEN_EXISTING,0,0); H2=::CreateFile(pDstModulePath,GENERIC_READ,0,0,OPEN_EXISTING,0,0); if(H1==INVALID_HANDLE_VALUE)break; if(H2==INVALID_HANDLE_VALUE)break;
DWORD dwdSize=::GetFileSize(H1,0); if(dwdSize!=::GetFileSize(H2,0))break;
M1=::CreateFileMapping(H1,0,PAGE_READONLY,0,dwdSize,0); M2=::CreateFileMapping(H2,0,PAGE_READONLY,0,dwdSize,0); if(M1==0)break; if(M2==0)break;
pf1=::MapViewOfFile(M1,FILE_MAP_READ,0,0,dwdSize); pf2=::MapViewOfFile(M2,FILE_MAP_READ,0,0,dwdSize); if(pf1==0)break; if(pf2==0)break;
if(0!=::memcmp(pf1,pf2,dwdSize))break;
bNeedCopy=false; break; } if(pf1)::UnmapViewOfFile(pf1);pf1=0; if(pf2)::UnmapViewOfFile(pf2);pf2=0; if(M1)::CloseHandle(M1);M1=0; if(M2)::CloseHandle(M2);M2=0; if(H1)::CloseHandle(H1);H1=0; if(H2)::CloseHandle(H2);H2=0; }
//копируем if(!bNeedCopy || ::CopyFile(pSrcModulePath, pDstModulePath,0)) { //запуск дочернего процесса ... }
|
|
« Последнее редактирование: 16-08-2010 20:00 от Алексей1153++ »
|
Записан
|
|
|
|
baldr
|
|
« Ответ #18 : 17-08-2010 06:39 » |
|
А нет апишки для побайтового сравнения двух файлов (на предмет одинаковые/разные)? Не смог найти в MSDN
Или же придётся вручную делать маппинг обоих файлов, а потом memcmp()==0 ?
А зачем - так у меня дочерний процесс формируется копированием исходного экзешника, а потом переименовывается и запускается Хочется избежать лишнего копирования
Лёх, попробуй какую-нибудь функцию для взятия хэша, типа getmd5() или ече что-нибудь такое.. Сравнишь хэши. Не должно быть долго, зато самому писать не надо.
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #19 : 17-08-2010 08:31 » |
|
baldr, да уже написал вроде )) Но сильно сомневаюсь, что расчёт хеша будет быстрее, чем memcmp двух проекций. Файлы - по 5 метров, сравнивается мгновенно
Кстати, работают трубы, всё , победил )
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #20 : 18-08-2010 06:49 » |
|
Жаль только, что отладку второй процесс уже не запустишь так, чтоб там были унаследованные хендлы (
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #21 : 19-08-2010 04:58 » |
|
А вот такой ещё вопрос. Что передать в качестве stdOUT хендла процессу, чтоб он выводил поток в окно отладки студии ? Такое возможно?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #22 : 03-09-2010 07:11 » |
|
ещё вопрос: как не заблокироваться при чтении из трубы я сделал через PeekNamedPipe , а воть как определить, что в трубу больше не надо записывать (что она полная), чтобы не заблокироваться ?
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #23 : 03-09-2010 08:35 » |
|
Леш, а что твой процесс будет делать, если труба полная? Тут либо писать (и блокироваться), либо увеличивать буфер, либо сбрасывать во временный файл, либо вообще отбрасывать.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #24 : 03-09-2010 10:09 » |
|
он просто перестанет записывать, пусть данные теряются. Главное, чтоб не застопорилось
|
|
|
Записан
|
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #25 : 03-09-2010 23:04 » |
|
Чтоб не блокироваться на I/O операциях, весь мир издревле пользуется асинхронным I/O.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #26 : 04-09-2010 09:17 » |
|
resource, как его сделать асинхронным ?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #27 : 04-09-2010 11:38 » |
|
структуру OVERLAPPED заполнить, когда ReadFile/WriteFile вызываешь) еще кажется при CreateFile - флаг FILE_FLAG_OVERLAPPED поставить... в msdn надо глянуть) либо сразу ReadFileEx()использовать
|
|
« Последнее редактирование: 04-09-2010 11:43 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #28 : 04-09-2010 12:56 » |
|
В данном случае наверное не CreateFile, а CreateNamedPipe. dwOpenMode должен включать FILE_FLAG_OVERLAPPED. Ну и дальше The ReadFileEx and WriteFileEx functions can only be used with a pipe handle in overlapped mode. The ReadFile, WriteFile, ConnectNamedPipe, and TransactNamedPipe functions can execute either synchronously or as overlapped operations.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #29 : 04-09-2010 15:13 » |
|
соответственно)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|