Ausführen eines dll-basierten com-Objekts außerhalb des SQL Server-Prozesses

Gilt für: Microsoft SQL Server 2005 Standard EditionMicrosoft SQL Server 2005 Developer EditionMicrosoft SQL Server 2005 Enterprise Edition

Zusammenfassung


Microsoft SQL Server 6,5 oder höher bietet die Möglichkeit zum Laden und Ausführen benutzerdefinierter COM-Objekte (Component Object Model) über einen Satz von gespeicherten OLE-Automatisierungs Prozeduren oder über erweiterte gespeicherte Prozeduren. DLL-basierte com-Objekte werden standardmäßig wie in Process Server geladen, was bedeutet, dass die COM-Objekte nicht nur im Speicheradressraum des SQL Server-Prozesses geladen werden, sondern auch Vollzugriff auf diesen Speicheradressraum haben. Daher muss ein im SQL Server-Prozess Speicher geladenes com-Objekt dieselben Regeln wie jede DLL-Datei einhalten. Es besteht die Möglichkeit, dass ein COM-Objekt den Arbeitsspeicher innerhalb des SQL Server-Prozesses überschreiben oder Ressourcen Auslaufen lässt, was zu Instabilität führt. Wenn Sie den Verdacht haben, dass ein COM-Objekt die Robustheit des SQL Server-Prozesses beeinflussen kann, sollten Sie die Schritte in diesem Artikel zum Instanziieren des COM-Objekts außerhalb des SQL Server-Prozessbereichs verwenden. Die Implementierung der DCOM-Spezifikation (Distributed Component Object Model) von "Standorttransparenz" in das Betriebssystem bietet die Möglichkeit, ein dll-basiertes com-Objekt außerhalb des SQL Server-Prozessbereichs auszuführen. Der Prozess, bei dem ein dll-basiertes com-Objekt außerhalb des Adressraums der Hauptanwendung ausgeführt wird, wird als Remoting bezeichnet. Für Remoting muss eine andere ausführbare Datei anstelle der ausführbaren Datei von SQL Server ein Ersatzprozess sein. Die vom DCOM-Dienststeuerungs-Manager (RPCSS. exe) verwendete Standarddatei trägt den Namen "Dllhost. exe". Die DCOM-Supportstruktur verwendet die Datei "Dllhost. exe", um die dll in ihren Prozessbereich zu laden, und verwendet dann Proxy-Stub-Paare, um die angeforderte Schnittstelle transparent zurück an den Client zu marshallen, was in diesem Fall der SQL-Server ist. Mit dieser ausführbaren Datei können mehrere Schnittstellen/Methoden Anforderungen gleichzeitig akzeptiert werden. Nachdem die Schnittstellen Verwendung abgeschlossen ist, verwaltet der DCOM-Dienststeuerungs-Manager (SCM) das Bereinigen und Entladen der Datei "Dllhost. exe". Es sollte nicht erwartet werden, dass COM-Objekte Zustandsinformationen zwischen Instanziierungen behalten. Damit dieser Artikel ordnungsgemäß funktioniert, muss auf dem System ein DCOM-fähiges Betriebssystem ausgeführt werden. Dabei handelt es sich um entweder Microsoft Windows NT 4,0 Service Pack 2 oder höher, Microsoft Windows 98 oder Microsoft Windows 95, auf dem das DCOM-Add-in installiert ist. Die folgenden Schritte können auf alle dll-basierten com-Objekte angewendet werden, die im SQL Server-Prozessbereich erstellt werden, unabhängig davon, ob Sie über sp_OACreate oder eine erweiterte gespeicherte Prozedur instanziiert werden.

Weitere Informationen


Nachfolgend finden Sie Informationen zu den beiden grundlegenden Methoden, mit denen Sie das COM-Objekt außerhalb des Prozesses instanziieren können. 

COM-Client fordert Remoting des Objekts an

