Condividi tramite


Eseguire un oggetto COM basato su DLL all'esterno del processo di SQL Server

Questo articolo descrive come eseguire un oggetto COM basato su DLL all'esterno del processo di SQL Server.

Versione originale del prodotto: SQL Server
Numero KB originale: 198891

Riepilogo

Microsoft SQL Server offre la possibilità di caricare ed eseguire oggetti COM (Component Object Model) personalizzati tramite un set di stored procedure di automazione OLE o tramite stored procedure estese. Per impostazione predefinita, gli oggetti COM basati su DLL vengono caricati come nel server di elaborazione, il che significa che gli oggetti COM non vengono caricati solo all'interno dello spazio indirizzi della memoria del processo di SQL Server, ma hanno anche accesso completo a questo spazio indirizzi di memoria. Pertanto, un oggetto COM caricato nello spazio di elaborazione di SQL Server deve rispettare le stesse regole di qualsiasi file DLL. Esiste un potenziale che un oggetto COM potrebbe sovrascrivere la memoria all'interno del processo di SQL Server o perdere risorse, causando instabilità.

Se si sospetta che un oggetto COM possa influire sull'affidabilità del processo di SQL Server, è possibile usare i passaggi descritti in questo articolo per creare un'istanza dell'oggetto COM all'esterno dello spazio di elaborazione di SQL Server. L'implementazione della specifica DCOM (Distributed Component Object Model) di Trasparenza percorso nel sistema operativo ha offerto la possibilità di eseguire un oggetto COM basato su DLL all'esterno dello spazio di elaborazione di SQL Server.

Il processo di esecuzione di un oggetto COM basato su DLL all'esterno dello spazio degli indirizzi dell'applicazione principale è denominato comunicazione remota. La comunicazione remota richiede che un altro eseguibile sia un processo surrogato al posto dell'eseguibile di SQL Server. L'eseguibile predefinito usato da DCOM Service Control Manager (rpcss.exe) è denominato dllhost.exe. La struttura di supporto DCOM usa il file dllhost.exe per caricare la DLL nello spazio di processo e quindi usa coppie proxy/stub per effettuare il marshalling dell'interfaccia richiesta in modo trasparente al client, che in questo caso è SQL Server. Questo eseguibile può accettare più richieste di interfaccia/metodo contemporaneamente. Al termine dell'utilizzo dell'interfaccia, DCOM Service Control Manager (SCM) gestisce la pulizia e lo scaricamento del file dllhost.exe . Non è previsto che gli oggetti COM mantengano le informazioni sullo stato tra le istanze.

La procedura seguente può essere applicata a qualsiasi oggetto COM basato su DLL creato nello spazio di elaborazione di SQL Server, indipendentemente dal fatto che venga creata un'istanza tramite sp_OACreate o una stored procedure estesa.

Ulteriori informazioni

Di seguito sono riportate informazioni sui due metodi di base che è possibile utilizzare per creare un'istanza dell'oggetto COM fuori processo.

Il client COM richiede la comunicazione remota dell'oggetto

Modificando il modo in cui si richiama l'oggetto COM, è possibile richiedere che l'oggetto venga creato all'esterno dello spazio indirizzi di SQL Server.

  • Se l'oggetto COM viene caricato utilizzando la sp_OACreate routine , per impostazione predefinita viene caricato in processo. Esiste tuttavia un terzo parametro facoltativo per questa procedura che può essere usato per indicare il contesto di dove creare l'oggetto. Se questo parametro non viene specificato, viene utilizzata l'impostazione predefinita di cinque (5), ovvero per eseguire l'oggetto all'interno o all'esterno del processo. È necessario modificare il parametro in quattro (4), che indica a DCOM che questo componente deve essere eseguito come eseguibile locale. Usare la sintassi simile all'esempio seguente per informare in modo esplicito DCOM di eseguire l'oggetto COM fuori processo usando la sp_OACreate stored procedure:

    DECLARE @object int
    DECLARE @hr int
    EXEC @hr = sp_OACreate 'SQLOLE.SQLServer', @object OUT, 4
    
  • Se l'oggetto COM viene creato all'interno di una stored procedure estesa, il terzo parametro di CoCreateInstance o CoCreateInstanceEx può essere modificato in CLSCTX_LOCAL_SERVER. Questo esempio di codice è illustrato nell'esempio di codice seguente usando CoCreateInstance:

    HRESULT hr = CoCreateInstance(CLSID_Test, NULL, CLSCTX_LOCAL_SERVER,
    IID_IUnknown, (void**)&piunknown);
    

