2012-11-23 36 views
5

Mam nadzieję, że wszyscy się dobrze bawili!Uzyskiwanie dostępu do COM w języku SQL CLR

Potrzebuję twoich rekomendacji dla czegoś, co myślałem o tych trzech ostatnich dniach. Mam komponent COM napisany na niezarządzanej platformie. Komponent ma metodę, która zwraca pewien rodzaj poufnych danych i muszę zapisać wartość, gdy tylko ją dostanę.

Potrzebuję wywołać UDF, aby uzyskać dostęp do obiektu COM i uzyskać jego wartość. Próbowałem to tak daleko, a ja otrzymuję ten wyjątek:

Msg 6522, Level 16, State 2, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "GetRate": System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {D039A99F-5D45-42C7-A53C-507913D8C6D6} failed due to the following error: 80040154.
System.Runtime.InteropServices.COMException:
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at UserDefinedFunctions.GetRate(SqlString Source_Currency_Name, SqlString Destination_Currency_Name, SqlMoney Amount, SqlBoolean Mode)

Wydaje się, że ta funkcja nie może zobaczyć zarejestrowaną komponent COM (80040154). Zespół Clr jest zarejestrowany jako nieograniczony. Próbowałem wywołać UDF z "sa" lub w trybie zintegrowanym systemu Windows. Nie ma różnicy.

Jest to kod dla inicjalizacji komponentu COM i kod działa poprawnie SQL poza:

Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("D039A99F-5D45-42C7-A53C-507913D8C6D6"), true)) 

Czy mimo to zrobić to chłopaki działa? Tak czy inaczej potrzebuję wywołania UDF tego obiektu COM lub przynajmniej dostępu do niektórych usług Windows z .NET remoting poprzez ten UDF. Każda sugestia poprowadzi mnie tą drogą będzie doceniona.

Dziękuję wszystkim.

+0

sprawdź ten link http://stackoverflow.com/questions/7289620/activator-createinstanceguid-works-inside-vside-but-not-externally –

+1

@DJKRAZE Wspomniałem, że kod działa dobrze poza SQL. :) – Rikki

+0

@BehnamEsmaili Wygląda na to, że łącze rozwiązało problem inicjowania obiektu COM poza SQL i nie mam z tym problemu, jak już wspomniałem. – Rikki

Odpowiedz

4

Zgaduję, że importujesz swój zestaw CLR do SQL Server? Jeśli tak, może to być problem z platformą/architekturą. Jaką platformę kierujesz do swojej biblioteki DLL?

Upewnij się, że budujesz bibliotekę DLL na odpowiedniej platformie (np. X86, x64).

Proponuję zmodyfikować platformę swojego projektu z "Any CPU" na "X86" we właściwościach projektu, Zbuduj/Platforma docelowa w Visual Studio.

Następnie użyj "DROP ASSEMBLY", a następnie "CREATE ASSEMBLY", aby ponownie zaimportować poprawnie zbudowaną bibliotekę dll.

Można również mieć pewność, że po dokonaniu następujących zmian:

  1. zlokalizować obiekt COM GUID pod HKEY_CLASSES_ROOT/Wow6432Node/CLSID.
  2. Po zlokalizowaniu dodaj nową wartość REG_SZ (ciąg). Nazwa powinna być AppID, a dane powinny być tym samym identyfikatorem GUID obiektu COM, który został właśnie przeszukany przez .
  3. Dodaj nowy klucz pod HKey_Classes_Root/Wow6432Node/AppID. Nowy klucz powinien być nazywany identyfikatorem GUID obiektu COM.
  4. Pod nowo dodanym kluczem dodaj nową wartość REG_SZ (string), i nazwij ją DllSurrogate. Pozostaw wartość pustą.
  5. Utwórz nowy klucz pod HKey_Local_Machine/Software/Classes/AppID, jeśli to jeszcze nie istnieje.
  6. Ponownie, nowy klucz powinien być nazywany identyfikatorem GUID obiektu COM . Do tego klucza nie trzeba dodawać żadnych wartości.

Innym rozwiązaniem byłoby użycie SQL clr do wywołania usługi WCF. Zobacz mój przewodnik, co następuje po tym, jak to zrobić:

http://www.codeproject.com/Articles/21149/Invoking-a-WCF-Service-from-a-CLR-Trigger

+0

Przepraszam, że sprawdziłem to również przed opublikowaniem pytania. To nie mój problem. Wiem dokładnie, w jaki sposób upuszczanie i tworzenie prac montażowych również uwzględnia komentarze. @Simon Mourier powiedział problem z platformą i właśnie odpowiedziałem na to. :) – Rikki

+1

Też myślę, że nie odpowiadasz. Pierwsza część to wszystkie pytania. – Rikki

+0

Ilekroć ktoś stawia pytanie o nagrodę, oznacza to, że potrzebują czegoś więcej niż tylko zgadywania i kilku prostych szczegółów. Przykro mi, proszę pana, ale twoja odpowiedź nie daje mi więcej. Niezależnie od informacji, które przekazałem wam wszystkim na temat komentarzy na temat platformy, wasza odpowiedź dotyczy właśnie instrukcji CREATE i DROP. Czy mam rację, proszę pana? – Rikki

5

Ogólnie nie polecam za pomocą obiektów SQL CLR jako pomost między COM i SQL. Istnieje wiele potencjalnych zastrzeżeń, począwszy od bezpieczeństwa, kończąc na bardzo uciążliwych procedurach wydawania, wymagających fizycznego dostępu do SQL Server, który może, ale nie musi być łatwo dostępny.

Zauważyłem również, że używasz Activator.CreateInstance, a następnie dostarczasz clsid do niego. W oryginalnym poście sugerujesz, że jest to COM clsid. Nie jestem pewien, czy aktywator działający z AppDomain utworzony w SQL CLR może faktycznie znaleźć obiekt dla comclsid.

Sposób Chciałbym spróbować:

  • Tworzenie zarządzanego serwera proxy dla com
  • upewnić się, że podpisane i umieszczone w GAC
  • Spróbuj uzyskać dostęp, że udało pełnomocnika z SQL CLR

Ale poważnie wątpię, że to zadziała. Każde zdalne rozwiązanie WCF/WebServices/Remoting lub nawet SQL Broker wydaje się lepszym rozwiązaniem.

W skrócie, trudno powiedzieć coś więcej, nie widząc rzeczywistego .net i sql codez.

+0

+1 Przyjemna próba ciała. Próbowałem używać .NET Remoting w SQL CLR, ale wydaje się to bardziej skomplikowane. Jakieś inne sugestie? Potrzebuję rozwiązania dostępu do COM z SQL CLR. To wszystko są kwestie techniczne, które już wcześniej wypróbowałem. Dziękuję przy okazji. – Rikki

+0

Możesz także wypróbować kilka ezoterycznych rozwiązań, jak w tym linku http://www.codeproject.com/Articles/37140/How-to-Integrate-an-OLE-Object-w-SQL-Server – b0rg

0

Uruchom ten cmd na sql select * from sys.dm_clr_properties, jeśli wersja net Twojej aplikacji COM świetnie z tym, że powróci tylko cmd będzie działać, jeśli wersja sieciowa jest mniejsza lub równa !!!