Wenn Sie die Art und Weise ändern, wie Sie das COM-Objekt aufrufen, können Sie anfordern, dass das Objekt außerhalb des SQL Server-Adressraums erstellt wird. 
  • Wenn das COM-Objekt mit der sp_OACreate -Prozedur geladen wird, wird es standardmäßig in Process geladen. Es gibt jedoch einen optionalen dritten Parameter für dieses Verfahren, mit dem Sie den Kontext angeben können, in dem das Objekt erstellt werden soll. Wenn dieser Parameter nicht angegeben wird, wird die Standardeinstellung Five (5) verwendet, was bedeutet, dass das Objekt entweder innerhalb oder außerhalb des Prozesses ausgeführt werden soll. Sie müssen den Parameter auf vier (4) ändern, was für DCOM angibt, dass diese Komponente als lokale ausführbare Datei ausgeführt werden soll. Verwenden Sie die Syntax ähnlich wie im folgenden Beispiel, um DCOM explizit zu informieren, dass das COM-Objekt "außerhalb des Prozesses" mit der sp_OACreate gespeicherten Prozedur ausgeführt werden soll:  
       DECLARE @object int   DECLARE @hr int   EXEC @hr = sp_OACreate 'SQLOLE.SQLServer', @object OUT, 4
  • Wenn das COM-Objekt innerhalb einer erweiterten gespeicherten Prozedur erstellt wird, kann der dritte Parameter von CoCreateInstance oder CoCreateInstanceEx in CLSCTX_LOCAL_SERVER geändert werden. Dies wird im folgenden Codebeispiel mit CoCreateInstanceangezeigt:  
       HRESULT hr = CoCreateInstance(CLSID_Test, NULL, CLSCTX_LOCAL_SERVER,     IID_IUnknown, (void**)&piunknown);

Ändern der Registrierung, um das Remoting des Objekts zu erzwingen

