Udostępnij za pośrednictwem


Uruchamianie obiektu COM opartego na bibliotekach DLL poza procesem programu SQL Server

W tym artykule opisano sposób uruchamiania obiektu COM opartego na bibliotekach DLL poza procesem programu SQL Server.

Oryginalna wersja produktu: SQL Server
Oryginalny numer KB: 198891

Podsumowanie

Program Microsoft SQL Server umożliwia ładowanie i uruchamianie niestandardowych obiektów modelu obiektów składników (COM) za pomocą zestawu procedur składowanych automatyzacji OLE lub rozszerzonych procedur składowanych. Domyślnie obiekty COM oparte na bibliotekach DLL są ładowane jak na serwerze przetwarzania, co oznacza, że obiekty COM nie tylko są ładowane w przestrzeni adresowej pamięci procesu programu SQL Server, ale mają również pełny dostęp do tej przestrzeni adresowej pamięci. W związku z tym obiekt COM załadowany w przestrzeni procesów programu SQL Server musi być zgodny z tymi samymi regułami co dowolny plik DLL. Istnieje możliwość, że obiekt COM może zastąpić pamięć w procesie programu SQL Server lub wycieku zasobów, co powoduje niestabilność.

Jeśli istnieje podejrzenie, że obiekt COM może mieć wpływ na niezawodność procesu programu SQL Server, możesz użyć kroków opisanych w tym artykule, aby utworzyć wystąpienie obiektu COM poza obszarem procesów programu SQL Server. Implementacja specyfikacji modelu DCOM (Distributed Component Object Model) przezroczystości lokalizacji w systemie operacyjnym zapewnia możliwość uruchamiania obiektu COM opartego na bibliotekach DLL poza przestrzenią procesów programu SQL Server.

Proces uruchamiania obiektu COM opartego na bibliotekach DLL poza przestrzenią adresową głównej aplikacji jest nazywany komunikacji wirtualnej. Komunikacja zdalna wymaga, aby inny plik wykonywalny był procesem zastępczym zamiast pliku wykonywalnego programu SQL Server. Domyślny plik wykonywalny używany przez program DCOM Service Control Manager (rpcss.exe) nosi nazwę dllhost.exe. Struktura obsługi modelu DCOM używa pliku dllhost.exe do załadowania biblioteki DLL do jej przestrzeni procesowej, a następnie używa par proxy/wycinków do marshalingu żądanego interfejsu w sposób niewidoczny dla klienta, co w tym przypadku jest programem SQL Server. Ten plik wykonywalny może akceptować wiele żądań interfejsu/metody jednocześnie. Po zakończeniu korzystania z interfejsu program DCOM Service Control Manager (SCM) zarządza czyszczeniem i zwalnianiem pliku dllhost.exe . Obiekty COM nie powinny zachowywać informacji o stanie między wystąpieniami.

Poniższe kroki mogą dotyczyć dowolnego obiektu COM opartego na bibliotekach DLL, który jest tworzony w przestrzeni procesów programu SQL Server, niezależnie od tego, czy jest tworzony za pomocą sp_OACreate , czy rozszerzonej procedury składowanej.

Więcej informacji

Informacje o dwóch podstawowych metodach, których można użyć do utworzenia wystąpienia obiektu COM poza procesem.

Klient COM żąda komunikacji wirtualnej obiektu

Zmieniając sposób wywoływania obiektu COM, można zażądać utworzenia obiektu poza przestrzenią adresową programu SQL Server.

  • Jeśli obiekt COM jest ładowany przy użyciu sp_OACreate procedury, domyślnie jest ładowany w procesie. Istnieje jednak opcjonalny trzeci parametr dla tej procedury, którego można użyć do wskazania kontekstu, w którym ma zostać utworzony obiekt. Jeśli ten parametr nie zostanie określony, zostanie użyte domyślne ustawienie pięciu (5), co oznacza uruchomienie obiektu wewnątrz lub poza procesem. Należy zmienić parametr na cztery (4), który wskazuje dcOM, że ten składnik ma być uruchamiany jako lokalny plik wykonywalny. Użyj składni podobnej do poniższego przykładu, aby jawnie poinformować dcOM o uruchomieniu obiektu COM poza procesem sp_OACreate przy użyciu procedury składowanej:

    DECLARE @object int
    DECLARE @hr int
    EXEC @hr = sp_OACreate 'SQLOLE.SQLServer', @object OUT, 4
    
  • Jeśli obiekt COM jest tworzony w ramach rozszerzonej procedury składowanej, trzeci parametr CoCreateInstance lub CoCreateInstanceEx można go zmienić na CLSCTX_LOCAL_SERVER. Jest to pokazane w poniższym przykładzie kodu przy użyciu polecenia CoCreateInstance:

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

