Kategorien

Manuelle COM to .NET Interoperability

Wegen diverser Einschränkungen auf dem GIS-Terminalserver an meinem Arbeitsplatz, kann ich mit ArcObjects entwickelte .NET-Komponenten nicht automatisch im COM-System registrieren und damit für ArcGIS zugänglich machen. Dasselbe gilt natürlich auch für selber entwickelte COM-Objekte, auch die können nicht registriert werden. Die Registrierung von .NET-Komponenten im COM-System läuft unter dem Stichwort “COM to .NET Interoperability”. Grob gesagt müssen dazu folgende Schritte ausgeführt werden:

1) Jeder Klasse in der DLL, die für das COM-System sichtbar sein soll, muss im Code eine eindeutige ID, die sogenannte GUID, zugewiesen werden. Die GUID kann mit dem GUID-Tool erzeugt werden. Das GUID-Tool ist Teil der ArcGIS-Installation und wahrscheinlich auch in der Visual Studio-IDE enthalten. Die Zuordnung erfolgt im Code mit folgenden Anweisungen:

	[ClassInterface(ClassInterfaceType.None)]
	[Guid("7CF958B9-0F0C-4CFF-B8C8-0DC6528071FA")]
	public class BerechneLaenge: ICommand

2) Um dem COM-System die neue DLL bekanntzumachen, müssen verschiedene Einträge in der Windows-Registry vorgenommen werden. Der eigentlich dafür vorgesehene Teilschlüssel der Registry (HKEY_CLASSES_ROOT) ist auf dem GIS-Server schreibgeschützt. Stattdessen muss die Registrierung im Teilschlüssel HKEY_CURRENT_USER\Software\Classes vorgenommen werden. Das heisst aber auch, dass die DLL dann nur für den Benutzer verfügbar ist, der die Registrierung vorgenommen hat. Wenn ein anderer Benutzer die DLL auch benutzen will, muss er sie ebenfalls noch registrieren.

3) Die Registrierung geschieht mit einem Registry-File, in dem alle notwendigen Einträge zusammengefasst sind. Die Erstellung des Grundgerüsts für dieses Registry-File geschieht mit Regasm.exe. Regasm steht für “Register Assembly” und ist Teil des .NET-Frameworks:

	RegAsm.exe /codebase /reg:MyRegFile.reg MyDLL.dll

4) Im so entstandenen Registry-File muss jedes Auftreten von “HKEY_CLASSES_ROOT” mit “HKEY_CURRENT_USER\Software\Classes” ersetzt werden (Suchen/Ersetzen in einem Editor).

5) Der Pfad in jedem Codebase-Wert muss auf das Verzeichnis gesetzt werden, in dem die DLL liegt und in dem sie später auch ausgeführt wird.

6) Jedes ITool, ICommand oder andere ArcObjects-Interface, das in ArcGIS verwendet werden soll, muss in einer oder mehreren sogenannten “Command Category” registriert werden. Einen Überblick über alle auf dem jeweiligen System vorhandenen Categories zeigt der OLEViewer oder der “Component Category Manager” (ist Teil der ArcGIS-Installation). Z.B. sind alle ArcMap-Commands in der Kategorie “ESRI Mx Commands”, alle ArcMap-Toolbars in der Kategorie “ESRI Mx CommandBars”, alle ArcMap-Extensions in der Kategorie “ESRI Mx Extensions” etc. ESRI hat dazu eine Übersicht über alle Commands, Menus und Toolbars in ArcMap und deren Kategorien und GUIDs zusammengestellt. Jede Kategorie weist wiederum eine eindeutige GUID auf, die aus der erwähnten Übersicht oder via den OLEViewer ermittelt werden kann. Der Registry-Schlüssel für die Category-Registrierung sieht etwa so aus (alle drei Zeilen gehören auf eine):

[HKEY_CURRENT_USER\Software\Classes\
CLSID\{Klassen-GUID}\
Implemented Categories\{Kategorien-GUID}]

Die erste GUID ist diejenige der betroffenen Klasse (Command, Toolbar etc.), die zweite GUID diejenige der Kategorie, in dem die Klasse registriert werden soll. Mit dem oben erwähnten Regasm-Befehl wird gleichzeitig auch für jede Klasse ein Registry-Schlüssel angelegt, der die Klasse in der Kategorie “.NET Category” registriert. Dies muss also nicht mehr manuell erledigt werden.

7) COM braucht allerdings noch weitere Infos über eine DLL, damit alles klappt. Diese Informationen werden in einer Type Library gespeichert. Die “Type Library” kann mit dem Programm TypeLibraryExporter.exe erzeugt werden, welches Teil des Buches “COM and .NET Interoperability” ist. Der Sourcecode kann auf der Buch-Homepage heruntergeladen werden. Das Programm kann einfach kompiliert und ausgeführt werden. Anschliessend müssen nur noch Pfad und Dateiname der DLL eingegeben und die Frage nach der Registrierung für COM mit Nein beantwortet werden. Danach wird das TLB-File erzeugt. Dieses gehört dann in das gleiche Verzeichnis wie die DLL.

8) Die Type Library selbst muss auch noch in der Registry registriert werden. Die Vorlage dazu:

[HKEY_CURRENT_USER\Software\Classes\TypeLib\{TLB-GUID}]
[HKEY_CURRENT_USER\Software\Classes\TypeLib\{TLB-GUID}\1.0]
[HKEY_CURRENT_USER\Software\Classes\TypeLib\{TLB-GUID}\1.0\0]
[HKEY_CURRENT_USER\Software\Classes\TypeLib\{TLB-GUID}\1.0\0\win32]
@="E:\\Pfad\\zur\\TLB.tbl"
[HKEY_CURRENT_USER\Software\Classes\TypeLib\{TLB-GUID}\1.0\FLAGS] 
@="0"

TLB-GUID steht für die GUID der TLB (im OLEViewer unter File\View TypeLib auffindbar) und die Versionsnummern (1.0 etc.) sollten mit denjenigen Versionsnummern übereinstimmen, die man der DLL in der IDE zuweist.

9) Das durch diese Schritte entstandene Registry-File muss nun nur noch ausgeführt werden und dann ist die DLL im COM-System registriert.

10) Die Überprüfung, ob alles geklappt hat, kann auf folgende Arten vorgenommen werden:

  • Mit regedit nachschauen, ob alle relevanten Einträge in der Registry auch wirklich vorgenommen wurden.
  • Im OLEViewer nachschauen, ob alle Klassen in den richtigen Kategorien auftauchen.
  • In ArcGIS kontrollieren, ob die Komponenten an den richtigen Orten auftauchen.

Diese Vorgehensweise ist sicherlich nicht gerade unkompliziert oder elegant, aber sie in der aktuellen Konfiguration doch die simpelste Lösung!

Nützliche Tools:

  • OLE Viewer: ein sehr nützliches Werkzeug zur Betrachtung des COM-Systems.
  • GUID-Tool: erzeugt eindeutige GUID (Teil der ArcGIS-Installation oder in Visual Studio enthalten).
  • Ildasm: zeigt den Inhalt von .NET Assemblies an.
  • .NET Reflector: bietet eine ganze Reihe von Betrachtungs- und Analysefunktionen für das .NET-Framework.
  • SharpDevelop: eine Open Source-IDE für das .NET-Framework. SharpDevelop wurde selber auf dem .NET-Framework implementiert.

Nützliche Dokumentationen:

Leave a Reply

  

  

  

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>