Per Mausklick bewerten und Feedback geben
MSDN
MSDN Library
Entwicklerbibliothek
 Weitergabe von verwalteten COM-Add-...
Weitergabe von verwalteten COM-Add-Ins in Office XP
Veröffentlicht: 18. Nov 2002 | Aktualisiert: 21. Jun 2004
Von Misha Shneerson und Siew-Moi Khor

In diesem Artikel wird die Installation und Weitergabe von verwalteten COM-Add-Ins in Office XP erläutert.

Auf dieser Seite

Einführung Einführung
Konzepte und Terminologie Konzepte und Terminologie
Sicherheit in Office XP Sicherheit in Office XP
Unterscheidungsmerkmale von verwaltetem Code Unterscheidungsmerkmale von verwaltetem Code
Die Projektmappe: Eine dedizierte, nicht verwaltete Shimkomponente Die Projektmappe: Eine dedizierte, nicht verwaltete Shimkomponente
Implementieren von Proxyobjekten Implementieren von Proxyobjekten
Testanleitung für die Projektmappe Testanleitung für die Projektmappe
Weitergabe der Projektmappe Weitergabe der Projektmappe
Nächste Schritte Nächste Schritte

Einführung

Durch die Bereitstellung der COM-Interop-Schicht und der COM-Interop-Tools hat Microsoft erreicht, dass der Übergang von Anwendungen der COM-Technologie zur .NET-Technologie so nahtlos wie möglich erfolgt. Dabei lassen sich (nicht verwaltete) COM-Schnittstellen in .NET (verwalteter Code) implementieren. Diese Implementierungen können transparent von COM-basierten Clients aus verwendet werden.

Wenn Sie benutzerdefinierte verwaltete COM-Add-Ins in Microsoft® Office XP erstellen, gibt es drei Schnittstellen, die für Sie von besonderem Interesse sein dürften: IDTExtensibility2, IsmartTagRecognizer und ISmartTagAction. Die IDTExtensibility2-Schnittstelle wird bei der Erstellung benutzerdefinierter COM-Add-Ins implementiert und die ISmartTagRecognizer- und ISmartTagAction-Schnittstellen werden bei der Erstellung von benutzerdefinierten Smarttag-COM-Add-Ins implementiert.

Wenn keine andere Angabe erfolgt, werden mit dem Begriff COM-Add-In solche COM-Add-Ins bezeichnet, die die IDTExtensibility2-, IsmartTagRecognizer- oder ISmartTagAction-Schnittstelle implementieren. Sobald eine deutliche Unterscheidung zwischen Smarttag-COM-Add-Ins und COM-Add-Ins erfolgt, die nur die IDTExtensibility2-Schnittstelle implementieren, wird dies aus dem Kontext ersichtlich sein.

Wenn ein verwaltetes COM-Add-In mit dem regasm-Dienstprogramm ("Register Assembly") weitergegeben wird und die Sicherheit in einer Office XP-Anwendung auf Mittel eingestellt ist, wobei die Option Allen installierten Add-Ins und Vorlagen vertrauen deaktiviert ist, werden Benutzer beim Starten der Anwendung aufgefordert, das COM-Add-In entweder zu aktivieren oder zu deaktivieren. Wenn jedoch die Sicherheitsstufe auf Hoch eingestellt ist, und die Option Allen installierten Add-Ins und Vorlagen vertrauen deaktiviert ist, wird das verwaltete COM-Add-In nicht geladen, selbst wenn es signiert ist. (Wenn Ihnen die Sicherheitseinstellungen in Office XP nicht vertraut sind, finden Sie weitere Informationen in Tabelle 1 weiter unten).

Dies entspricht nicht der erwarteten Funktionsweise im Zusammenhang mit den Sicherheitseinstellungen in Office XP. Und dies ist in der Tat so, falls es sich bei dem installierten COM-Add-In um ein nicht verwaltetes COM-Add-In handelt. Für eine korrekte Weitergabe von verwalteten COM-Add-Ins müssen Entwickler jedoch einen zusätzlichen Schritt ausführen, um Konformität mit dem Office-Sicherheitsmodell zu gewährleisten. Eine korrekte Weitergabe von verwalteten COM-Add-Ins bedeutet, dass die verwalteten COM-Add-Ins digital signiert und die Sicherheitseinstellungen in Office XP auf die höchste Stufe eingestellt sind.

Die Installation und Weitergabe von verwalteten COM-Add-Ins setzt spezielle Überlegungen und Vorgehensweisen in puncto Sicherheit voraus. Um eine erfolgreiche Weitergabe digital signierter verwalteter COM-Add-Ins zu gewährleisten, müssen Sie in Ihr verwaltetes COM-Add-In-Projekt ein kleines, nicht verwaltetes Proxy einfügen, das als Shim bezeichnet wird.

In diesem Artikel wird erläutert, warum ein Shim benötigt wird, und wie eine Shim-Projektmappe funktioniert. Die Verwendung der Shim-Projektmappe wird in zwei nachfolgenden schrittweisen Lernprogrammen erläutert, eines für verwaltete Smarttag-COM-Add-Ins und ein weiteres für generische verwaltete COM-Add-Ins:

Diese schrittweisen Lernprogramme enthalten die downloadbare Shim-Projektmappenvorlage.

