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


Автор: Lazin 8.11.2007, 10:26
Пишу программу, которая должна получать информацию от разных процессов. Вместе с информацией передается идентификатор процесса, передавшего информацию ( GetCurrentProcessId() ). Моя программа по этим идентификаторам процессы различает, плюс получает информацию о процессе, вот так:
Код

HANDLE _h_proc = OpenProcess(
            PROCESS_QUERY_INFORMATION /*| PROCESS_VM_READ*/, 
            FALSE, id//<--идентификатор процесса
            );

далее я делаю с хэндлом всякое, например это
Код

if ( ! GetProcessImageFileName(_h_proc, _base_name, _MAX_PATH)  )
{
    blablabla - обработка всяких ошибок

В общем программа различает все процессы которые к ней обращаются. 
Проблема в том, что моя программа работает долго, а процессы которые с ней работают могут пере запускаться многократно, и в один прекрасный момент вновь запушеный процесс может иметь такой-же идентификатор как и процесс убитый неделю назад, и в этом случае логика работы нарушается. В общем я решил, отслеживать не только id процесса, но и время его запуска. Такой набор данных будет уникален для всех когда либо запущенных процессов ОС.
Либо еще один вариант, можно(?) как то определить момент завершения процесса(не только нормального, но и аварийного), и ... удалить невалидный идентификатор из списка.

Автор: ama_kid 8.11.2007, 10:56
Как вариант - можно периодически делать "снимок" процессов функцией EnumProcesses и если процесса из твоего списка нету в снимке - тогда он не валиден...

Автор: Lazin 8.11.2007, 11:39
Цитата(ama_kid @  8.11.2007,  10:56 Найти цитируемый пост)
Как вариант - можно периодически делать "снимок" процессов функцией EnumProcesses и если процесса из твоего списка нету в снимке - тогда он не валиден... 

То-же вариант.
Открыл для себя функцию GetProcessTimes.
P.S.
Еше один вопрос, что возвратит функция WaitForSingleObject(hProcess, INFINITE) при завершении процесса hProcess.

Добавлено через 2 минуты и 9 секунд
WAIT_OBJECT_0, WAIT_TIMEOUT или WAIT_ABANDONED?

Автор: SergeCpp 8.11.2007, 12:18
Цитата(Lazin @  8.11.2007,  12:26 Найти цитируемый пост)
Вместе с информацией передается идентификатор процесса, передавшего информацию ( GetCurrentProcessId() )

Чтобы не было вот такого вот
Цитата(Lazin @  8.11.2007,  12:26 Найти цитируемый пост)
в один прекрасный момент вновь запушеный процесс может иметь такой-же идентификатор как и процесс убитый неделю назад

Нужно передавать handle (GetCurrentProcess() => DuplicateHandle())

Полученный handle будет действителен. Если при очередной проверке окажется, что процесс уже не работает, handle можно и закрыть если он не нужен дальше. Можно и удерживать.

Автор: Lazin 8.11.2007, 13:05
SergeCpp, а что делать если процессы разные - часть 32х битные, а часть 64х, у них HANDLE будет разной длины. А вообще спасибо, интересный вариант.

Автор: SergeCpp 8.11.2007, 16:07
С handle что-нибудь сами придумайте, это уже микроскопические детали

Использование Process ID в Вашей задаче чем-то сродни
неиспользованию межпроцессной синхронизации при доступе к разделяемому ресурсу

Используя же handle, Вы придерживаете объект ядра процесс, он не будет удалён
(сам процесс может быть и завершён)

Автор: Lazin 14.11.2007, 16:21
еще один вопрос, я пытаюсь проверить существует ли процесс с определенным идентификатором с помощью OpenProcess, msdn говорит что OpenProcess возвращает NULL, если процесс с таким идентификатором не существует, но на практике выясняется, что OpenProcess для недавно закрытого процесса (через TerminateProcess) возвращает хэндл(не NULL и не INVALID_HANDLE_VALUE), по которому можно получить информацию о процессе!!! В это время процесса с таким идентификатором в системе нет и в помине. Как можно еще проверить есть ли процесс с заданным идентификатором, не делая snapshot всех процессов.

Автор: asd 15.11.2007, 07:58
Lazin, 
Чтобы узнать завершился ли процес Нужно вызвать ф-ию GetExitCodeProcess. Если процесс работает, то ф-ия вернёт STILL_ACTIVE, если нет, то статус завершения.
Чтобы поймать момент завершения процесса, нужно Перезать в ф-ию WaitForSingleObject хендл процесса, и ожидание закончится, когда процесс завершится. 
Вобщем в MSDN-е прочитай про эти ф-ии.

Автор: Lazin 15.11.2007, 08:28
Цитата(asd @  15.11.2007,  07:58 Найти цитируемый пост)
Чтобы узнать завершился ли процес Нужно вызвать ф-ию GetExitCodeProcess. Если процесс работает, то ф-ия вернёт STILL_ACTIVE, если нет, то статус завершения.

Вообще изначально у меня есть id процесса, по нему я получаю хэндл, так-вот, для завершенного процесса(через terminate) в течении длительного времени возвращается нормальный хэндл, мне очень интересно почему.
Wait функции, то-же ведут себя так как будто процесс не завершен, хотя процесса с таким id в данный момент времени несуществует.
В списке возвращаемом EnumProcesses его то-же нету.

Автор: Lazin 15.11.2007, 09:30
GetExitCodeProcess работает так как нужно, всем спс
правда я так и непонял почему процесс можно открыть функцией OpenProcess после его (процесса) завершения

Автор: SergeCpp 15.11.2007, 10:15
Цитата(Lazin @  15.11.2007,  11:30 Найти цитируемый пост)
...не понял, почему процесс можно открыть функцией OpenProcess после его (процесса) завершения...

Я уже писал про это

Цитата(SergeCpp @  8.11.2007,  18:07 Найти цитируемый пост)
Используя же handle, Вы придерживаете объект ядра процесс, он не будет удалён
(сам процесс может быть и завершён)


Дело в том, что объект ядра процесс удерживается системой до тех пор,
пока есть хотя бы один открытый handle этого процесса

Выполнение процесса — это ведь условность, это же выполнение потока в процессе

Существование объекта ядра "процесс" не зависит от выполнения объекта ядра "поток" в этом процессе

Проверьте Ваши программы — все ли handle процессов закрываются (когда они уже не нужны)

Автор: Lazin 15.11.2007, 11:17
Цитата(SergeCpp @  15.11.2007,  10:15 Найти цитируемый пост)
Проверьте Ваши программы — все ли handle процессов закрываются (когда они уже не нужны)

в том то и дело, что  закрываются, это очень легко проверить: во первых по коду их использование ограничено одним классом, handle-ы создаются и сразу уничтожаются, и никогда не хранятся,
во вторых, когда я открываю процессы с разными id
Код

for (....)
HANDLE hProc = OpenProcess(....
*****
CloseHandle(hProc);

hProc - всегда имеет одно и то-же значение, если бы я не закрыл хэндл где-нибудь, то значения хэндлов для разных процессов отличались-бы.

Автор: alias_trinity 11.12.2007, 13:42
Для получения информации про процесс юзай Натив АПИ. NtQuerySystemInformation(). Полезная штука. 
Можеш написать полноценный диспетчер задач.
Хотя в режиме юзера тоже можно заменить кучкой ф-ций. GetProcessMemoryInfo(), GetProcessHandleCount(), GetProcessTimes()...

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