Comment exécuter un objet COM basé sur une DLL hors du processus SQL Server

S’applique à : Microsoft SQL Server 2005 Standard EditionMicrosoft SQL Server 2005 Developer EditionMicrosoft SQL Server 2005 Enterprise Edition

Résumé


Microsoft SQL Server 6,5 ou version ultérieure offre la possibilité de charger et d’exécuter des objets COM (Component Object Model) personnalisés via un ensemble de procédures stockées OLE Automation ou par le biais de procédures stockées étendues. Par défaut, les objets COM DLL sont chargés en tant que tels dans le serveur de processus, ce qui signifie que les objets COM ne sont pas chargés uniquement dans l’espace d’adressage de mémoire de processus SQL Server, mais ils ont également un accès complet à cet espace d’adressage de mémoire. Par conséquent, un objet COM chargé dans l’espace de processus SQL Server doit adhérer aux mêmes règles que tout fichier DLL. Il est possible qu’un objet COM puisse remplacer la mémoire dans le processus SQL Server ou les ressources de fuite, provoquant une instabilité. S’il existe une suspicion qu’un objet COM peut affecter la fiabilité du processus SQL Server, il est possible que vous souhaitiez suivre les étapes décrites dans cet article pour instancier l’objet COM en dehors de l’espace de processus SQL Server. Dans le système d’exploitation, l’implémentation de la spécification de modèle d’objet de composant distribué (DCOM) « transparence de l’emplacement » permet d’exécuter un objet COM basé sur une DLL en dehors de l’espace de processus SQL Server. Le processus d’exécution d’un objet COM basé sur une DLL en dehors de l’espace d’adressage de l’application principale est appelé accès distant. L’accès distant nécessite qu’un autre exécutable soit un processus de substitution à la place du fichier exécutable SQL Server. L’exécutable par défaut utilisé par le gestionnaire de contrôle des services DCOM (RPCSS. exe) est appelé DllHost. exe. La structure de prise en charge DCOM utilise le fichier Dllhost. exe pour charger la DLL dans son espace de processus, puis utilise les paires proxy/stub pour marshaler l’interface demandée de manière transparente vers le client, ce qui est le cas dans le serveur SQL Server. Ce fichier exécutable peut accepter plusieurs demandes d’interface/méthode en même temps. À l’issue de l’utilisation de l’interface, le gestionnaire de contrôle de service DCOM gère le nettoyage et le déchargement du fichier Dllhost. exe. Les objets COM ne doivent pas être censés conserver des informations d’État entre les instanciations. Pour que cet article fonctionne correctement, le système doit exécuter un système d’exploitation compatible DCOM. Il s’agirait de Microsoft Windows NT 4,0 Service Pack 2 ou version ultérieure, Microsoft Windows 98 ou Microsoft Windows 95 avec le complément DCOM installé. Les étapes suivantes peuvent s’appliquer à tout objet COM DLL créé dans l’espace de processus SQL Server, qu’il soit instancié par le biais d' sp_OACreate ou d’une procédure stockée étendue.

Informations supplémentaires


Vous trouverez ci-après des informations sur les deux méthodes de base que vous pouvez utiliser pour instancier l’objet COM hors processus. 

Le client COM demande l’accès distant de l’objet

En modifiant la façon dont vous appelez l’objet COM, vous pouvez demander la création de l’objet en dehors de l’espace d’adressage SQL Server. 
  • Si l’objet COM est chargé à l’aide de la procédure sp_OACreate , il est chargé par défaut dans Process. Néanmoins, il existe un troisième paramètre facultatif pour cette procédure qui peut vous permettre d’indiquer le contexte dans lequel créer l’objet. Si ce paramètre n’est pas spécifié, la valeur par défaut de cinq (5) est utilisée, ce qui signifie que vous pouvez exécuter l’objet à l’intérieur ou à l’extérieur du processus. Vous devez changer le paramètre en quatre (4), ce qui indique à DCOM que ce composant doit être exécuté en tant qu’exécutable local. Utilisez une syntaxe similaire à celle qui suit pour informer explicitement DCOM d’exécuter l’objet COM « hors processus » à l’aide de la procédure stockée sp_OACreate :  
       DECLARE @object int   DECLARE @hr int   EXEC @hr = sp_OACreate 'SQLOLE.SQLServer', @object OUT, 4
  • Si l’objet COM est créé au sein d’une procédure stockée étendue, le troisième paramètre de CoCreateInstance ou CoCreateInstanceEx peut être modifié en CLSCTX_LOCAL_SERVER. Vous trouverez ci-dessous un exemple de code qui illustre l’utilisation de CoCreateInstance:  
       HRESULT hr = CoCreateInstance(CLSID_Test, NULL, CLSCTX_LOCAL_SERVER,     IID_IUnknown, (void**)&piunknown);