Es wird vorausgesetzt, dass die Leser mit der Microsoft .NET-Technologie vertraut und in der Lage sind, ein verwaltetes COM-Add-In mit Microsoft Visual Studio® .NET zu erstellen. Weiterhin wird vorausgesetzt, dass die Leser über Kenntnisse in der Bedeutung und Durchführung von Codesignaturen verfügen. Wenn dies nicht der Fall ist, gibt es eine Vielzahl hervorragender Artikel zu diesem Thema unter MSDN, auf die am Ende dieses Artikels verwiesen wird.

Konzepte und Terminologie

Vor einer eingehenden Behandlung dieses Themas werden im Anschluss einige Konzepte und Terminologiebegriffe erläutert. Ein Verständnis dieser Konzepte dürfte sich als sehr hilfreich erweisen, um die Sicherheitsaspekte in Bezug auf verwaltete COM-Add-Ins vollständig zu begreifen. Diese Konzepte werden logisch dargestellt. Falls Sie mit diesen jedoch bereits vertraut sind, können Sie diesen Abschnitt überspringen. Ausführliche Informationen zu diesen Konzepten finden Sie in den Artikeln, die im Referenzabschnitt am Ende dieses Artikels aufgelistet sind.

Assembly, Microsoft Intermediate Language (MSIL) und Common Language Runtime (CLR)
Eine Assembly entspricht einer COM-Dynamic Link Library (DLL) oder einer ausführbaren Datei (EXE). Es handelt sich um eine logische Einheit, in der kompilierter Code für .NET gespeichert ist. Bei der Kompilierung eines Microsoft Visual Basic® .NET- oder Microsoft Visual C#T-Klassenbibliothekprojekts wird eine Assembly mit MSIL-Code (Microsoft Intermediate Language) generiert. Die Ausführung des MSIL-Codes wird von der Common Language Runtime erledigt. Die Common Language Runtime unterscheidet sich von anderen Ausführungsumgebungen, denn sie kompiliert die MSIL in Computercode, um eine optimale Leistung zu erreichen. Der Computercode wird dann ohne den erheblichen Overhead eines Interpreters ausgeführt.

Digitale Signatur
Mithilfe von digitalen Signaturen kann überprüft werden, ob eine Assembly modifiziert wurde. Bei der Überprüfung digitaler Signaturen werden kryptografische Protokolle und Verfahren auf Basis öffentlicher Schlüssel verwendet. Eine Beschreibung der Kryptografie mit öffentlichen Schlüsseln übersteigt den Rahmen dieses Artikels.

Von besonderem Interesse in Bezug auf digitale Signaturen sind jedoch zwei sehr große Zahlen, die als die "öffentlichen und privaten Schlüsselpaare" bezeichnet werden. Die Schlüssel ergänzen sich gegenseitig, indem Daten, die mit dem privaten Schlüssel signiert wurden, nur erfolgreich mit dem entsprechenden öffentlichen Schlüssel überprüft werden können. In der Regel verwenden Softwareherausgeber private Schlüssel zum Signieren der Assembly, bevor sie diese über ein Netzwerk an die Öffentlichkeit weitergeben. Der öffentliche Schlüssel wird an die Assembly angehängt. Bevor die Assembly ausgeführt werden darf, überprüft die Common Language Runtime, ob die Datenintegrität der Assembly gefährdet wurde. Falls die Assembly geändert wurde, kann die digitale Signatur nicht mit dem öffentlichen Schlüssel überprüft werden. Folglich wird der Assembly keine Ausführung gestattet. Die Assembly wird nur dann geladen und kann ausgeführt werden, wenn die Überprüfung erfolgreich war.

Strong Name und Microsoft Authenticode
Zur Gewährleistung der Datenintegrität und Authentizität einer Assembly werden Strong Names verwendet. Strong Names werden mit dem Strong Name-Dienstprogramm unter Verwendung öffentlicher Schlüsselkryptografie erstellt. Strong Names stellen sicher, dass freigegebene Assemblys über global eindeutige Namen verfügen. Ein Strong Name besteht aus einem einfachen Assemblynamen in Textform, der Versionsnummer, Kulturinformationen, einem öffentlichen Schlüssel und der digitalen Signatur.

Strong Names und Microsoft Authenticode® dienen unterschiedlichen Zwecken. Authenticode, das auch Kryptografieprotokolle auf Basis öffentlicher Schlüssel für die Datenintegrität verwendet, geht viel weiter. Hierbei kommt ebenfalls ein hierarchisches System vertrauenswürdiger Stellen zum Einsatz, um zu überprüfen, ob vermeintliche Softwareherausgeber einer Datei auch authentisch sind. Insbesondere impliziert Authenticode ein gewisses Maß an Vertrauen für einen Softwareherausgeber, was bei Strong Names nicht der Fall ist.

