2012-11-23 1 views
5

Надеюсь, у вас у вас хороший день!Доступ к COM в SQL CLR

Мне нужны ваши рекомендации относительно того, о чем я думал об этих последних трех днях. У меня есть компонент COM, написанный на неуправляемой платформе. У компонента есть метод, который возвращает вид некоторых конфиденциальных данных, и мне нужно сохранить значение, как только я его получу.

Мне нужно, чтобы вызвать UDF для доступа к COM-объекту и получить значение. Я попытался это до сих пор, и я получаю это исключение:

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)

кажется, что функция не может видеть зарегистрированный COM компонента (80040154). Узел clr зарегистрирован как неограниченный. Я попытался вызвать UDF с помощью «sa» или в режиме Windows Integrated. Нет никакой разницы.

Это код для инициализации компонента COM и код работает штраф за пределами SQL:

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

Есть в любом случае, чтобы это работало, ребята? Так или иначе мне нужно, чтобы UDF вызывал этот COM-объект или, по крайней мере, обращался к некоторым службам Windows с удаленным .NET через этот UDF. Каждое предложение подскажет мне таким образом.

Спасибо всем.

+0

проверить эту ссылку http://stackoverflow.com/questions/7289620/activator-createinstanceguid-works-inside-vside-but-not-externally –

+1

@DJKRAZE Я уже упоминал, что код отлично работает за пределами SQL. :) – Rikki

+0

@BehnamEsmaili Кажется, что ссылка решила проблему инициирования COM-объекта вне SQL, и я не имею проблемы с этим, как я уже упоминал. – Rikki

ответ

4

Я предполагаю, что вы импортируете свою сборку CLR в SQL Server? Если это так, это может быть проблемой платформы/архитектуры. Какова платформа для вашего таргетинга при создании вашей DLL?

Убедитесь, что вы создаете свою DLL на правильной платформе (например, x86, x64).

Я предлагаю вам изменить платформу вашего проекта с "Any CPU" до "X86" в свойствах проекта, сборки/цели платформы в Visual Studio.

Затем используйте "DROP ASSEMBLY", а затем "CREATE ASSEMBLY", чтобы повторно импортировать правильно построенную dll.

Вы также можете убедиться, что вы сделали следующее изменение:

  1. Найдите ваш COM объект GUID под HKEY_CLASSES_ROOT/Wow6432Node/CLSID.
  2. После размещения добавьте новое значение REG_SZ (string). Имя должно быть AppID, и данные должны быть тем же самым идентификатором объекта COM объекта, который вы только что нашли .
  3. Добавить новый ключ под HKey_Classes_Root/Wow6432Node/AppID. Новый ключ должен называться так же, как GUID объекта COM.
  4. Под новым ключом, который вы только что добавили, добавьте новое значение REG_SZ (string), и назовите его DllSurrogate. Оставьте значение пустым.
  5. Создайте новый ключ под HKey_Local_Machine/Software/Classes/AppID, если он еще не существует.
  6. Опять же, новый ключ должен называться так же, как и идентификатор объекта COM. Никакие значения не нужно добавлять под этим ключом.

Другим решением является использование SQL clr для вызова службы WCF. Смотрите мое руководство в следующих за то, как сделать это:

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

+0

Сэр я тоже проверил этот вопрос, прежде чем публиковать вопрос. Это не моя проблема. Я точно знаю, как отбрасывать и создавать сборку, а также просматривать комментарии. @Simon Mourier сказал, что проблема с платформой, и я просто ответил на это. :) – Rikki

+1

Также я думаю, что вы не отвечаете. Первая часть - все вопросы. – Rikki

+0

Всякий раз, когда кто-то задает вопрос о щедрости, это означает, что им нужно что-то большее, чем просто угадать и некоторые простые детали. Простите, сэр, но ваш ответ не дает мне больше. Независимо от информации, которую я дал вам всем в комментариях к платформе, ваш ответ - это только оператор CREATE и DROP. Я прав, сэр? – Rikki

5

В общем, я бы не рекомендовал использовать объекты SQL CLR в качестве моста между COM и SQL. Существует множество потенциальных предостережений, начиная от безопасности и заканчивая очень громоздкими процедурами выпуска, требующими физического доступа к окну sql производства, который может быть или не быть легко доступен.

Я также заметил, что вы используете Activator.CreateInstance, а затем передаете ему clsid. В вашем исходном сообщении вы подразумеваете, что это COM clsid. Я не уверен, что Activator, работающий из AppDomain, созданного в SQL CLR, может фактически найти объект для com clsid.

Как я хотел бы попробовать:

  • Создание управляемых прокси для ком
  • убедитесь, что он подписал и помещен в GAC
  • Попробуйте получить доступ, что управляемый прокси из SQL CLR

Но я серьезно сомневаюсь, что это сработает. Любое удаленное решение WCF/WebServices/Remoting или даже SQL-брокер выглядит лучше.

Одним словом, трудно сказать ничего более, не видя фактических .net и sql-кода.

+0

+1 Хорошее тело. Я попытался использовать .NET Remoting в SQL CLR, но, похоже, это усложняет ситуацию. Любые другие предложения? Мне нужно решение для доступа к COM из SQL CLR. Все это технические проблемы, которые я уже пробовал большинство из них. Спасибо, кстати. – Rikki

+0

Вы также можете попробовать некоторые эзотерические решения, как в этой ссылке http://www.codeproject.com/Articles/37140/How-to-Integrate-an-OLE-Object-with-SQL-Server – b0rg

0

Запуск этого cmd на sql выберите * из sys.dm_clr_properties, если чистая версия вашего COM-приложения, отличного от возвращаемого cmd, будет работать только в том случае, если чистая версия меньше или равна!

 Смежные вопросы

  • Нет связанных вопросов^_^