Wenn Sie den com-Client nicht ändern können, um zu fordern, dass das Objekt außerhalb des Prozesses erstellt wird, gibt es zwei verschiedene Methoden, um zu erzwingen, dass das Objekt außerhalb des Prozesses erstellt wird.
  • Verwenden Sie die OLE/com-Objektanzeige (OLEVIEW. exe), die im Lieferumfang von Microsoft Visual C++ enthalten ist, und suchen Sie die ProgID in Form von OLEComponent. Object unter alle Objekte. Wählen Sie das COM-Objekt aus, und wählen Sie dann im Menü Objekt die Option CoCreateInstance-Flagsaus. Stellen Sie sicher, dass nur CLSCTX_LOCAL_SERVER ausgewählt ist. Wählen Sie als nächstes unter der Registerkarte Implementierungs -und Inproc-Server die Option Surrogatprozess verwenden aus, und lassen Sie den "Pfad zu benutzerdefiniertem Ersatzzeichen" leer, wodurch die Datei "Dllhost. exe" geladen und die com-dll innerhalb des Prozessbereichs eingefügt werden kann.
  • Führen Sie die folgenden Schritte aus, um die Registrierung manuell zu aktualisieren. Warnung Die unsachgemäße Verwendung des Registrierungs-Editors oder einer anderen Methode kann schwerwiegende Probleme verursachen. Diese Probleme können eine Neuinstallation des Betriebssystems erforderlich machen. Microsoft kann nicht garantieren, dass Probleme, die von einer falschen Verwendung des Registrierungs-Editors herrühren, behoben werden können. Änderungen in der Registrierung geschehen auf eigene Verantwortung.
    1. Rufen Sie den Klassenbezeichner (CLSID) des COM-Objekts ab. Bei der CLSID handelt es sich um eine 128-Bit-Zahl, die als GUID (Globally Unique Identifier) bezeichnet wird, mit der die Komponente, das Modul oder die Datei, die dieses COM-Objekt enthält, eindeutig identifiziert wird. Beim Erstellen von COM-Objekten mithilfe der gespeicherten OLE-Automatisierungs Prozeduren ist der erste Parameter für die gespeicherte Prozedur ein programmgesteuerter Bezeichner, oder die ProgID des OLE-Objekts wird zum Ableiten der CLSID verwendet. Diese Zeichenfolge beschreibt die Klasse des OLE-Objekts und weist das folgende Format auf:
            OLEComponent.Object 
      Sie können den Programmatic-Bezeichner verwenden, um den Klassenbezeichner für ein COM-Objekt zu finden. Öffnen Sie den Registrierungs-Editor (regedit. exe), und verwenden Sie unter dem HKEY_CLASSES_ROOT-Schlüssel die Find -Methode, um einen Schlüssel mit dem Namen Ihres <OLEComponent. Object->zu finden. Sie werden es auf anderen Ebenen finden, sollten sich aber auf der Ebene befinden, die sich direkt unterhalb der HKEY_CLASSES_ROOT befindet. Nachdem Sie den Schlüssel gefunden haben, erweitern Sie den Ordner für den Schlüsselnamen, und es sollte ein Unterschlüssel mit dem Namen CLSID angezeigt werden. Klicken Sie auf diesen Ordner, um die Werte in diesem Schlüssel anzuzeigen. Auf der rechten Seite des Bildschirms befindet sich ein Titel mit dem Namen "(Standard)". Die Daten für diesen Schlüssel sollten in der folgenden Form sein:  
            {59F929A0-74D8-11D2-8CBC-08005A390B09} 
      Notieren Sie sich diesen Wert, oder kopieren Sie ihn in Editor. Schließen Sie die eckigen Klammern ein.
    2. Navigieren Sie unter dem HKEY_CLASSES_ROOT-\CLSID-Schlüssel, und suchen Sie den Unterschlüssel mit dieser GUID-Nummer. Nachdem Sie den HKEY_CLASSES_ROOT \CLSID-Schlüssel markiert haben, können Sie die Funktion Suchen im Registrierungs-Editor (im Menü Bearbeiten ) verwenden und die GUID in das Dialogfeld Suchen einfügen. Stellen Sie sicher, dass Sie die richtige Schnittstelle gefunden haben, indem Sie den InprocServer32-Unterschlüssel unterhalb dieses Schlüssels überprüfen, der auf den Speicherort Ihrer com-dll-Datei verweist. Wenn ein Typbibliotheks Schlüssel vorhanden ist, überprüfen Sie diesen GUID-Wert. Dies sollte anders sein als das, was Sie in Schritt 1 angegeben haben. Andernfalls verfügen Sie über die GUID der Typbibliothek und nicht die GUID für das COM-Objekt. Der ProgID-Unterschlüssel hat den Wert "OLEComponent. Object. 1". Die am Ende ist nur für dieses Beispiel und wird für Versionsinformationen verwendet.
    3. Stellen Sie sicher, dass unter dem InprocServer32-Unterschlüssel des GUIDs ein Threading Model-Wert vorhanden ist, der entweder auf beide oder auf frei festgesetzt ist, um sicherzustellen, dass das Marshalling das Threadingmodell des COM-Objekts versteht, um die Ausführung von com außerhalb des SQL Server-Prozessspeichers zu ermöglichen. Wenn kein Threading Model-Wert vorhanden ist oder auf "Apartment" gesetzt ist, ist die com-Objektinstanziierung möglicherweise nicht konsistent. Hinweis Wenn Sie den Threading Model-Wert hinzufügen, stellen Sie sicher, dass Sie das COM-Objekt vor der Implementierung testen.
    4. Markieren Sie die GUID-Nummer/den Schlüssel unter dem HKEY_CLASSES_ROOT \CLSID-Schlüssel. Klicken Sie im Menü Bearbeiten auf neu, und wählen Sie dann Zeichenfolgenwertaus. Geben Sie unter der Spalte Name Folgendes ein:
      AppID
    5. Drücken Sie die EINGABETASTE , und fügen Sie dann den Klassenbezeichner oder die GUID-Nummer, die Sie in Schritt 1 angegeben haben, als Wert ein. Die GUID sollte sich innerhalb der geschweiften Klammern befinden, wie im folgenden Beispiel gezeigt:  
             {59F929A0-74D8-11D2-8CBC-08005A390B09}  
      Die Application Identifier-Anwendungskennung wird von DCOM verwendet, um die dll einer ausführbaren Datei zuzuordnen.
    6. Fügen Sie einen neuen Unterschlüssel unter dem HKEY_CLASSES_ROOT \AppID hinzu, und legen Sie den Namen auf den gleichen Klassenbezeichner oder die gleiche GUID-Nummer wie im vorherigen Schritt eingefügte Klammern ab.
    7. Markieren Sie den GUID-Namen. Klicken Sie im Menü Bearbeiten auf neu, und wählen Sie dann Zeichenfolgenwertaus. Geben Sie unter der Spalte Name Folgendes ein:  
      DllSurrogate
      Lassen Sie die Daten Spalte für diesen Wert leer. Da die Datenspalte leer ist, wird DCOM darüber informiert, dass die ausführbare Standarddatei dllhost. exe ausgeführt und das COM-Objekt innerhalb des Prozessbereichs geladen wird.
    8. Schließen Sie den Registrierungs-Editor. Klicken Sie auf Start und anschließend auf Ausführen. Geben Sie im Dialogfeld Ausführen Folgendes ein:  
      DCOMCNFG
      Drücken Sie die Eingabe Taste, um das Dialogfeld Eigenschaften für verteilte com-Konfiguration zu öffnen. Klicken Sie auf die Registerkarte Standardeigenschaften , und stellen Sie sicher, dass " Distributed COM auf diesem Computer aktivieren " aktiviert ist. Wenn dies nicht der Fall ist, wählen Sie ihn aus, und klicken Sie dann auf über nehmen.
    9. Stellen Sie sicher, dass das Microsoft Windows NT-Benutzerkonto, unter dem SQL Server ausgeführt wird, über die Berechtigung "Vollzugriff" für die Registrierungsschlüssel für dieses Objekt verfügt. Wenn die Berechtigungen nicht ausreichen oder die Registrierungsschlüssel falsch eingegeben werden, können die folgenden Fehler auftreten, wenn Sie das COM-Objekt erstellen:  
      Fehlerinformationen zur OLE-Automatisierung HRESULT: 0x80040154 Quelle: Erweiterte Prozedur ODSOLE- Beschreibung: Klasse nicht registriert Fehlerinformationen zur OLE-Automatisierung HRESULT: 0x80070005 Quelle: Erweiterte Prozedur ODSOLE- Beschreibung: Zugriff verweigert. Fehlerinformationen zur OLE-Automatisierung HRESULT: 0x80080005 Quelle: Erweiterte Prozedur ODSOLE- Beschreibung: Fehler bei der Server Ausführung
    10. Testen Sie, ob dies die Datei "Dllhost. exe" ausführt, und laden Sie das COM-Objekt in seinen Prozessbereich. Dazu muss sich das Microsoft Windows NT Resource Kit auf dem Windows NT-Computer befinden, auf dem SQL Server ausgeführt wird. Öffnen Sie eine Eingabeaufforderung, und führen Sie an der Eingabeaufforderung die Datei "tlist. exe" aus, in der alle Prozesse und die zugehörigen Prozessbezeichner oder Prozess-IDs (PID) angezeigt werden. Verwenden Sie im Transact-SQL-Skript, in dem sp_OACreate ausgeführt wird und nach der Ausführung des Aufrufs, aber vor dem Ende des Skripts, die folgenden Schritte, um den Skript Abschluss für weitere 20 Sekunden zu verzögern:  
      WAITFOR DELAY '000:00:20'
      Führen Sie das Skript aus, navigieren Sie sofort zur Eingabeaufforderung, und führen Sie die Datei "tlist. exe" aus. Beachten Sie die PID dllhost. exe. Führen Sie tlist. exe erneut aus, und übergeben Sie die PID als Parameter. Zeigt die DLLs an, die im Prozessbereich "Dllhost. exe" geladen werden. Das dll-basierte com-Objekt sollte als in diesem Prozess ausgeführt aufgelistet werden. Nachdem das Skript zurückgegeben wurde, zeigt die Ausführung von tlist. exe erneut, dass der dllhost. exe-Prozess nicht mehr ausgeführt wird. Im folgenden Beispiel wird die Datei ADODB. Das Connection-Objekt wird außerhalb des SQL Server-Prozessbereichs erstellt. Dieser Snapshot mit "tlist. exe" wurde ausgeführt, während das COM-Objekt im Prozessbereich "Dllhost. exe" vorhanden war. Beachten Sie, dass das Modul MSADO15. dll, das das Modul mit dem COM-Objekt ist, geladen wird.  
      C:\>tlist dllhost 275 dllhost.exe   CWD:     C:\NT40\system32\    CmdLine: C:\NT40\System32\dllhost.exe {00000514-0000-0010-8000-00AA006D2EA4}-Embedding   VirtualSize:    19180 KB   PeakVirtualSize:    19180 KB   WorkingSetSize:  1780 KB   PeakWorkingSetSize:  1780 KB   NumberOfThreads: 3    278 Win32StartAddr:0x01001920 LastErr:0x00000000 State:Waiting    215 Win32StartAddr:0x00001b5e LastErr:0x00000000 State:Waiting    253 Win32StartAddr:0x00001b60 LastErr:0x000000cb State:Waiting   4.0.1381.105 shp  0x01000000  dllhost.exe   4.0.1381.130 shp  0x77f60000  ntdll.dll   4.0.1381.121 shp  0x77dc0000  ADVAPI32.dll   4.0.1381.133 shp  0x77f00000  KERNEL32.dll   4.0.1381.133 shp  0x77e70000  USER32.dll   4.0.1381.115 shp  0x77ed0000  GDI32.dll   4.0.1381.131 shp  0x77e10000  RPCRT4.dll   4.0.1381.117 shp  0x77b20000  ole32.dll     6.0.8267.0 shp  0x78000000  MSVCRT.dll                     0x1f310000  msado15.dll    2.30.4265.1 shp  0x766f0000  OLEAUT32.dll    4.0.1381.72 shp  0x77bf0000  rpcltc1.dll
      Mit der SQL Server-Version 7,0 Desktop Edition, die auf Microsoft Windows 95-oder Microsoft Windows 98-Workstations ausgeführt wird, können während der Ausführung die "32-Bit-Module" geladen werden, die innerhalb des Microsoft-Systeminformations-Anwendungstools verwendet werden, um die loading\unloading der Datei "Dllhost. exe" und die COM-Objekt-dll während dieses Tests anzuzeigen. Um auf das Tool zuzugreifen, klicken Sie auf Start, zeigen Sie auf Programme, zeigen Sie auf Zubehör, und klicken Sie dann auf System Tools.