Strong Names sind ein fester Bestandteil des Inhalts und Erstellungsprozesses einer Assembly. Jede Assembly mit einem Strong Name referenziert andere Assemblys mit ihrem jeweiligen Strong Name. Dadurch wird sichergestellt, dass die Assembly zur Laufzeit nur diejenigen Assemblys verwendet, mit denen sie verknüpft war, wodurch DLL-Konflikte gelöst werden. Andererseits wird die Authenticode-Signatur im PE-Header (Portable Executable) einer Assembly gespeichert und wird häufig zusätzlich zu den Strong Names verwendet, um die Vertrauenwürdigkeit einer Assembly festzustellen. Aus diesem Grund muss eine Assembly auch mit einem Strong Name versehen werden, bevor sie mit Authenticode signiert wird.

.NET-Sicherheit
Die .NET-Sicherheit ist ein äußerst umfangreiches und faszinierendes Thema. Jedoch würde eine Besprechung den Rahmen dieses Artikels sprengen. Weitere Informationen zur .NET-Sicherheit finden Sie im Artikel An Overview of Security in the .NET Framework.

Es gibt jedoch ein paar Aspekte, die trotzdem angesprochen werden müssen. Beim Laden einer Assembly werden dieser eine Reihe von Berechtigungen zugewiesen. Wenn einer Assembly die maximale Anzahl an Berechtigungen gewährt wird, wird dieser Ausführungsmodus als "voll vertrauenswürdig" bezeichnet. Dabei kann diese jede gewünschte Operation ausführen. Einigen Assemblys werden eventuell bestimmte Berechtigungen nicht gewährt, weshalb diese z.B. keine Eingabe-/Ausgabeoperationen durchführen oder keinen nicht verwalteten Code ausführen können.

Der Vorgang der Berechtigungszuweisung wird von der Common Language Runtime-Sicherheitsrichtlinie eines Computers kontrolliert. (Diese wird mit den Standardeinstellungen ausgeführt, es sei denn, es wurde eine Neukonfiguration von einem Benutzer oder einem Sicherheitsrichtlinienadministrator einer Organisation durchgeführt.)

Sicherheit in Office XP

Viele sicherheitsbewusste Benutzer und Administratoren stellen die Sicherheitsstufe in Microsoft Office XP auf Hoch ein. Die Standardeinstellung Allen installierten Add-Ins und Vorlagen vertrauen ist jedoch deaktiviert, was äußerst empfehlenswert ist. Mit dieser speziellen Einstellung werden automatisch alle Add-Ins und Vorlagen deaktiviert, für die keine Codesignatur durchgeführt wurde. Falls die Add-Ins und Vorlagen zwar über eine Codesignatur verfügen, aber ein Zertifikat nicht in der Liste Vertrauenswürdige Quellen aufgelistet ist, erhalten Benutzer eine Aufforderung, die Add-Ins oder Vorlagen entweder zu aktivieren oder zu deaktivieren.

Tabelle 1. Office XP-Sicherheitseinstellungen

Sicherheitsstufe

Allen installierten Add-Ins und Vorlagen vertrauen

Digital signiert

Aus vertrauenswürdigen Quellen

Office XP führt folgende Aufgaben aus:

Hoch

Deaktiviert

Ja

Ja

Automatisches Laden des Add-Ins/Makros

Hoch

Deaktiviert

Ja

Nein

Auffordern zum Aktivieren/Deaktivieren des Add-Ins/Makros

Hoch

Deaktiviert

Nein

N/V

Kein Laden des Add-Ins/Makros

Mittel

Deaktiviert

Ja

Ja

Automatisches Laden des Add-Ins/Makros

Mittel

Deaktiviert

Ja

Nein

Auffordern zum Aktivieren/Deaktivieren des Add-Ins/Makros

Mittel

Deaktiviert

Nein

N/V

Auffordern zum Aktivieren/Deaktivieren des Add-Ins/Makros

Niedrig

Deaktiviert

Ja/Nein

Ja/Nein

Automatisches Laden des Add-Ins/Makros

Hoch, Mittel oder Niedrig

Aktiviert

Ja/Nein

Ja/Nein

Automatisches Laden des Add-Ins/Makros

Anmerkung: Um die Sicherheitseinstellung in einer Office XP-Anwendung zu überprüfen, klicken Sie auf Extras, zeigen Sie auf Makro und klicken Sie anschließend auf Sicherheit. Dadurch wird das Dialogfeld Sicherheit angezeigt.

Wie aus dem vorangegangenen Absatz und der Tabelle 1 ersichtlich ist, funktioniert die Sicherheit in Office XP auf Vertrauensbasis. Add-Ins und Vorlagen dürfen nur ausgeführt werden, wenn diesen vertraut wird. Das heißt wenn diese von vertrauenswürdigen Quellen veröffentlicht wurden, oder falls sich Benutzer für die Option Allen installierten Add-Ins und Vorlagen vertrauen entschieden haben.

Das Vertrauenskonzept ist zunächst einmal subjektiv. Die Benutzer entscheiden, ob sie dem Code vertrauen möchten, der von einer bestimmten Quelle veröffentlicht wurde. Objektiv daran ist die Identität des Softwareherausgebers und das Zertifikat, das vom Softwareherausgeber zum Signieren der Codedatei verwendet wurde. Office XP-Komponenten müssen Authenticode zum Signieren ihrer Codedateien verwenden, damit Benutzer von Codedateien die Identität des Softwareherausgebers überprüfen können.

