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 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 solo vengono caricati all'interno dello spazio indirizzi di memoria SQL Server processo, ma hanno anche accesso completo a questo spazio di indirizzi di memoria. Pertanto, un oggetto COM caricato nello spazio del processo SQL Server deve rispettare le stesse regole di qualsiasi file DLL. È possibile che un oggetto COM sovrascriva la memoria all'interno del processo di SQL Server o la perdita di risorse, causando instabilità.

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

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

I passaggi seguenti possono essere applicati a qualsiasi oggetto COM basato su DLL creato nello spazio del processo 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 usare per creare un'istanza dell'oggetto COM all'esterno del 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 SQL Server.

  • Se l'oggetto COM viene caricato tramite la sp_OACreate procedura , per impostazione predefinita viene caricato in elaborazione. In questa procedura è tuttavia disponibile un terzo parametro facoltativo che può essere usato per indicare il contesto in cui creare l'oggetto. Se questo parametro non viene specificato, viene usata l'impostazione predefinita cinque (5), che significa 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. Utilizzare una sintassi simile all'esempio seguente per informare in modo esplicito DCOM di eseguire l'oggetto COM fuori processo tramite 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 è 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 in Tutti gli oggetti. Selezionare l'oggetto COM e quindi scegliere CoCreateInstance Flag dal menu 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 l'inserimento della DLL COM all'interno dello spazio del processo.

  • Per aggiornare manualmente il Registro di sistema, seguire questa procedura.

    Avviso

    L'errata modifica del Registro di sistema tramite l'editor o un altro metodo può causare seri 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. IL CLSID è un numero a 128 bit e considerato un GUID (Globally Unique Identifier) usato per identificare in modo univoco il componente, il modulo o il file che contiene questo oggetto COM. Quando si creano oggetti COM usando le stored procedure di Automazione OLE, il primo parametro della stored procedure è un identificatore a livello di codice oppure il ProgID dell'oggetto OLE viene usato per derivare il CLSID. Questa stringa di caratteri descrive la classe dell'oggetto OLE e presenta il formato seguente:

      OLEComponent.Object
      
    2. È possibile usare l'identificatore a livello di codice per trovare l'identificatore di classe per un oggetto COM.

      Aprire il Editor del Registro di sistema (regedit.exe) e nella HKEY_CLASSES_ROOT chiave utilizzare il Find metodo per individuare una chiave con il nome di <OLEComponent.Object>. Lo si troverà ad altri livelli, ma dovrebbe trovarsi al 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 la 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 Find in Registry Editor (nel menu Modifica) e incollare il GUID nella finestra di dialogo Trova. Assicurarsi di aver trovato l'interfaccia corretta controllando la sottochiave InprocServer32 sotto questa chiave, che punta al percorso del file DLL COM. Se è presente una chiave TypeLib, controllare questo valore GUID. Questa operazione dovrebbe essere diversa da quella annotata nel passaggio 1. In caso contrario, si dispone del GUID TypeLib e non del GUID per l'oggetto COM. Il valore della OLEComponent.Object.1sottochiave ProgID sarà . Quello alla fine è solo per questo esempio e viene usato per le informazioni sul controllo delle versioni.

    4. Mentre nella sottochiave InprocServer32 del GUID, verificare che esista un ThreadingModel valore e che sia impostato su Entrambi o Libero per assicurarsi che il marshalling comprenda il modello di threading dell'oggetto COM per abilitare l'esecuzione di COM all'esterno dello spazio del processo SQL Server. Se non è presente un ThreadingModel valore o è impostato su Apartment, l'istanza dell'oggetto COM potrebbe non essere coerente.

      Nota

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

    5. Evidenziare il numero GUID/sottochiave sotto la HKEY_CLASSES_ROOT\CLSID chiave. Dal menu Modifica selezionare Nuovo 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'identificatore dell'applicazione AppID viene usato da DCOM per associare la DLL a un file eseguibile.

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

    8. Evidenziare il nome guid. Dal menu Modifica selezionare Nuovo e quindi selezionare Valore stringa. Nella colonna Nome digitare dllSurrogate.

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

    9. Chiudere l'Editor del Registro di sistema. Fare clic sul pulsante Start e scegliere Esegui. Nella finestra di dialogo Esegui digitare DCOMCNFG.

      Premere INVIO per aprire la finestra di dialogo Proprietà configurazione COM distribuita . 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 se l'input delle chiavi del Registro di sistema non è corretto, 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: L'esecuzione del server non è riuscita

    11. Testare e verificare se è in esecuzione il file dllhost.exe e caricare l'oggetto COM nel relativo spazio di elaborazione. Ciò richiede che Il Resource Kit di Windows NT 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 i relativi identificatori di processo associati o identificatori di processo (PID). Nello script Transact-SQL in cui sp_OACreate viene eseguito e dopo l'esecuzione della chiamata, ma prima della fine dello script, 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 . Si noti il dllhost.exe PID. Eseguire di nuovotlist.exe e passare il PID come parametro. Vengono visualizzate le DLL caricate all'interno dello spazio del processo dllhost.exe . L'oggetto COM basato su DLL deve essere elencato come in esecuzione all'interno di questo processo. Al termine dello script, l'esecuzione ditlist.exe rivela nuovamente che il processo didllhost.exe non è più in esecuzione.

      Nell'output di esempio seguente, ADODB. L'oggetto connessione viene creato all'esterno dello spazio del processo SQL Server. Questo snapshot che usa tlist.exe è stato eseguito mentre l'oggetto COM era presente nello spazio del processo 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)