Modification du Registre pour forcer l’accès distant de l’objet

Si vous ne pouvez pas modifier le client COM pour demander que l’objet soit créé hors processus, il existe deux méthodes différentes permettant de forcer la création de l’objet hors processus.
  • Utilisez OLE/COM Object Viewer (OLEVIEW. exe) fourni avec Microsoft Visual C++ et recherchez le ProgID sous la forme OLEComponent. Object sous tous les objets. Sélectionnez l’objet COM, puis dans le menu objet , sélectionnez indicateurs CoCreateInstance. Assurez-vous que l’option uniquement CLSCTX_LOCAL_SERVER est sélectionnée. Sous les onglets serveur implémentation et InProc du serveur , sélectionnez utiliser le processus de substitution et laissez le champ « chemin d’accès à un substitut personnalisé » vide, ce qui permet le chargement du fichier Dllhost. exe et la dll com dans son espace de processus.
  • Procédez comme suit pour mettre à jour manuellement le registre. Avertissement Toute modification incorrecte du Registre à l'aide de l'Éditeur du Registre ou d'une autre méthode peut entraîner des problèmes sérieux. Ces problèmes peuvent nécessiter la réinstallation du système d'exploitation. Microsoft ne peut pas garantir que ces problèmes peuvent être résolus. Vous modifiez le Registre à vos risques et périls.
    1. Obtenez l’identificateur de classe (CLSID) de l’objet COM. Le CLSID est un nombre 128 bits qui est considéré comme un identificateur global unique (GUID) qui est utilisé pour identifier de manière unique le composant, le module ou le fichier qui contient cet objet COM. Lors de la création d’objets COM en utilisant les procédures stockées OLE Automation, le premier paramètre de la procédure stockée est un identificateur par programmation ou le ProgID de l’objet OLE est utilisé pour dériver le CLSID. La chaîne de caractères suivante décrit la classe de l’objet OLE et se présente comme suit :
            OLEComponent.Object 
      Vous pouvez utiliser l’identificateur programmatique pour Rechercher l’identificateur de classe d’un objet COM. Ouvrez l’éditeur du Registre (regedit. exe), puis sous la clé HKEY_CLASSES_ROOT, utilisez la méthode Find pour rechercher une clé portant le nom de votre ><OLEComponent. Object . Vous le trouverez à d’autres niveaux, mais il devrait être placé au niveau juste en dessous du HKEY_CLASSES_ROOT. Une fois que vous avez trouvé la clé, développez le dossier du nom de la clé et une sous-clé nommée CLSID s’affiche. Cliquez sur ce dossier pour afficher les valeurs de cette clé. Sur le côté droit de l’écran figure le titre "(par défaut)". Les données pour cette clé doivent être sous la forme suivante :  
            {59F929A0-74D8-11D2-8CBC-08005A390B09} 
      Notez cette valeur ou copiez-la dans le bloc-notes. Incluez les crochets.
    2. Naviguez sous la clé HKEY_CLASSES_ROOT \CLSID et recherchez la sous-clé avec ce numéro GUID. Après avoir mis en surbrillance la clé de \CLSID HKEY_CLASSES_ROOT, vous pouvez utiliser la fonction trouve dans l’éditeur du Registre (sous le menu Edition ) et coller le GUID dans la boîte de dialogue Rechercher . Vérifiez que vous avez trouvé l’interface appropriée en inspectant la sous-clé InprocServer32 sous cette clé, qui pointe vers l’emplacement de votre fichier DLL COM. S’il existe une clé TypeLib, vérifiez la valeur GUID. Cela doit être différent de ce que vous avez mentionné à l’étape 1. Sinon, vous avez le GUID TypeLib et non le GUID de l’objet COM. La sous-clé ProgID aura la valeur « OLEComponent. Object. 1 ». Le premier à la fin s’utilise uniquement pour cet exemple et est utilisé pour les informations de contrôle de version.
    3. Sous la sous-clé InprocServer32 du GUID, assurez-vous qu’il existe une valeur ThreadingModel et qu’elle est définie sur les deux ou sur libre pour s’assurer que le marshaling comprend le modèle de thread de l’objet COM pour permettre l’exécution de l’espace de processus SQL Server en dehors de SQL Server. S’il n’existe pas de valeur ThreadingModel ou si elle est définie sur Apartment, l’instanciation d’objet COM risque de ne pas être cohérente. Remarque Si vous ajoutez la valeur ThreadingModel, veillez à tester votre objet COM avant de l’implémenter.
    4. Mettez en surbrillance le numéro/sous-clé GUID sous la clé de \CLSID HKEY_CLASSES_ROOT. Dans le menu édition , cliquez sur nouveau, puis sélectionnez valeur chaîne. Dans la colonne nom , tapez les informations suivantes :
      AppID
    5. Appuyez sur entrée , puis insérez l’identificateur de classe ou le numéro de GUID que vous avez indiqué à l’étape 1 comme valeur. Le GUID doit se trouver entre les crochets comme dans l’exemple suivant :  
             {59F929A0-74D8-11D2-8CBC-08005A390B09}  
      L’identificateur d’ID d’application est utilisé par DCOM pour associer la DLL à un fichier exécutable.
    6. Ajoutez une nouvelle sous-clé sous la HKEY_CLASSES_ROOT \AppID et attribuez-lui le nom de l’identificateur de classe ou du GUID correspondant aux crochets insérés dans l’étape précédente.
    7. Mettez en surbrillance le nom du GUID. Dans le menu édition , cliquez sur nouveau, puis sélectionnez valeur chaîne. Dans la colonne nom , tapez les informations suivantes :  
      DllSurrogate
      Ne renseignez pas la colonne de données pour cette valeur. Étant donné que la colonne Data est vide, la valeur DCOM est utilisée pour exécuter le fichier exécutable par défaut, Dllhost. exe et charger l’objet COM dans son espace de processus.
    8. Fermez l’éditeur du Registre. Cliquez sur Démarrer, puis sur Exécuter. Dans la boîte de dialogue exécuter , tapez les informations suivantes :  
      DCOMCNFG
      Appuyez sur la touche entrée pour ouvrir la boîte de dialogue Propriétés de configuration de Distributed COM . Cliquez sur l’onglet propriétés par défaut , puis vérifiez que l’option Activer le com distribué sur cet ordinateur est sélectionnée. Si ce n’est pas le cas, sélectionnez-la, puis cliquez sur appliquer.
    9. Assurez-vous que le compte d’utilisateur Microsoft Windows NT exécutant SQL Server dispose de l’autorisation « contrôle total » sur les clés de registre de cet objet. Si les autorisations ne sont pas suffisantes ou que les clés de Registre sont incorrectes, les erreurs suivantes peuvent se produire lors de la création de l’objet COM :  
      Informations d’erreur OLE Automation HRESULT : 0x80040154 Source : ODSOLE de processus étendu Description : classe non enregistrée Informations d’erreur OLE Automation HRESULT : 0x80070005 Source : ODSOLE de processus étendu Description : accès refusé. Informations d’erreur OLE Automation HRESULT : 0x80080005 Source : ODSOLE de processus étendu Description : échec de l’exécution du serveur
    10. Testez et regardez si cela exécute le fichier Dllhost. exe et chargez l’objet COM dans son espace de processus. Pour cela, le kit de ressources Microsoft Windows NT doit être installé sur l’ordinateur Windows NT sur lequel SQL Server est en cours d’exécution. Ouvrez une invite de commandes et à partir de l’invite de commandes, exécutez le fichier tlist. exe, qui affiche tous les processus et leurs identificateurs de processus associés, ou identificateurs de processus. Dans le script Transact-SQL sur lequel sp_OACreate s’exécute et après l’exécution de cet appel, mais avant la fin du script, utilisez la commande suivante pour retarder la fin du script d’une vingtaine de secondes supplémentaires :  
      WAITFOR DELAY '000:00:20'
      Exécutez le script et accédez immédiatement à l’invite de commandes et exécutez le fichier tlist. exe. Notez le PID Dllhost. exe. Réexécutez tlist. exe et transmettez le PID en tant que paramètre. Cela montre les DLL chargées dans l’espace de processus Dllhost. exe. L’objet COM DLL doit être répertorié comme étant en cours d’exécution dans le cadre de ce processus. Une fois le script renvoyé, l’exécution de tlist. exe révèle qu’il n’est plus en cours d’exécution par tlist. exe. Dans l’exemple suivant, la sortie de l’ADODB. L’objet connexion est créé en dehors de l’espace de processus SQL Server. Cette capture d’image à l’aide de tlist. exe a été effectuée lorsque l’objet COM existait dans l’espace de processus Dllhost. exe. Notez que le module msado15. dll, qui est le module qui contient l’objet COM, est chargé.  
      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
      Lorsque SQL Server version 7,0 Desktop Edition est en cours d’exécution sur les postes de travail Microsoft Windows 95 ou Microsoft Windows 98, les « modules 32-bits chargés » dans l’outil d’application informations système Microsoft peuvent être utilisés lors de l’exécution pour voir le loading\unloading du fichier Dllhost. exe et la DLL d’objet COM au cours de ce test. Pour accéder à l’outil, cliquez sur Démarrer, pointez sur programmes, sur accessoires, puis cliquez sur Outils système.
Remarque En raison des limitations de sécurité, Windows 95 ou Windows 98 ne prend pas en charge le démarrage d’un processus DLLSurrogate et le chargement d’une DLL COM par un client distant. Par conséquent, l’objet COM doit exister dans la table ROT (Running Object Table) et être en cours d’exécution/de chargement s’il doit être utilisé par un ordinateur client distant. Vous pouvez suivre la procédure décrite dans cet article pour isoler les objets COM quand ils sont susceptibles d’être à l’origine de l’instabilité du serveur SQL Server. Assurez-vous que chaque composant est testé de manière approfondie pour garantir un comportement cohérent. La différence de performance dans l’instanciation d’un objet COM dans le processus SQL Server et en dehors de l’espace de processus varie. Par ailleurs, certains objets COM n’ont pas été créés pour être distants et peuvent fuir des ressources. Testez minutieusement avant d’implémenter les étapes décrites dans cet article pour une autre chose qu’une procédure de dépannage. L’article de la base de connaissances Microsoft suivant présente un exemple de la façon dont l’accès distant d’un objet COM peut provoquer une perte de ressources :
197426 Correction : fuite de handles lors du passage d’objets ADO entre processus 
Remarque Par défaut, Microsoft SQL Server 6,5 fonctionne avec un modèle de thread unique cloisonné (STA) et gère l’initialisation d’objets COM sur un thread interne distinct. Dans ce modèle, un thread est sélectionné pour contrôler la création de tous les objets OLE dans le processus SQL Server, ainsi que l’accès par proxy à toutes les connexions clientes qui ont besoin d’accéder à cet objet COM. Étant donné qu’il est géré en interne par le serveur SQL Server, la persistance de l’objet ne peut pas être garantie entre les instanciations de l’objet COM. 