Bei Office-COM Add-Ins handelt es sich um COM-Komponenten, die in systemeigenen DLL-Dateien enthalten sind. Beim Registrieren einer COM-Komponente werden einige Informationen darüber in die Registrierung geschrieben. Insbesondere verfügen alle COM-Komponenten (oder COM-Klassen) über eine global eindeutige Identität, die als Klassen-ID (CLSID) bezeichnet wird. Alle CLSIDs sind in der Registrierung unter HKEY_CLASSES_ROOT\CLSID gruppiert und verfügen über das folgende Format {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX}, wobei 'X' eine Hexadezimalzahl ist. Unterhalb des CLSID-Schlüssels gibt es mehrere verschachtelte Registrierungsunterschlüssel. Einer der Unterschlüssel ist InprocServer32, dessen Standardwert den vollständigen Pfad zu einer DLL-Datei enthält, wie im Registrierungslayout des CLSID-Schlüssels in Abbildung 1 gezeigt.

Dabei handelt es sich um die DLL, die die COM-Klasse enthält (oder Zugriff darauf bietet), diese ist mit der CLSID verknüpft. In Übereinstimmung mit dem Office-Sicherheitsmodell handelt es sich auch um die Klasse, die mit Authenticode signiert werden muss. Da Klassen nicht mit digitalen Signaturen signiert werden können, wird ihr unmittelbarer Container signiert, das heißt die DLL-Datei.

Bild01

Abbildung 1. CLSID-Einträge des "InprocServer"-Schlüssels für eine COM-Klasse mit nicht verwaltetem Code

Unterscheidungsmerkmale von verwaltetem Code

Verwalteter Code ist deshalb unterschiedlich, weil seine Ausführung von der Common Language Runtime verwaltet wird. Aus diesem Grund scheitert die Ausführung von COM-Serveraufrufen, falls der DLL-Pfad in Abbildung 1 direkt auf den Speicherort einer Assembly zeigt. Wie bereits im Abschnitt Assembly, Microsoft Intermediate Language (MSIL) und Common Language Runtime (CLR) erläutert, muss die Assemby im MSIL-Code von der Common Language Runtime ausgeführt werden. Deshalb ist es notwendig, dass die Ausführungsumgebung, also die Common Language Runtime, gestartet wird.

Dies wird durch Festlegung einer speziellen DLL mit der Bezeichnung mscoree.dll als Standardwert von InprocServer32 erreicht. Zur Registrierung einer Assembly für die COM-Interop-Operation wird das Dienstprogramm RegAsm.exe ("Register Assembly") verwendet. Dieses Dienstprogramm registriert Typinformationen von .NET-Komponenten in der Systemregistrierung, damit COM-Clients darauf zugreifen können und die verwalteten Komponenten für die nicht verwaltete COM-Umgebung zur Verfügung gestellt werden.

Alternativ dazu können Sie die Eigenschaft Für COM-Interop registrieren auf der Seite Erstellen der Projekteigenschaften auf TRUE setzen, bevor Sie die Assembly kompilieren. Weitere Informationen über RegAsm.exe finden Sie unter Registering Assemblies with COM.

Der interessanteste Teil ist der Standardwert für den InprocServer32-Schlüssel (siehe Abbildung 2). Anstatt auf den Pfad der DLL-Datei mit verwaltetem Code zeigt dieser auf die mscoree.dll, den Haupteinstiegspunkt der Common Language Runtime-Engine. (Der Schlüssel InProcServer32 wird vorher mit dem RegAsm.exe-Dienstprogramm erstellt. Der Standardwert ist auf mscoree.dll eingestellt.)

Bild02

Abbildung 2. CLSID-Einträge des "InprocServer"-Schlüssels für eine COM-Klasse mit verwaltetem Code, die über COM-Interop offen gelegt wird.

Die Signierung einer Assembly mit Auhenticode funktioniert aus folgendem Grund nicht: Da der InprocServer32-Schlüssel auf mscoree.dll zeigt, untersucht Office XP mscoree.dll auf Signatur und nicht die Assembly an sich. Bei Mscoree.dll handelt es sich jedoch um eine Systemkomponente, die nicht signiert ist. Wenn daher die Office XP-Sicherheit auf Hoch eingestellt und die Option Allen installierten Add-Ins und Vorlagen vertrauen deaktiviert ist, wird die Datei mscoree.dll nicht geladen.

Die Projektmappe: Eine dedizierte, nicht verwaltete Shimkomponente

Eine mögliche Lösung wäre die Erstellung einer DLL aus nicht verwaltetem Code, die über alle Funktionen der Common Language Runtime-Engine verfügt, aber nur auf das Laden einer bestimmten Assembly beschränkt ist: Dem COM-Add-In aus verwaltetem Code. Auf die gleiche Art und Weise, wie RegAsm.exe die Datei mscoree.dll dazwischen platziert, ist es möglich, Ihre eigene Komponente so zu platzieren, dass der Wert von InprocServer32 auf Ihre DLL zeigt.
Eine nicht verwaltete Komponente kann die Common Language Runtime in ihrem Adressraum enthalten, wie dies ausführlich unter Microsoft .NET: Implement a Custom Common Language Runtime Host for Your Managed App beschrieben ist.

