In diesem Beitrag möchte ich zeigen, wie man Addins für Sparx Systems Enterprise Architect auch ohne Administratorrechte entwickeln und betreiben kann.
Ich selbst entwickle solche Addins immer mal wieder seit nunmehr 20 Jahren und mir war bis gestern nicht klar, dass es möglich ist diese auch ohne Administratorrechte zu entwickeln und zu betreiben. Aber es geht, wenn man weiß wie!
Wie funktionieren Addins für Enterprise Architect?
Die Modellierungsplattform Sparx Systems Enterprise Architect (EA) ist eine in C++ implementierte Windows-Anwendung und basiert auf der Microsoft COM-Technology (Component Object Model). Man kann die Anwendung über selbstgeschriebene Addins um neue Funktionalitäten erweitern. Diese Addins können mit COM, aber auch mit dem damit kompatiblen neueren .NET-Framework entwickelt werden. Das Addin wird dabei als eine Klassenbibliothek (DLL) erstellt und per Registry-Eintrag wird dem EA bekannt gegeben, dass es dieses Addin gibt.
Wenn EA startet, dann wird versucht die DLL zu laden und auszuführen. Das Plugin beginnt zu arbeiten. Dazu ist es allerdings notwendig, dass der EA die DLL auch auf der Festplatte finden kann. Damit dies funktioniert muss man die DLL als „COM-sichtbar“ markieren und bei Betriebssystem registrieren (so genannte „COM-Registrierung“). Zu diesem Zweck gibt es von Microsoft das Werkzeug regasm.exe, das genau diese COM-Registrierung macht.
Nun ist es aber so, dass das Werkzeug regasm.exe die Registrierung nur erfolgreich durchführen kann, wenn man Administratorrechte hat. Zumindest sagt das die Fehlermeldung die man bekommt, wenn man es ohne Administratorrechte ausführt:
C:\work\MDD4All.UserRegistredAddin\MDD4All.UserRegistredAddin\bin\Debug>c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /codebase MDD4All.UserRegistredAddin.dll
Microsoft .NET Framework Assembly Registration Utility 4.8.9032.0
für Microsoft .NET Framework, Version 4.8.9032.0
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.
RegAsm : error RA0000 : Fehler beim Schreiben der Registrierungsinformationen in die Registrierung. Zur Verwendung der ausgewählten Optionen sind Administratorrechte erforderlich. Verwenden Sie einen Administratorbefehl, um diese Aufgaben abzuschließen.
Wie kann man nun dieses Problem lösen?
Dazu muss man verstehen was bei einer COM-Registrierung passiert. Es werden von regasm.exe verschiedene Registry-Einträge erstellt, die die Informationen über die registrierte DLL enthalten, in die Registry geschrieben. Diese werden in den Bereich HKLM (=Computer) abgelegt. Auf diesen Bereich haben allerdings Benutzer ohne Administratorrechte normalerweise keinen schreibenden Zugriff. Daher funktioniert der Befehl auch nicht ohne erhöhte Rechte.
COM-Registrierung ohne Administratorrechte?
Auf der Suche, ob man eine COM-Registrierung auch ohne Administratorrechte machen kann, stößt man darauf, dass es möglich sein soll, die notwendigen Registrierungen statt im Bereich des Computers (HKLM) statt dessen im Bereich des aktuellen Benutzers zu machen (HKEY_CURRENT_USER). Die Anwendungen suchen auch in diesem Bereich nach COM-Registrierungsinformationen.
Um jetzt eine COM-Registrierung in den Bereich des Benutzers zu schreiben anstatt des Computers bietet regasm.exe glücklicherweise die Option /regfile an. Damit werden die Registrierungsschlüssel nicht direkt in die Registry geschrieben, sondern in eine .reg-Datei gespeichert, die man verändern und dann ausführen kann. Es wird so möglich die Ziele der Registrierungsschlüssel manuell zu verändern und die COM-Komponente im Benutzerbereich, den man auch beschreiben darf durchzuführen. Einen guten Hinweis, dass dies dann auch mit Enterprise Architect Addins funktionieren sollte gibt auch die Seite AddInWithoutAdmin · Helmut-Ortmann/EnterpriseArchitect_hoTools Wiki (github.com).
Schritt für Schritt zum EA-Addin ohne notwendige Administratorrechte
Mit dem oben beschriebenen Wissen über die COM-Registrierung kann man nun ein EA-Addin Schritt für Schritt aufsetzen. Die Umgebung sieht dabei folgendermaßen aus:
- Enterprise Architect 32-Bit Version. Installiert unter C:\Program Files (x86)\Sparx Systems\EA\EA.exe
- Visual Studio 2022
- .NET Framework 4.8
- Keine Administratorrechte vorhanden
Man geht nun folgendermaßen vor:
- Visual Studio starten
- Neues Projekt erstellen
- Die
Class1
inEaAddin
umbenennen (im Code und der Datei) - In der Klasse wird ein Anfang für ein Addin programmiert, dass ein Menü anzeigt:
namespace MDD4All.UserRegistredAddin { public class EaAddin { private const string MENU_HEADER = "-&Addin w/o Admin"; private const string MENU_ACTION1 = "&Action 1"; private const string MENU_ACTION2 = "&Action 2"; public object EA_GetMenuItems(EA.Repository repository, string menuLocation, string menuName) { object result = ""; switch (menuName) { case "": result = MENU_HEADER; break; case MENU_HEADER: result = new string[] { MENU_ACTION1, MENU_ACTION2 }; break; } return result; } } }
- Nun muss unter den Projekteigenschaften (Eigenschaften –> Anwendung –> Assemblyinformationen…) die Option „Assembly COM-sichtbar machen“ aktiviert werden.
- Damit das Assembly einen starken Namen (strong name) für die COM-Registrierung bekommt, muss man es außerdem signieren (Eigenschaften –> Signierung).
- Nun das Projekt übersetzen.
- Damit der Enterprise Architect das Addin findet, muss man es in die Registry eintragen (<Namespace>.<Klassenname>):
- Wenn man nun den EA startet, kann das Addin nicht geladen werden, da die COM-Registrierung noch fehlt. Es erscheint im EA als „Error – Missing“:
Die COM-Registrierung
Nun erfolgt die modifizierte COM-Registrierung. Dazu wird im ersten Schritt mit Hilfe der Kommandozeile regasm.exe ausgeführt und eine passende .reg-Datei generiert:
-
C:\work\MDD4All.UserRegistredAddin\MDD4All.UserRegistredAddin\bin\Debug>c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /codebase /regfile MDD4All.UserRegistredAddin.dll
Microsoft .NET Framework Assembly Registration Utility 4.8.9032.0
für Microsoft .NET Framework, Version 4.8.9032.0
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.
Das Registrierungsskript „C:\work\MDD4All.UserRegistredAddin\MDD4All.UserRegistredAddin\bin\Debug\MDD4All.UserRegistredAddin.reg“ wurde generiert.
- Die generierte .-reg-Datei sieht so aus: Sie besteht dabei aus 7 Einträgen. Die ersten beiden definieren die zu registrierende Klasse und vergeben für diese eine eindeutige ID (hier {E961C205-523D-3365-A56E-1B3387E60C82}). Die nachfolgenden 5 Einträge beschreiben dann die DLL und deren Position im Dateisystem des Rechners.
REGEDIT4 [HKEY_CLASSES_ROOT\MDD4All.UserRegistredAddin.EaAddin] @="MDD4All.UserRegistredAddin.EaAddin" [HKEY_CLASSES_ROOT\MDD4All.UserRegistredAddin.EaAddin\CLSID] @="{E961C205-523D-3365-A56E-1B3387E60C82}" [HKEY_CLASSES_ROOT\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}] @="MDD4All.UserRegistredAddin.EaAddin" [HKEY_CLASSES_ROOT\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}\InprocServer32] @="mscoree.dll" "ThreadingModel"="Both" "Class"="MDD4All.UserRegistredAddin.EaAddin" "Assembly"="MDD4All.UserRegistredAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dfd4bdb117292732" "RuntimeVersion"="v4.0.30319" "CodeBase"="file:///C:/work/MDD4All.UserRegistredAddin/MDD4All.UserRegistredAddin/bin/Debug/MDD4All.UserRegistredAddin.dll" [HKEY_CLASSES_ROOT\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}\InprocServer32\1.0.0.0] "Class"="MDD4All.UserRegistredAddin.EaAddin" "Assembly"="MDD4All.UserRegistredAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dfd4bdb117292732" "RuntimeVersion"="v4.0.30319" "CodeBase"="file:///C:/work/MDD4All.UserRegistredAddin/MDD4All.UserRegistredAddin/bin/Debug/MDD4All.UserRegistredAddin.dll" [HKEY_CLASSES_ROOT\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}\ProgId] @="MDD4All.UserRegistredAddin.EaAddin" [HKEY_CLASSES_ROOT\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]
- Nun erfolgt die Ersetzung von HKEY_CLASSES_ROOT durch die entsprechenden Benutzerbereiche innerhalb der Registry.
- Man ersetzt also HKEY_CLASSES_ROOT mit HKEY_CURRENT_USER\Software\Classes
Achtung Falle 32 Bit!
Wenn man die Ersetzung oben macht und dann die Registrierungsdatei ausführt werden die Daten alle in die Registry geschrieben. Leider findet dann der Enterprise Architect immer noch nicht das Addin. 🙁 Dies liegt daran, dass die Klassen auf einem 64 Bit betriebssystem auch für 64 Bit Umgebungen registriert werden. Enterprise Architect ist jedoch in der 32 Bit Version installiert.
In der Registry gibt es für Klassen, die für 32 Bit registriert werden sollen einen eigenen Bereich, der als WOW6432Node bezeichnet wird. Genau dort muss man auch die DLL-Informationen hinterlegen, damit das Addin dann auch gefunden werden kann.
- Es benötigt daher noch folgende Ersetzung in der .reg-Datei: Ersetzen von Classes\CLSID mit Classes\WOW6432Node\CLSID und Speichern
- Es ergibt sich für unser Beispiel folgende .reg-Datei als Resultat:
REGEDIT4 [HKEY_CURRENT_USER\Software\Classes\MDD4All.UserRegistredAddin.EaAddin] @="MDD4All.UserRegistredAddin.EaAddin" [HKEY_CURRENT_USER\Software\Classes\MDD4All.UserRegistredAddin.EaAddin\CLSID] @="{E961C205-523D-3365-A56E-1B3387E60C82}" [HKEY_CURRENT_USER\Software\Classes\WOW6432Node\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}] @="MDD4All.UserRegistredAddin.EaAddin" [HKEY_CURRENT_USER\Software\Classes\WOW6432Node\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}\InprocServer32] @="mscoree.dll" "ThreadingModel"="Both" "Class"="MDD4All.UserRegistredAddin.EaAddin" "Assembly"="MDD4All.UserRegistredAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dfd4bdb117292732" "RuntimeVersion"="v4.0.30319" "CodeBase"="file:///C:/work/MDD4All.UserRegistredAddin/MDD4All.UserRegistredAddin/bin/Debug/MDD4All.UserRegistredAddin.dll" [HKEY_CURRENT_USER\Software\Classes\WOW6432Node\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}\InprocServer32\1.0.0.0] "Class"="MDD4All.UserRegistredAddin.EaAddin" "Assembly"="MDD4All.UserRegistredAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dfd4bdb117292732" "RuntimeVersion"="v4.0.30319" "CodeBase"="file:///C:/work/MDD4All.UserRegistredAddin/MDD4All.UserRegistredAddin/bin/Debug/MDD4All.UserRegistredAddin.dll" [HKEY_CURRENT_USER\Software\Classes\WOW6432Node\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}\ProgId] @="MDD4All.UserRegistredAddin.EaAddin" [HKEY_CURRENT_USER\Software\Classes\WOW6432Node\CLSID\{E961C205-523D-3365-A56E-1B3387E60C82}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]
- Startet man diese .reg-Datei und wendet sie an, dann kann der EA das Addin finden und ausführen:
Debugging funktioniert auch
Man kann nun auch im Visual Studio noch den Debugger aktivieren. Dazu trägt man unter den Projekteigenschaften –> Debuggen den Enterprise Architect als zu startendes externes Programm ein:
Wenn man das Debugging startet kann man nun wie gewohnt Breakpoints setzen und Variablen anschauen.
Fazit
EA-Addins lassen sich durch „Umbiegen“ der COM-Registrierung auch ohne Administratorrechte entwickeln und betreiben. Das Beispiel zeigt, dass 20 Jahre als sicher geglaubtes Wissen sich auch mal als falsch herausstellen kann und es doch Lösungen für Probleme geben kann, die man als so nicht lösbar eingestuft hatte :-).