DuplicateHandle (), использовать в первом или втором процессе? - PullRequest
4 голосов
/ 04 мая 2009

Windows API DuplicateHandle () http://msdn.microsoft.com/en-us/library/ms724251(VS.85).aspx Требует дублирования дескриптора объекта и дескриптора как исходного процесса, так и другого процесса, в котором вы хотите использовать дублированный дескриптор.

Я предполагаю, что, если у меня есть два НЕПРАВИЛЬНЫХ процесса, я могу вызвать DuplicateHandle () в любом из них, если у меня есть необходимые дескрипторы?

Мой вопрос касается использования канала для связи между двумя процессами для достижения этого с помощью события.

В первом процессе я создаю событие (). Теперь я хочу использовать WaitForSingleObject () во втором процессе.

Если я попытаюсь продублировать дескриптор в первом процессе, мне нужно будет сначала отправить второй дескриптор процесса в первый процесс через канал, продублировать дескриптор, а затем отправить дескриптор второму процессу?

Альтернативно, я мог бы начать с отправки дескриптора первого процесса и дескриптора события второму процессу и просто скопировать его там.

Есть ли причина, по которой я должен выбрать один из других?

Чтобы добавить складку, дескриптор Event фактически наследуется от родительского процесса, который фактически вызвал первый процесс (который является приложением CGI). Если этот дескриптор события был создан с помощью HANDLE_DO_NOT_DUPLICATE (что-то в этом роде), то могу ли я фактически использовать DuplicateHandle () для дублирования его для второго процесса?

Ответ:

Что ж, я мог бы создать новое событие NAMED в первом процессе и найти его во втором процессе, как было предложено, но я пытаюсь ДУБЛИРОВАТЬ событие, которое было создано в родительском элементе первого процесса, и перенаправить его во второй процесс. , Это событие не является именованным, поэтому мне нужно использовать DuplicateHandle ().

Я использую трубу для МПК. Я понимаю, что DuplicateHandle () придется вызывать в первом процессе, потому что дескриптор события находится вне контекста при отправке во второй процесс.

        hProcPseudo  = GetCurrentProcess() 

    //Then call either:
        lpRealHandle = OpenProcess( PROCESS_DUP_HANDLE, 0, hProcPseudo ) 
//This fails with GetLastError= 87 - The parameter is incorrect ???
// same thing with PROCESS_ALL_ACCESS ??


    //OR
        lRet = DuplicateHandle( hProcPseudo, hProcPseudo, hProcPseudo, lpRealHandle, DUPLICATE_SAME_ACCESS, 0, 0 )

    //then I can Duplicate my Event Handle in the first thread with:
        lRet = DuplicateHandle( hLocalProcess, hEvent, lpRealHandle, hDupEvent, DUPLICATE_SAME_ACCESS, 0, 0)

Второй процесс преобразует свой дескриптор с помощью функции DuplicateHandle (), описанной выше при конвертации

hProcPseudo = 4294967295

до

hProcess = 152

Затем я передаю дескриптор этого процесса первому процессу через именованный канал. В первом процессе (где дескриптор события действителен) я вызываю дубликат дескриптора:

DuplicateHandle( hFirstProcess, hEvent, hSecondProc, hDupEvent, DUPLICATE_SAME_ACCESS, 0, 0)

К сожалению, я получаю сообщение об ошибке:

DuplicateHandle hPipeFCGI GetLastError = 6 - дескриптор недействителен.

Дальнейшее тестирование (замена hFirstProcess) показывает, что hSecondProc является недействительным! ??

Большая Тайна.

Ответы [ 4 ]

2 голосов
/ 17 августа 2012

Process Handle отличается от идентификатора процесса. OpenProcess принимает идентификатор процесса. Используйте что-то вроде ...

HANDLE hProcess = OpenProcess (PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId ());

2 голосов
/ 04 мая 2009

Используйте именованный канал или почтовые ящики для IPC, это должно работать надежно для ваших целей Если вам нужно подождать, используйте именованные дескрипторы ожидания.

В противном случае я бы выбрал DuplicateHandle во втором процессе, чтобы правильно установить владение дескриптором.

1 голос
/ 05 ноября 2011
  1. Каким-то образом второй процесс должен получить свой идентификатор процесса для первого процесса. Это может быть получено через GetCurrentProcessId()
  2. Первый процесс теперь должен использовать этот идентификатор, чтобы получить HANDLE для второго процесса: hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
  3. Теперь вы можете продублировать дескриптор в первом процессе, используя реальный дескриптор процесса второго процесса и псевдо-дескриптор первого процесса: DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hDupEvent, 0, FALSE, DUPLICATE_SAME_ACCESS);
  4. Не забудьте в конце концов выпустить ручку, которую вы создали с помощью OpenProcess (я не знаю, какая разница, но вы должны ...). Кроме того, освободите ОБА дескрипторы события: один, данный второму процессу и начальный дескриптор.
1 голос
/ 04 мая 2009

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

Создайте его с помощью CreateEvent API-функции, введите имя, затем из второго процесса используйте OpenEvent API-функцию, указав имя события.

У вас есть похожие функции для других объектов синхронизации, таких как мьютексы ( OpenMutex ) или семафоры ( OpenSemaphore ).

...