Hinweis Aufgrund von Sicherheitseinschränkungen unterstützt Windows 95 oder Windows 98 nicht das Starten eines DLLSurrogate-Prozesses und das Laden einer com-dll durch einen Remote Client. Daher muss das COM-Objekt innerhalb der ausgeführten Objekttabelle (rot) vorhanden sein und ausgeführt/geladen werden, wenn es für die Verwendung durch einen Remoteclientcomputer verfügbar sein soll. Mit den Schritten in diesem Artikel können Sie COM-Objekte isolieren, wenn Sie vermuten, dass Sie die Ursache der Instabilität in SQL Server sind. Stellen Sie sicher, dass jede Komponente gründlich ausgeführt wird, um ein konsistentes Verhalten zu gewährleisten. Die Leistungsunterschiede beim Instanziieren eines COM-Objekts im SQL Server-Prozess und außerhalb des Prozessbereichs sind unterschiedlich. Darüber hinaus wurden einige COM-Objekte nicht für die Remoteerstellung entwickelt und können Ressourcen auslaufen. Testen Sie gründlich, bevor Sie die in diesem Artikel beschriebenen Schritte für einen anderen Schritt zur Problembehandlung durchführen. Der folgende Microsoft Knowledge Base-Artikel enthält ein Beispiel dafür, wie Remoting eines COM-Objekts zu einem Ressourcen Leck führen kann:
197426 Fix: handle Leak beim Übergeben von ADO-Objekten zwischen Prozessen 
Hinweis Microsoft SQL Server 6,5 arbeitet standardmäßig mit einem STA-Modell (Single Thread Apartment) und verarbeitet die Initialisierung von COM-Objekten in einem separaten internen Thread. In diesem Modell wird ein Thread ausgewählt, um die Erstellung aller OLE-Objekte innerhalb des SQL Server-Prozesses zu steuern und einen Proxy wieder an alle Clientverbindungen zu übersetzen, die Zugriff auf dieses COM-Objekt benötigen. Da dies intern von SQL Server behandelt wird, kann die Persistenz des Objekts zwischen Instanziierungen des COM-Objekts nicht garantiert werden. 