Modificare il Registro di sistema per forzare la comunicazione remota dell'oggetto

Se non è possibile modificare il client COM per richiedere che l'oggetto venga creato fuori processo, esistono due metodi diversi per forzare la creazione dell'oggetto fuori processo.

  • Usare il visualizzatore oggetti OLE/COM (oleview.exe) fornito con Visual C++ e individuare il ProgID sotto forma di OLEComponent.Object tutti gli oggetti. Selezionare l'oggetto COM e quindi scegliere Flag dal menu CoCreateInstance Oggetto. Assicurarsi che sia selezionato solo CLSCTX_LOCAL_SERVER . Quindi, nelle schede Implementazione e Server inproc selezionare Usa processo surrogato e lasciare vuoto il percorso del surrogato personalizzato, che consente il caricamento del file dllhost.exe e la DLL COM inserita all'interno dello spazio di processo.

  • Usare la procedura seguente per aggiornare manualmente il Registro di sistema.

    Avviso

    Se si modifica il Registro di sistema in modo errato tramite l'Editor del Registro di sistema o con un altro metodo, possono verificarsi gravi problemi Questi problemi potrebbero richiedere la reinstallazione del sistema operativo. Microsoft non è in grado di garantire la soluzione di tali problemi. La modifica del Registro di sistema è a rischio e pericolo dell'utente.

    1. Ottenere l'identificatore di classe (CLSID) dell'oggetto COM. CLSID è un numero a 128 bit e considerato un IDENTIFICATORe univoco globale (GUID) usato per identificare in modo univoco il componente, il modulo o il file che contiene questo oggetto COM. Quando si creano oggetti COM utilizzando le stored procedure di automazione OLE, il primo parametro della stored procedure è un identificatore programmatico o il ProgID dell'oggetto OLE viene utilizzato per derivare il CLSID. Questa stringa di caratteri descrive la classe dell'oggetto OLE e ha il formato seguente:

      OLEComponent.Object
      
    2. È possibile utilizzare l'identificatore programmatico per trovare l'identificatore di classe per un oggetto COM.

      Aprire l'Editor del Registro di sistema (regedit.exe) e nella HKEY_CLASSES_ROOT chiave usare il Find metodo per individuare una chiave con il nome dell'oggetto <OLEComponent.Object>. Lo troverete ad altri livelli, ma dovrebbe trovarsi a livello direttamente sotto .HKEY_CLASSES_ROOT Dopo aver individuato la chiave, espandere la cartella per il nome della chiave e verrà visualizzata una sottochiave denominata CLSID. Selezionare tale cartella per visualizzare i valori all'interno di tale chiave. Sul lato destro della schermata è presente un titolo denominato Default. I dati per tale chiave devono essere nel formato seguente:

      {59F929A0-74D8-11D2-8CBC-08005A390B09}

      Prendere nota di questo valore o copiarlo nel Blocco note. Includere le parentesi quadre.

    3. Passare sotto la HKEY_CLASSES_ROOT\CLSID chiave e trovare la sottochiave con questo numero GUID. Dopo aver evidenziato la HKEY_CLASSES_ROOT\CLSID chiave, è possibile usare la funzione Trova nell'editor del Registro di sistema (nel menu Modifica ) e incollare il GUID nella finestra di dialogo Trova . Assicurarsi di aver trovato l'interfaccia corretta controllando la sottochiave InprocServer32 in questa chiave, che punta al percorso del file DLL COM. Se è presente una chiave TypeLib, controllare questo valore GUID. Questa operazione deve essere diversa da quella annotata nel passaggio 1. In caso contrario, si dispone del GUID TypeLib e non del GUID per l'oggetto COM. La sottochiave ProgID avrà il valore .OLEComponent.Object.1 Quello finale è solo per questo esempio e viene usato per le informazioni sul controllo delle versioni.

    4. Nella sottochiave InprocServer32 del GUID assicurarsi che esista un ThreadingModel valore e che sia impostato su Entrambi o Su Free per assicurarsi che il marshalling comprenda il modello di threading dell'oggetto COM per abilitare l'esecuzione di COM dallo spazio di elaborazione di SQL Server. Se non è presente un ThreadingModel valore o è impostato su Apartment, la creazione di istanze dell'oggetto COM potrebbe non essere coerente.

      Note

      Se si aggiunge il valore, assicurarsi di testare l'oggetto ThreadingModel COM prima dell'implementazione.

    5. Evidenziare il numero GUID/sottochiave sotto la HKEY_CLASSES_ROOT\CLSID chiave. Scegliere Nuovo dal menu Modifica e quindi selezionare Valore stringa. Nella colonna Nome digitare AppID.

    6. Premere INVIO e quindi inserire l'identificatore di classe o il numero GUID annotato nel passaggio 1 come valore. Il GUID deve trovarsi all'interno delle parentesi graffe come nell'esempio seguente:

      {59F929A0-74D8-11D2-8CBC-08005A390B09}
      

      L'id applicazione AppID viene usato da DCOM per associare la DLL a un file eseguibile.

    7. Aggiungere una nuova sottochiave sotto HKEY_CLASSES_ROOT\AppID e impostarne il nome sullo stesso identificatore di classe o numero GUID con le parentesi quadre inserite nel passaggio precedente.

    8. Evidenziare il nome GUID. Scegliere Nuovo dal menu Modifica e quindi selezionare Valore stringa. Nella colonna Nome digitare dllSurrogate.

      Lasciare vuota la colonna Dati per questo valore. Poiché la colonna di dati è vuota, indica a DCOM di eseguire il file eseguibile predefinito, dllhost.exe e caricare l'oggetto COM all'interno dello spazio di elaborazione.

    9. Chiudere l'Editor del Registro di sistema. Fare clic su Start e quindi selezionare Esegui. Nella finestra di dialogo Esegui digitare DCOMCNFG.

      Premere INVIO per aprire la finestra di dialogo Proprietà di configurazione COM distribuite. Fare clic sulla scheda Proprietà predefinite e verificare che l'opzione Abilita COM distribuito nel computer sia selezionata. In caso contrario, selezionarlo e quindi selezionare Applica.

    10. Assicurarsi che l'account utente di Windows NT in cui è in esecuzione SQL Server disponga dell'autorizzazione Controllo completo per le chiavi del Registro di sistema per questo oggetto. Se le autorizzazioni non sono sufficienti o le chiavi del Registro di sistema vengono immesse in modo errato, possono verificarsi gli errori seguenti durante la creazione dell'oggetto COM:

      Informazioni sugli errori di automazione OLE
      HRESULT: 0x80040154
      Origine: procedura estesa ODSOLE
      Descrizione: Classe non registrata

      Informazioni sugli errori di automazione OLE
      HRESULT: 0x80070005
      Origine: procedura estesa ODSOLE
      Descrizione: accesso negato.

      Informazioni sugli errori di automazione OLE
      HRESULT: 0x80080005
      Origine: procedura estesa ODSOLE
      Descrizione: Esecuzione del server non riuscita

    11. Testare e verificare se è in esecuzione il file dllhost.exe e caricare l'oggetto COM nello spazio di elaborazione. Ciò richiede che Windows NT Resource Kit si trova nel computer Windows NT in cui è in esecuzione SQL Server. Aprire un prompt dei comandi e dal prompt dei comandi eseguire il file tlist.exe , che mostra tutti i processi e gli identificatori di processo associati o i PID (Process Identifiers). Nello script Transact-SQL in cui sp_OACreate viene eseguita e dopo l'esecuzione di tale chiamata, ma prima che lo script termini, usare quanto segue per ritardare il completamento dello script per altri 20 secondi:

      WAITFOR DELAY '000:00:20'
      

      Eseguire lo script e passare immediatamente al prompt dei comandi ed eseguire il file tlist.exe . Prendere nota del PID dllhost.exe . Eseguire di nuovo tlist.exe e passare il PID come parametro. Vengono visualizzate le DLL caricate all'interno dello spazio di elaborazione dllhost.exe . L'oggetto COM basato su DLL deve essere elencato come in esecuzione all'interno di questo processo. Al termine dell'esecuzione dello script, tlist.exe rivela di nuovo che il processo di dllhost.exe non è più in esecuzione.

      Nell'output di esempio seguente, ADODB. L'oggetto connessione viene creato all'esterno dello spazio di elaborazione di SQL Server. Questo snapshot che usa tlist.exe è stato eseguito mentre l'oggetto COM esiste nello spazio di elaborazione dllhost.exe . Si noti che il modulo msado15.dll, ovvero il modulo che contiene l'oggetto COM, viene caricato.

      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
      

Riferimenti

Stored procedure di automazione OLE (Transact-SQL)