Références


Pour plus d’informations sur le modèle d’objet COM SQL Server 6,5, cliquez sur le numéro ci-dessous pour consulter l’article de la base de connaissances Microsoft :
194661 Modèle de persistance d’objets COM SQL Server
Pour plus d’informations sur la manière d’implémenter la procédure stockée Sp_OA, cliquez sur le numéro ci-dessous pour consulter l’article de la base de connaissances Microsoft :
180780 Comment Sp_OA extension de procédures sur SQL Server est implémentée
Pour plus d’informations sur l’exécution d’objets COM basés sur une DLL dans des substitutions de DLL ; Pour plus d’informations, consultez les rubriques suivantes : Eddon, Guy ; Eddon Henry, au sein d’un Distributed COM (MPS). Microsoft Press, 1998, (ISBN 1-57231-849-X), chapitre huit : 'substitutions de DLL et Components’Box exécutable, Paul, le com essentiel. Addison-Wesley pub. Co., (ISBN 0-201-63446-5) chapitre 6 : « applications » Grimes, Richard et programmation DCOM. Wrox Press Inc. (ISBN 1-861000-60-X), chapitre 4 : « modèle d’objet de composant distribué » le complément DCOM pour Windows 95 est fourni avec le média SQL Server 7,0 et le fichier est appelé DCOM95. exe. Vous pouvez télécharger DCOM95. exe à partir du site Web suivant :