Informationsquellen


Wenn Sie weitere Informationen zum SQL Server 6,5-com-Objektmodell erhalten möchten, klicken Sie auf die folgende Artikelnummer, um den Artikel in der Microsoft Knowledge Base anzuzeigen:
194661 SQL Server-COM-Objekt-Dauerhaftigkeits Modell
Wenn Sie weitere Informationen zur Implementierung der gespeicherten Prozedur Sp_OA erhalten möchten, klicken Sie auf die folgende Artikelnummer, um den Artikel in der Microsoft Knowledge Base anzuzeigen:
180780 Implementierung Sp_OA Prozeduren-Erweiterung für SQL Server
Weitere Informationen zum Ausführen von dll-basierten com-Objekten in dll-Surrogaten Bitte lesen Sie die folgenden Informationen: Eddon, Guy; Eddon Henry, in Distributed COM (MPS). Microsoft Press, 1998, (ISBN 1-57231-849-X), Kapitel 8: "dll-Surrogate und ausführbare Components'Box, Don, Essential com. Addison-Wesley Pub. Co., (ISBN 0-201-63446-5) Kapitel sechs: "Anwendungen" Grimes, Richard, professionelle DCOM-Programmierung. Wrox Press Inc. (ISBN 1-861000-60-X), Kapitel 4: "verteiltes Komponentenobjektmodell" das DCOM-Add-in für Windows 95 wird mit dem SQL Server 7,0-Medium ausgeliefert, und die Datei hat den Namen "Dcom95. exe". Sie können Dcom95. exe von der folgenden Website herunterladen: