2012-11-23 7 views
5

Spero che tu abbia una buona giornata!Accesso a COM in SQL CLR

Ho bisogno dei tuoi consigli per qualcosa che ho pensato a questi ultimi tre giorni. Ho un componente COM scritto in una piattaforma non gestita. Il componente ha un metodo che restituisce una sorta di alcuni dati sensibili e ho bisogno di memorizzare il valore non appena ho capito.

Quello che mi serve è chiamare una UDF per accedere all'oggetto COM e ottenere il valore. Ho provato questo finora e sto ottenendo questa eccezione:

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)

Sembra che la funzione non può vedere il componente COM registrato (80040154). L'assembly clr è registrato come non limitato. Ho provato a chiamare l'UDF con 'sa' o in modalità integrata di Windows. Non c'è differenza.

Questo è il codice per l'inizializzazione del componente COM e il codice sta lavorando bene SQL fuori:

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

Esiste un modo per rendere questi ragazzi che lavorano? In un modo o nell'altro ho bisogno di un UDF chiamare questo oggetto COM o almeno accedere ad alcuni servizi Windows con .NET remoting tramite questa UDF. Ogni suggerimento mi guiderà attraverso questo modo sarebbe apprezzato.

Grazie a tutti.

+0

controllare questo collegamento http://stackoverflow.com/questions/7289620/activator-createinstanceguid-works-inside-vside-but-not-externally –

+1

@DJKRAZE Ho menzionato che il codice funziona bene al di fuori dell'SQL. :) – Rikki

+0

@BehnamEsmaili Sembra che il collegamento abbia risolto il problema di avviare l'oggetto COM al di fuori dell'SQL e non ho alcun problema con quello che ho già menzionato. – Rikki

risposta

4

Suppongo che stai importando l'assembly CLR in SQL Server? Se è così, questo potrebbe essere un problema di piattaforma/architettura. Quale piattaforma è il tuo targeting quando costruisci la tua DLL?

Assicurarsi di creare la DLL sulla piattaforma corretta (ad esempio x86, x64).

Vorrei suggerire di modificare la piattaforma del progetto da "Any CPU" a "X86" in Proprietà progetto, Build/Target di piattaforma in Visual Studio.

Quindi utilizzare "DROP ASSEMBLY", seguito da "CREATE ASSEMBLY", per reimportare quella DLL correttamente compilata.

Si consiglia inoltre di garantire che hai fatto la seguente modifica:

  1. Individuare l'oggetto COM GUID sotto HKey_Classes_Root/Wow6432Node/CLSID.
  2. Una volta individuato, aggiungere un nuovo valore REG_SZ (stringa). Il nome dovrebbe essere AppID e i dati dovrebbero essere lo stesso GUID dell'oggetto COM che hai appena cercato .
  3. Aggiungere una nuova chiave in HKey_Classes_Root/Wow6432Node/AppID. La nuova chiave deve essere chiamata come GUID dell'oggetto COM.
  4. Sotto la nuova chiave appena aggiunta, aggiungere un nuovo valore REG_SZ (stringa), e chiamarlo DllSurrogate. Lascia il valore vuoto.
  5. Creare una nuova chiave in HKey_Local_Machine/Software/Classes/AppID, se non esiste già.
  6. Anche in questo caso, la nuova chiave deve essere chiamata uguale al GUID dell'oggetto dell'oggetto COM. Non è necessario aggiungere valori sotto questa chiave.

Un'altra soluzione potrebbe essere l'utilizzo di SQL clr per richiamare un servizio WCF. Vedere la mia guida al seguente per sapere come fare questo:

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

+0

Signore, avevo controllato anche questo prima di postare la domanda. Non è un mio problema. So esattamente come rilasciare e creare lavori di assemblaggio dare anche un'occhiata ai commenti. @Simon Mourier ha detto il problema della piattaforma e ho appena risposto. :) – Rikki

+1

Anche io penso che tu non stia rispondendo. La prima parte è tutte domande. – Rikki

+0

Ogniqualvolta qualcuno fa una domanda sulla generosità, significa che hanno bisogno di qualcosa di più della semplice congettura e di alcuni semplici dettagli. Mi dispiace signore, ma la tua risposta non mi dà altro. Indipendentemente dall'informazione che ho dato a tutti voi nei commenti sulla piattaforma, la vostra risposta riguarda solo l'istruzione CREATE e DROP. Ho ragione, signore? – Rikki

5

In generale non consiglierei utilizzando oggetti SQL CLR come un ponte tra COM e SQL. Ci sono un sacco di potenziali avvertimenti a partire dalla sicurezza e si concludono con procedure di rilascio molto macchinose, che richiedono l'accesso fisico alla sql box di produzione che può o meno essere facilmente disponibile.

Ho anche notato che stai usando Activator.CreateInstance e poi fornisci il clsid ad esso. Nel tuo post originale intendi che si tratta di un clsid COM. Non sono sicuro che Activator che funziona da AppDomain creato in SQL CLR possa effettivamente trovare l'oggetto per com clsid.

Il modo in cui vorrei provare:

  • Creazione di proxy gestito per il vostro com
  • assicurarsi che sia firmato e messo in GAC
  • provare ad accedere a che è riuscito delega da SQL CLR

Ma dubito seriamente che funzionerà. Qualsiasi soluzione remota WCF/WebServices/Remoting o anche SQL Broker sembra una scelta migliore.

In breve è difficile dire qualcosa di più senza vedere l'attuale .net e sql codez.

+0

+1 Bel tentativo di corpo. Ho provato a utilizzare .NET Remoting in SQL CLR ma sembra complicare di più le cose. Qualche altro suggerimento? Ho bisogno di una soluzione per accedere a COM da SQL CLR. Sono tutti problemi tecnici che ho già provato quasi tutti. Grazie a proposito. – Rikki

+0

Puoi anche provare alcune soluzioni esoteriche come in questo link http://www.codeproject.com/Articles/37140/How-to-Integrate-an-OLE-Object-with-SQL-Server – b0rg

0

Esegui questo cmd su sql select * da sys.dm_clr_properties se la versione net della tua app COM grande di quella restituita cmd funzionerà solo se la versione net è inferiore o uguale !!!