Indem Sie sicherstellen, dass die Hostanwendung die Gültigkeit von Assemblys überprüfen kann, die in ihren Adressraum geladen werden, können Sie der Office XP-Sicherheitsanforderung gerecht werden, wonach DLLs signiert sein müssen. Auf diese Weise wird die Sicherheit des Computers eines Benutzers nicht gefährdet. Bei dieser speziellen Komponente, die wir als "Shim" bezeichnen, handelt es sich um eine nicht verwaltete Komponente, die als Proxy fungiert.

Im Anschluss erhalten Sie eine kurze Übersicht über die Vorgehensweise:

  1. Integrieren der Shim-DLL in das verwaltete COM-Add-In mit Visual Studio .NET.

  2. Signieren der Shim-DLL.

  3. Registrieren der signierten Shim-DLL mit Regsvr32.

  4. Bei der ersten Instantiierung der COM-Klassen innerhalb einer Office XP-Anwendung treten die folgenden Ereignisse auf:

    • Die Common Language Runtime wird innerhalb der Shim-DLL mithilfe einer Hostschnittstelle gestartet.

    • Eine Anwendungsdomäne (diese entspricht Prozessen in einer nicht verwalteten Umgebung) wird erstellt, die die COM-Add-In-Assembly ausführt.

    • Die Assembly wird dann in die oben genannte Domäne geladen.

    • Instanzen verwalteter COM-Add-In-Klassen werden erstellt, und Zeiger auf diese Schnittstellen werden zwischengespeichert.

    • Alle Aufrufe der nicht verwalteten Klassen werden an ihre verwalteten Entsprechungen mithilfe von zwischengespeicherten Zeigern umgeleitet.

Da die Shim-DLL selbst mit Authenticode signiert wird, gestattet Office XP das Laden der Shim-DLL in den Adressraum. Achtung: Wenn Komponenten "dazwischen" platziert werden und dies nicht korrekt erfolgt, schaffen Sie damit mögliche andere Bereiche für Sicherheitsangriffe. Deshalb ist es äußerst wichtig, dass Sicherheitsvorkehrungen getroffen werden, damit die Pfade zu Ihren Komponenten korrekt sind und nicht gefälscht werden können.
Vor allem ist es wichtig zu verstehen, dass das Shim dafür verantwortlich ist, die Ausführung nicht vertrauenswürdiger Assemblys zu verhindern. Glücklicherweise kann die Authentizität der zu ladenden Assembly sichergestellt werden, indem Sie den Strong Name der Assembly und vor allem ihren öffentlichen Schlüsseltoken angegeben und gleichzeitig den entsprechenden privaten Schlüssel geheim halten.

Implementieren von Proxyobjekten

Im Anschluss wird beschrieben, wie ein Shim als Host eines verwalteten COM-Add-Ins implementiert wird. Das Shim wird in nicht verwaltetem Microsoft Visual C++®-Code in der Visual Studio .NET-IDE implementiert. Visual Basic-Entwickler stellen sich eventuell die Frage, ob das Shim in Microsoft Visual Basic 6.0 implementiert werden kann. Die Antwort lautet derzeit nein. Einer der Gründe besteht darin, dass das nicht verwaltete Shim-COM-Add-In in derselben Entwicklungsumgebung sein muss wie die verwaltete COM-Add-In-Assembly. Sie können zwar ein nicht verwaltetes Visual C++-Projekt in Visual Studio .NET entwickeln, nicht jedoch ein nicht verwaltetes Visual Basic 6-Projekt. Außerdem ist Visual C++-Code in der Lage, die Common Language Runtime zu laden, während dies in Visual Basic nicht möglich ist.

Visual Basic-Entwickler, die nicht mit C++ und der Active Template Library (ATL) vertraut sind, brauchen trotzdem nicht zu resignieren. Es liegen zwei separate fertige Projektmappen zum Download bereit Eine Mappe für das Hosting generischer verwalteter COM-Add-Ins für Office XP und eine weitere speziell für verwaltete Smarttags. Sie brauchen also keine eigene zu erstellen.

Im Anschluss erfolgt eine technische Erklärung der Shim-Projektmappe. Diese ist relativ unkompliziert, auch wenn Sie nicht mit Visual C++- und ATL-Begriffen vertraut sind. Von großer Bedeutung ist auch die Testanleitung weiter unten im Artikel.

Die Entwicklung eines Shim für ein Office-COM-Add-In ist der Art und Weise sehr ähnlich, wie ein Smarttag-Shim implementiert wird. Zur besseren Erklärung werden sowohl die generischen COM-Add-Ins als auch die Smarttag-Shim-Projektmappen verwendet.

Bei dem COM-Add-In handelt es sich um ein einfaches ATL-Projekt mit einer Proxyklasse, das die IDTExtensibility2-Schnittstelle implementiert. Um die Projektmappe in Visual Studio .NET anzuzeigen, klicken Sie auf die Datei COMAddinShim.sln, die sich im Ordner COMAddInShim des Downloads befindet, der zu diesem Artikel gehört. Bei dem Smarttag-Shim handelt es sich um ein einfaches ATL-Projekt mit zwei Proxyklassen, die die ISmartTagRecognizer- und ISmartTagAction-Schnittstellen implementieren. Um die Projektmappe in Visual Studio .NET anzuzeigen, klicken Sie auf die Datei SmartTagShim.sln, die sich im Ordner SmartTagShim befindet.

Werfen wir zunächst einen Blick auf die FinalConstruct()-Methode. (Um für das COMAddinShim-Projekt die FinalConstruct()-Methode anzuzeigen, öffnen Sie die ConnectProxy.cpp-Datei. Für das SmartTagShim-Projekt öffnen Sie die Datei STRecognizerProxy.cpp oder STActionProxy.cpp.)

Die FinalConstruct()-Methode wird bei jeder Instantiierung der enthaltenen Klasse aufgerufen. Die FinalConstruct()-Methode der einzelnen COM-Add-Ins und Smarttag-Klassen verwendet die nicht verwaltete API, um eine Instanz einer entsprechenden verwalteten Komponente zu erstellen.

Im Anschluss sehen Sie einen Codeausschnitt aus der Datei ConnectProxy.cpp, der diesen Vorgang illustriert:

HRESULT CConnectProxy::FinalConstruct()
{
    HRESULT hr = S_OK;
    CCLRLoader *pCLRLoader = CCLRLoader::TheInstance();
    IfNullGo(pCLRLoader);
    IfFailGo(pCLRLoader->CreateInstance(AssemblyName(),
                                        ConnectClassName(),
                                        __uuidof(IDTExtensibility2),
                                        (void **)&m_pConnect));
Error:
    return hr;
}

Der entsprechende Codeausschnitt aus der Datei STRecognizerProxy.cpp folgt im Anschluss:

HRESULT CSmartTagRecognizerShimProxy::FinalConstruct()
{
    HRESULT hr = S_OK;
    CCLRLoader *pCLRLoader = CCLRLoader::TheInstance();
    IfNullGo(pCLRLoader);
    IfFailGo(pCLRLoader->CreateInstance(AssemblyName(),
                                        RecognizerClassName(),
                                        __uuidof(ISmartTagRecognizer),
                                        (void **)&m_pISTRecognizer));
Error:
    return hr;
}

Der Code ist sehr einfach aufgebaut. Der Großteil der Arbeit passiert innerhalb der Klasse mit der Bezeichnung CCLRLoader. Bei der Klasse CCLRLoader handelt es sich um eine Singleton-Klasse (das heißt, es gibt nur eine Instanz der Klasse mit einem globalen Zugriffspunkt), die gestartet wird und die gesamte Kommunikation mit der Common Language Runtime erledigt. (Die detaillierte Implementierung von CCLRLoader würde den Rahmen dieses Artikels sprengen.)

Die CCLRLoader::CreateInstance()-Methode dient zur Erstellung einer Instanz der verwalteten Klasse. Sie entspricht in etwa der Funktionsweise von CoCreateInstance() bei der COM-Technologie. Die CCLRLoader::CreateInstance()-Methode akzeptiert die folgenden Parameter:

  • Den Namen der Assembly, die die Klasse enthält.

  • Den vollständigen Namen der zu instantiierenden Klasse.

  • Den Verweis auf den Bezeichner der Schnittstelle.

  • Die Adresse der Ausgabevariable, die den Schnittstellenzeiger empfängt.

Die Werte der ersten beiden Parameter werden von den Funktionen aus dem ShimConfig-Namespace zurückgegeben (siehe die ShimConfig.cpp-Datei). Dieser Namespace enthält die Funktionen, die den Namen der Zielassembly definieren, sowie den Namen der zu instantiierenden verwalteten Klasse, wie dies aus dem nachfolgenden Codeausschnitt aus dem COMAddInShim-Projekt ersichtlich ist:

static LPCWSTR szAddInAssemblyName = 
     L"ManagedAddIn, PublicKeyToken=6c96c7507b8e2be8";
static LPCWSTR szConnectClassName = L"ManagedAddIn.Connect";
LPCWSTR ShimConfig::AssemblyName()
{
    return szAddInAssemblyName;
}
LPCWSTR ShimConfig::ConnectClassName()
{
    return szConnectClassName;
}

Im Anschluss folgt der entsprechende Codeausschnitt aus der ShimConfig.cpp-Datei des SmartTagShim-Projekts:

static LPCWSTR szSmartTagsAssemblyName =
    L"HelloSmartTag, PublicKeyToken=6c96c7507b8e2be8";
static LPCWSTR szRecognizerClassName = L"HelloSmartTag.STRecognizer";
static LPCWSTR szActionClassName = L"HelloSmartTag.STAction";
LPCWSTR ShimConfig::AssemblyName()
{
    return szSmartTagsAssemblyName;
}
LPCWSTR ShimConfig::RecognizerClassName()
{
    return szRecognizerClassName;
}
LPCWSTR ShimConfig::ActionClassName()
{
    return szActionClassName;
}

Die Funktionen geben Werte zurück, die im oberen Teil des Codes angegeben werden. Beachten Sie, dass der Pfad zur verwalteten Assembly nicht angegeben ist, sondern nur sein Name. Die Klasse CCLRLoader setzt voraus, dass sich die verwaltete Assembly in demselben Verzeichnis wie die Shim-DLL befindet.

Die AssemblyName()-Funktion gibt den Strong Name der Assembly zurück. Im COM-Add-In-Codeausschnitt weiter oben ist dies "ManagedAddIn, PublicKeyToken=6c96c7507b8e2be8".

Der Strong Name gibt hier nur den öffentlichen Schlüsseltoken zurück, das heißt das Hash des öffentlichen Schlüssels. Es ist weiterhin möglich, Versions- und Kulturinformationen anzugeben, falls für diese eine Übereinstimmung wichtig ist.

Der öffentliche Schlüsseltoken spielt eine wichtige Rolle dabei, dass das Laden einer gefährdeten Assembly verhindert wird. Da Angreifer den entsprechenden privaten Schlüssel nicht kennen, sind diese nicht in der Lage, eine Assembly korrekt zu signieren, die Ihre Assembly ersetzen soll. Falls also eine Assembly geändert wurde, schlägt die Überprüfung fehl und die Assembly kann nicht ausgeführt werden. Die Angabe eines öffentlichen Schlüsseltokens sollte daher niemals weggelassen werden, da dies Sicherheitslücken in Ihrer Software erzeugen kann. Weitere Informationen zur Vergabe eines Strong Name für Ihre Assembly finden Sie in den spezifischen Anweisungen für Ihren Projekttyp. Derzeit sind diese für C#- und Visual Basic .NET-Projekte unterschiedlich.

Die Implementierung für die Schnittstellenmethoden CConnectProxy() und CSmartTagRecognizerShimProxy (siehe ConnectProxy.h und die entsprechenden STRecognizerProxy.h- und STActionProxy.h-Headerdateien) ist relativ unkompliziert, sobald ein Schnittstellenzeiger vorhanden ist. Dieser leitet die Aufrufe an die enthaltene Instanz einer verwalteten Klasse um. Im Anschluss sehen Sie den Codeausschnitt aus der ConnectProxy.h-Headerdatei des COMAddInShim-Projekts:

class ATL_NO_VTABLE CConnectProxy :
{
...
public:
    //IDTExtensibility2-Implementierung:
    STDMETHOD(OnConnection)(IDispatch * Application, 
      AddInDesignerObjects::ext_ConnectMode ConnectMode, IDispatch 
      *AddInInst, SAFEARRAY **custom)
    {
        return m_pConnect->OnConnection(Application, ConnectMode, 
          AddInInst, custom);
    }
    STDMETHOD(OnBeginShutdown)(SAFEARRAY **custom )
    {
        return m_pConnect->OnBeginShutdown(custom);
    }
protected:
    // speichert Zeiger auf verwaltetes Add-In zwischen
    AddInDesignerObjects::IDTExtensibility2 *m_pConnect;
};
OBJECT_ENTRY_AUTO(__uuidof(ConnectProxy), CConnectProxy)

Der entsprechende Codeausschnitt aus der STRecognizerProxy.h-Headerdatei folgt im Anschluss:

class ATL_NO_VTABLE CSmartTagRecognizerShimProxy :
{
    // ISmartTagRecognizer-Methoden
public:
    STDMETHOD(get_ProgId)(BSTR * ProgId)
    {
        return m_pISTRecognizer->get_ProgId(ProgId);
    }
    STDMETHOD(Recognize)(BSTR Text, IF_TYPE DataType, int LocaleID,
      ISmartTagRecognizerSite * RecognizerSite)
    {
        return m_pISTRecognizer->Recognize(Text, DataType, LocaleID,
          RecognizerSite);
    }
protected:
    // speichert Zeiger auf verwalteten SmartTagRecognizer zwischen
    ISmartTagRecognizer *m_pISTRecognizer;
};

Ein fast identischer Code wird zum Laden der Aktionsklasse des verwalteten Smarttags verwendet. Der dazugehörige Codedownload verfügt über umfassende Kommentare, die jeden nicht selbstverständlichen Schritt des Programms erklären.

Testanleitung für die Projektmappe

Beim Testen der Projektmappe müssen die folgenden Dateien signiert werden:

  • Die Shim-DLL muss mit Authenticode signiert werden.

  • Ihre COM-Add-In-Assembly muss mit einem Strong Name signiert werden.

  • Versehen Sie weitere private Assemblys, von denen die COM-Add-In-Assembly abhängen könnte, ebenfalls mit einem Strong Name.

In den meisten Organisationen sind die privaten Schlüssel für das Signieren einer nicht verwalteten Komponente nur für autorisierte Mitarbeiter zugänglich. In den meisten Fällen gehören Softwareentwickler dieser Kategorie nicht an. Trotzdem ist es notwendig, dass sie Software im signierten Zustand testen. Dies lässt sich mithilfe von Testzertifikaten erreichen. Ausführliche Informationen zur Erstellung von und Signierung mithilfe von Testzertifikaten finden Sie unter Digital Code Signing Step-by-Step Guide. Dieser Artikel enthält schrittweise Anleitungen und Erklärungen zur Verwendung von Authenticode-Testzertifikaten.

Verzögertes Signieren
Wenn Sie eine Assembly signieren, die mit einem Strong Name versehen werden muss, damit Sie Tests durchführen kann, können Sie jedoch keinen Zugriff auf den privaten Schlüssel Ihrer Organisation haben Die Assembly wied verzögert signieren. Dises verzögerte Signieren ermöglicht das Testen von Assemblys, die mit einem Strong Name versehen werden müssen, wobei das tatsächliche Signieren später nach Abschluss der Entwicklung durchgeführt wird. Der Artikel Delay Signing an Assembly erklärt sehr detailliert verschiedene Aspekte und Lösungen des verzögerten Signierens für Assemblys, die in C# und Visual Basic .NET erstellt wurden.

Um das verzögerte Signieren zu aktivieren, müssen Sie ein spezielles Assemblyattribut mit der Bezeichnung AssemblyDelaySign(true) hinzufügen. Die Wrapperassemblys müssen ebenfalls mit einem Strong Name versehen werden. Dies lässt sich über tlbimp /delaysign /keyfile:PartialKeyPair.snk SourceTypeLibrary realisieren. Der Befehl erstellt eine Assembly für die partielle Signierung.

Der nächste Schritt besteht in der Deaktivierung der Assemblyüberprüfung. Dieser Vorgang muss für COM-Wrapper und für die COM-Add-In-Assembly mit dem sn -Vr-Befehl durchgeführt werden. Der sn -Vr-Befehl akzeptiert eine Assembly, deren Überprüfung Sie überspringen möchten, sowie eine optionale Liste mit Benutzern, die die Überprüfung überspringen können. (Der Befehl kann auch mit einem Platzhalter wie etwa * versehen werden, um alle Assemblys in einem Verzeichnis zu überspringen.) Nachdem der Code getestet wurde und korrekt funktioniert, besteht der nächste Schritt darin, die Assembly an eine autorisierte Stelle weiterzuleiten, die den privaten Schlüssel für eine vollständige Signatur mithilfe des sn -Rc <assembly> <keypaircontainer>-Befehls besitzt. Dieser Schritt wird im Artikel Delay Signing an Assembly sehr ausführlich erläutert.

Aspekte der .NET-Sicherheit - Common Language Runtime-Sicherheitsrichtlinie
Unter der CLR-Standardsicherheitsrichtlinie und in den allgemeinen CLR-Sicherheitsrichtlinienkonfigurationen der meisten Organisationen kann Ihre Assembly mit der Berechtigung Voll vertrauenswürdig ausgeführt werden. In seltenen Fällen ist es jedoch möglich, dass die CLR-Sicherheitsrichtlinie einer Organisation mit geringeren Berechtigungen konfiguriert wurde. In einem solchen Szenario besitzt Ihre Assembly zur Ausführung nicht die Berechtigung Voll vertrauenswürdig. In solchen Fällen ist der Entwickler dafür verantwortlich, die erforderlichen Nachweise zu liefern, damit eine Assembly beim Laden die Berechtigung Voll vertrauenswürdig erhält. Diese Nachweise müssen in die Datei CLRLoader.cpp eingefügt werden.

Weitergabe der Projektmappe

Bei der Weitergabe Ihrer Projektmappe ist es wichtig, zu beachten, dass alle Assemblys und die Shim-DLL in demselben Verzeichnis auf dem Zielcomputer abgelegt werden müssen. Anschließend muss eine Selbstregistrierung des Shim mit regsvr32 durchgeführt werden.

Die einfachste Möglichkeit dafür ist die Verwendung eines Setup- und Weitergabeprojekts von Visual Studio .NET. Sie erstellen dafür ein leeres Setup- und Weitergabeprojekt und fügen anschließend die Ausgabe der COM-Add-In-Assembly und der Shim-DLL ein. Daraufhin wählen Sie die Shim-Projektausgabe aus und ändern die Register-Eigenschaft in vsdrpCOMSelfReg um. Bei der Kompilierung des Setup- und Weitergabeprojekts wird eine .msi-Datei erstellt, die alle Dateien enthält, um eine Veröffentlichung in einer einzelnen Unit zu ermöglichen.

Ausführliche Informationen dafür werden in den schrittweisen Lernprogrammen erläutert:

Nächste Schritte

Es gibt eine Vielzahl von Vorteilen für die Verwendung der Shim-Projektmappe. Hier sind zwei davon:

  • Sie sind in der Lage, die Shim-DLL digital zu signieren und entsprechen somit dem Überprüfungsmechanismus für Sicherheitssignaturen von Office XP. Auf diese Weise können Benutzer Ihrer verwalteten COM-Add-Ins ihre Office-Sicherheitseinstellung auf der höchsten Einstellung belassen.

  • Außerdem verfügen Sie über ein gewisses Maß an Kontrolle darüber, welche Aktionen von der Common Language Runtime durchgeführt werden.

Ausführliche Informationen darüber, wie Sie die Shim-Projektmappe tatsächlich in Ihr verwaltetes COM-Add-In-Projekt integrieren, finden Sie in den schrittweisen Lernprogrammen auf MSDN:

In den Lernprogrammen wird auch gezeigt, wie Sie die im Abschnitt Weitergabe der Projektmappe erwähnte .msi-Datei erstellen. Im Anschluss folgt eine Liste mit Referenzen zum .NET Framework, zur .NET-Sicherheit, zur .NET- und COM-Interop usw.:


© 2009 Microsoft Corporation. Alle Rechte vorbehalten. Nutzungsbedingungen  |  Markenzeichen  |  Informationen zur Datensicherheit
Page view tracker