.NET, CoInitializeSecurity und RPC_E_TOO_LATE

13 03 2009

Es gibt folgendes Problem: Wir möchten eine existierende C++ Komponente von .NET aus verwenden. Die C++ Komponente implementiert wiederum einen Client für einen DCOM-Server. Wir verwenden hier „echtes“ DCOM, also COM im Netzwerk (LAN) wobei die Verbindung zum Server durch eine Firewall und DCOM-Security (Authentifizierung mittels Benutzername/Passwort) abgesichert ist. Die client-seitigen Security Einstellung und insbesondere die Initialisierung der COM-Security-Schicht mittels CoInitializeSecurity ist äußerst heikel und darf keinesfalls geändert werden. Hier steckt erheblicher Aufwand drin, um die Sache im Kundennetzwerk zuverlässig zum Laufen zu bringen.

Die naheliegende Idee, die C++ Komponente für .NET zugänglich zu machen, wäre die Erstellung eines Adapters mittels Managed C++. Diese Möglichkeit scheidet aber aus da die C++ Komponente in Visual C++ 6.0 implementiert ist und eine Portierung auf VS2008 nicht in Frage kommt.

Wir haben uns daher dafür entschieden, den Adapter als automation-kompatible COM-Komponente zu implementieren. Die COM-Komponente kann dann von .NET aus referenziert und instanziiert werden. Die COM-Klasse lädt dann die bestehende C++-Klasse und adaptiert und delegiert alle gewrappten Methodenaufrufe.

Das Problem dieser Lösung ist, dass der Aufruf von CoInitializeSecurity, der von der Initialisierungfunktion der bestehenden C++ Komponente gemacht wird, mit dem Fehlercode RPC_E_TOO_LATE (0x80010119) fehlschlägt. Siehe hierzu auch CoInitializeSecurity auf pinvoke.net. Dass das so ist, ist logisch: CoInitializeSecurity darf nicht aufgerufen werden, nachdem eine COM-Referenz gemarshalt wurde. Das ist aber hier der Fall, da wir unseren COM-Adapter instanziiert haben und eine Referenz auf die COM-Schnittstelle des Adapters erhalten haben.

Die Lösung für dieses Problem ist, den notwendigen Aufruf von CoInitalizeSecurity über P/Invoke direkt vom .NET Client unmittelbar nach dem Programmstart durchzuführen, bevor der COM-Adapter instanziiert wird.

Hinweis: Der Aufruf von CoInitializeSecurity schlägt im .NET Client ebenfalls mit RPC_E_TOO_LATE fehl wenn der .NET Client Prozess im Debugger läuft und die Option „Enable the Visual Studio hosting process“ aktiv ist. Ohne diese Option funktioniert es.