2009-05-04 6 views
3

Der Windows-API DuplicateHandle() http://msdn.microsoft.com/en-us/library/ms724251(VS.85).aspx den Objektgriff erfordert sowohl den ursprünglichen Prozess und den anderen Prozess, den Sie in den duplizierten Griff verwenden mögen dupliziert und einen Griff werden.DuplicateHandle(), im ersten oder zweiten Prozess verwenden?

Ich gehe davon aus, dass, wenn ich habe zwei UNRELATED-Prozesse, könnte ich DuplicateHandle() in beiden aufrufen, solange ich die benötigten Handles zur Verfügung hatte?

Meine Frage bezieht sich auf die Verwendung einer Pipe für die Kommunikation zwischen den beiden Prozessen, um dies mit einem Event zu erreichen.

Im ersten Prozess CreateEvent(). Jetzt möchte ich WaitForSingleObject() im zweiten Prozess verwenden.

Wenn ich versuche, das Handle im ersten Prozess zu duplizieren, muss ich zuerst das zweite Prozess-Handle an den ersten Prozess über die Pipe senden, das Handle duplizieren und dann den Handle an den zweiten Prozess übergeben?

Alternativ könnte ich beginnen, indem Sie das erste Prozess-Handle und das Event-Handle an den zweiten Prozess senden und es dort einfach duplizieren.

Gibt es einen Grund, warum ich einen über den anderen wählen sollte?

Zum Hinzufügen eines Knicks wird das Ereignis-Handle tatsächlich vom übergeordneten Prozess geerbt, der den ersten Prozess (der eine CGI-Anwendung ist) aufgerufen hat. Wenn dieses Event-Handle mit HANDLE_DO_NOT_DUPLICATE (so etwas) erstellt wurde, kann ich dann DuplicateHandle() verwenden, um es für den zweiten Prozess zu duplizieren?

Antwort:

Nun, ich ein neues benanntes Ereignis in dem ersten Prozess schaffen könnte und in dem zweiten Prozess finden, wie vorgeschlagen, aber ich versuche, um das Ereignis zu duplizieren, die in den übergeordneten des ersten Prozess erstellt wurden und weiter zum zweiten Prozess. Dieses Ereignis ist kein benanntes Ereignis, daher muss ich DuplicateHandle() verwenden.

Ich verwende eine Leitung für den IPC. Ich bin mir bewusst, dass DuplicateHandle() im ersten Prozess aufgerufen werden muss, da das Event-Handle außerhalb des Kontextes ist, wenn es an den zweiten Prozess gesendet wird.

 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) 

Der zweite Prozess wandelt seinen Griff mit DuplicateHandle() Ausführliches oben Umwandlung

hProcPseudo = 4294967295

zu

hProcess = 152

Dann gebe ich diesen Prozess Handle der erste Prozess über die Named Pipe. In dem ersten Verfahren (in dem das Ereignis Handle gültig ist) nenne ich doppelte Griff:

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

Unfortunatly bekomme ich den Fehler:

DuplicateHandle hPipeFCGI GetLastError = 6 - Der Griff ist ungültig.

Weitere Tests (Substitution von hFirstProcess) zeigt, dass es hSecondProc ungültig ist!

Großes Geheimnis.

+1

Ich kenne Ihr Layout nicht, aber möchten Sie ein benanntes Ereignis verwenden? Das könnte einfacher sein, als zu versuchen, das Handle zu duplizieren. –

Antwort

1

Verwenden Sie eine named pipe oder mailslots für IPC, dies sollte zuverlässig für Ihren Zweck arbeiten. Wenn Sie warten müssen, verwenden Sie die Wait-Handles.

Sonst würde ich wählen, DuplicateHandle im zweiten Prozess zu tun, um die Handle-Besitz richtig zu setzen.

+0

Ich benutze eine NamedPipe erfolgreich für die IPC ja. Ich kann das Handle in dem zweiten Prozess nicht duplizieren, da das Handle aus dem ersten Prozess keinen Kontext in dem zweiten Prozess hat. Ich wundere mich auch über die Tatsache, dass GetCurrentProcess() den gleichen Wert in beiden Prozessen zurückgibt ... –

+0

Das liegt daran, dass GetCurrentProcess() zuerst einen konstanten Pseudo-Handle an den Prozess zurückgibt, den Sie auflösen müssen, bevor Sie ihn an den anderen Prozess übergeben über RPC. Sehen Sie die Dokumentation hier: http://msdn.microsoft.com/en-us/library/ms683179(VS.85).aspx – Lucero

+0

Ahhh ok, so dass der obige Code ok aussehen? Es scheint seltsam, DuplicateHandle() mit dem Pseudo-Handle als die ersten drei Argumente aufzurufen! –

1

Wenn ich richtig verstanden habe, möchten Sie zwei unabhängige Prozesse über das gleiche Ereignis synchronisieren. Wenn dies der Fall ist, können Sie benannte Ereignisse verwenden.

Erstellen Sie einen mit CreateEvent API-Funktion, geben Sie einen Namen, dann aus dem zweiten Prozess OpenEvent API-Funktion, die Angabe des Namens des Ereignisses.

Sie haben ähnliche Funktionen für andere Synchronisationsobjekte, z. B. Mutexe (OpenMutex) oder Semaphore (OpenSemaphore).

+0

Siehe oben. Ich sehe einen identischen Wert für GetCurrentProcess() - in DuplicateHandle() verwendet - in BEIDE Prozesse. Das scheint nicht richtig zu sein? Warum ist das? –

+0

Welche Art von Handle haben Sie versucht, mit DuplicateHandle zu duplizieren? AFAIK, der Prozess, der das Handle (mit CreateXXXX-Funktionen) erstellt hat, ist der Besitzer des erstellten Objekts. –

1
  1. Irgendwie muss der zweite Prozess seine Prozess-ID zum ersten Prozess bekommen. Dies kann durch "GetProcessId (GetCurrentProcess());"
  2. Der erste Prozess muss jetzt diese ID verwenden, um ein HANDLE für den zweiten Prozess zu erhalten: "hProcess = OpenProcess (PROCESS_DUP_HANDLE, FALSE, dwProcessId);"
  3. Jetzt können Sie das Handle im ersten Prozess duplizieren, mit der REAL-Prozess-Handle des zweiten Prozesses und der Pseudo-Handle des ersten Prozesses: "DuplicateHandle (GetCurrentProcess(), hEvent, hProcess, & hDupEvent, 0, FALSE , DUPLICATE_SAME_ACCESS); "
  4. Denken Sie daran, das Handle freizugeben, das Sie mit "OpenProcess" erstellt haben (ich weiß nicht, welchen Unterschied es machen würde, aber Sie sollten es ...). Geben Sie BOTH auch für das Ereignis frei: das für den zweiten Prozess und das anfängliche Handle.
0

Prozesshandle unterscheidet sich von Prozess-ID. OpenProcess übernimmt die Prozess-ID. Verwenden Sie etwas wie ...

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

Verwandte Themen