Modyfikowanie rejestru w celu wymuszenia komunikacji z obiektem

Jeśli nie możesz zmodyfikować klienta COM, aby zażądał, aby obiekt został utworzony poza procesem, istnieją dwie różne metody wymuszenia utworzenia obiektu poza procesem.

  • Użyj przeglądarki obiektów OLE/COM (oleview.exe) dostarczanej z językiem Visual C++ i znajdź identyfikator ProgID w postaci w obszarze OLEComponent.Object Wszystkie obiekty. Wybierz obiekt COM, a następnie z menu Obiekt wybierz pozycję CoCreateInstance Flagi. Upewnij się, że wybrano tylko CLSCTX_LOCAL_SERVER opcję . Następnie na kartach Implementacja i Serwer inproc wybierz pozycję Użyj procesu zastępczego i pozostaw pole Ścieżka do niestandardowego zastępczego pustego, co umożliwia załadowanie pliku dllhost.exe i bibliotekę DLL COM przeniesioną w przestrzeni procesu.

  • Wykonaj poniższe kroki, aby ręcznie zaktualizować rejestr.

    Ostrzeżenie

    Niepoprawne zmodyfikowanie rejestru przy użyciu Edytora rejestru lub innej metody może stać się przyczyną poważnych problemów. Problemy te mogą spowodować konieczność ponownej instalacji systemu operacyjnego. Firma Microsoft nie może zagwarantować, że rozwiązanie tych problemów będzie możliwe. Rejestr można modyfikować na własną odpowiedzialność.

    1. Uzyskaj identyfikator klasy (CLSID) obiektu COM. CLSID jest 128-bitową liczbą i uważany za unikatowy identyfikator globalny (GUID), który jest używany do unikatowego identyfikowania składnika, modułu lub pliku zawierającego ten obiekt COM. Podczas tworzenia obiektów COM przy użyciu procedur składowanych automatyzacji OLE pierwszy parametr procedury składowanej jest identyfikatorem programowym lub progID obiektu OLE jest używany do uzyskiwania identyfikatora CLSID. Ten ciąg znaków opisuje klasę obiektu OLE i ma następującą postać:

      OLEComponent.Object
      
    2. Możesz użyć identyfikatora programowego, aby znaleźć identyfikator klasy dla obiektu COM.

      Otwórz Edytor rejestru (regedit.exe) i w kluczu HKEY_CLASSES_ROOT użyj Find metody , aby zlokalizować klucz o nazwie <OLEComponent.Object>. Znajdziesz go na innych poziomach, ale powinien on znajdować się na poziomie bezpośrednio poniżej HKEY_CLASSES_ROOT. Po zlokalizowaniu klucza rozwiń folder nazwy klucza i powinien zostać wyświetlony podklucz o nazwie CLSID. Wybierz ten folder, aby wyświetlić wartości w tym kluczu. Po prawej stronie ekranu znajduje się tytuł o nazwie Default. Dane dla tego klucza powinny mieć następującą postać:

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

      Zanotuj tę wartość lub skopiuj ją do Notatnika. Uwzględnij nawiasy kwadratowe.

    3. Przejdź pod HKEY_CLASSES_ROOT\CLSID klucz i znajdź podklucz z tym numerem GUID. Po zaznaczeniu HKEY_CLASSES_ROOT\CLSID klucza możesz użyć funkcji Find w Edytorze rejestru (w menu Edycja ) i wkleić identyfikator GUID w oknie dialogowym Znajdowanie . Upewnij się, że został znaleziony odpowiedni interfejs, sprawdzając podklucz InprocServer32 pod tym kluczem, który wskazuje lokalizację pliku DLL COM. Jeśli istnieje klucz TypeLib, sprawdź tę wartość identyfikatora GUID. Powinno to być inne niż to, co zanotowano w kroku 1. W przeciwnym razie masz identyfikator GUID biblioteki TypeLib, a nie identyfikator GUID dla obiektu COM. Podklucz ProgID będzie miał wartość OLEComponent.Object.1. Ten na końcu jest przeznaczony tylko dla tego przykładu i jest używany do przechowywania informacji o wersji.

    4. W podkluczu InprocServer32 identyfikatora GUID upewnij się, że ThreadingModel istnieje wartość i że jest ustawiona na wartość Zarówno, jak i Bezpłatna, aby upewnić się, że marshaling rozumie model wątków obiektu COM, aby umożliwić wykonywanie modelu COM z przestrzeni procesowej programu SQL Server. Jeśli nie ThreadingModel ma wartości lub jest ustawiona na Wartość Apartament, wystąpienie obiektu COM może nie być spójne.

      Uwaga 16.

      Jeśli dodasz ThreadingModel wartość, przed wdrożeniem upewnij się, że testujesz obiekt COM.

    5. Wyróżnij numer/podklucz identyfikatora GUID pod kluczem HKEY_CLASSES_ROOT\CLSID . Z menu Edycja wybierz pozycję Nowy, a następnie wybierz pozycję Wartość ciągu. W kolumnie Nazwa wpisz AppID.

    6. Naciśnij ENTER , a następnie wstaw identyfikator klasy lub numer GUID zanotowany z kroku 1 jako wartość. Identyfikator GUID powinien znajdować się wewnątrz nawiasów klamrowych, jak w poniższym przykładzie:

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

      Identyfikator aplikacji AppID jest używany przez dcOM do skojarzenia biblioteki DLL z plikiem wykonywalnym.

    7. Dodaj nowy podklucz HKEY_CLASSES_ROOT\AppID pod elementem i ustaw jego nazwę na ten sam identyfikator klasy lub numer GUID z nawiasami kwadratowymi wstawionym w poprzednim kroku.

    8. Wyróżnij nazwę identyfikatora GUID. Z menu Edycja wybierz pozycję Nowy, a następnie wybierz pozycję Wartość ciągu. W kolumnie Nazwa wpisz dllSurrogate.

      Pozostaw kolumnę Dane pustą dla tej wartości. Ponieważ kolumna danych jest pusta, informuje DCOM o uruchomieniu domyślnego pliku wykonywalnego, dllhost.exe i załadowaniu obiektu COM w przestrzeni procesu.

    9. Zamknij Edytor rejestru. Kliknij przycisk Start, a następnie wybierz pozycję Uruchom. W oknie dialogowym Uruchamianie wpisz DCOMCNFG.

      Naciśnij ENTER, aby otworzyć okno dialogowe Właściwości konfiguracji rozproszonego modelu COM. Kliknij kartę Właściwości domyślne i upewnij się, że wybrano opcję Włącz rozproszony com na tym komputerze. Jeśli tak nie jest, wybierz ją, a następnie wybierz pozycję Zastosuj.

    10. Upewnij się, że konto użytkownika systemu Windows NT, w ramach którego działa program SQL Server, ma uprawnienie Pełna kontrola na kluczach rejestru dla tego obiektu. Jeśli uprawnienia nie są wystarczające lub klucze rejestru są niepoprawnie wprowadzane, podczas tworzenia obiektu COM mogą wystąpić następujące błędy:

      Informacje o błędzie automatyzacji OLE
      HRESULT: 0x80040154
      Źródło: Rozszerzona procedura ODSOLE
      Opis: Klasa nie jest zarejestrowana

      Informacje o błędzie automatyzacji OLE
      HRESULT: 0x80070005
      Źródło: Rozszerzona procedura ODSOLE
      Opis: Odmowa dostępu.

      Informacje o błędzie automatyzacji OLE
      HRESULT: 0x80080005
      Źródło: Rozszerzona procedura ODSOLE
      Opis: Wykonanie serwera nie powiodło się

    11. Przetestuj i sprawdź, czy jest uruchomiony plik dllhost.exe i ładowanie obiektu COM w jego przestrzeni procesowej. Wymaga to, aby zestaw Zasobów Windows NT był na komputerze z systemem Windows NT, na którym działa program SQL Server. Otwórz wiersz polecenia i w wierszu polecenia uruchom plik tlist.exe , który zawiera wszystkie procesy i skojarzone identyfikatory procesów lub identyfikatory procesów (PID). W skrypcie Języka Transact-SQL, w którym sp_OACreate jest uruchamiane i po wykonaniu tego wywołania, ale przed zakończeniem skryptu użyj następującego polecenia, aby opóźnić ukończenie skryptu przez dodatkowe 20 sekund:

      WAITFOR DELAY '000:00:20'
      

      Uruchom skrypt i natychmiast przejdź do wiersza polecenia i uruchom plik tlist.exe . Zanotuj dllhost.exe PID. Uruchom ponownie tlist.exe i przekaż identyfikator PID jako parametr. Spowoduje to wyświetlenie bibliotek DLL załadowanych w przestrzeni procesów dllhost.exe . Obiekt COM oparty na bibliotekach DLL powinien być wymieniony jako uruchomiony w ramach tego procesu. Po powrocie skryptu uruchomienie tlist.exe ponownie pokazuje, że proces dllhost.exe nie jest już uruchomiony.

      W poniższych przykładowych danych wyjściowych ADODB. Obiekt połączenia jest tworzony poza przestrzenią procesów programu SQL Server. Ta migawka używająca tlist.exe została wykonana, gdy obiekt COM istniał w przestrzeni procesu dllhost.exe . Zwróć uwagę, że moduł msado15.dll, który jest modułem zawierającym obiekt COM, jest załadowany.

      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
      

Informacje

Procedury składowane automatyzacji OLE (Transact-SQL)