Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在sqlclr中访问COM_C#_Sql Server 2008_Com_User Defined Functions_Sqlclr - Fatal编程技术网

C# 在sqlclr中访问COM

C# 在sqlclr中访问COM,c#,sql-server-2008,com,user-defined-functions,sqlclr,C#,Sql Server 2008,Com,User Defined Functions,Sqlclr,希望大家今天过得愉快 这三天我一直在想的事情,我需要你的建议。我有一个COM组件是在非托管平台上编写的。该组件有一个返回某种敏感数据的方法,我需要在获得该值后立即存储该值 我需要的是调用一个UDF来访问COM对象并获取值。到目前为止,我已经尝试过了,我得到了一个例外: Msg 6522,第16级,状态2,第1行 在执行用户定义例程或聚合“GetRate”期间发生.NET Framework错误: System.Runtime.InteropServices.COMException:检索COM类

希望大家今天过得愉快

这三天我一直在想的事情,我需要你的建议。我有一个COM组件是在非托管平台上编写的。该组件有一个返回某种敏感数据的方法,我需要在获得该值后立即存储该值

我需要的是调用一个UDF来访问COM对象并获取值。到目前为止,我已经尝试过了,我得到了一个例外:

Msg 6522,第16级,状态2,第1行
在执行用户定义例程或聚合“GetRate”期间发生.NET Framework错误: System.Runtime.InteropServices.COMException:检索COM类 具有CLSID的组件的工厂 {D039A99F-5D45-42C7-A53C-507913D8C6D6}由于以下原因失败 错误:80040154。
System.Runtime.InteropServices.COMException:
在System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔值 publicOnly、Boolean noCheck、Boolean&canBeCached、, RuntimeMethodHandle&ctor、Boolean&bNeedSecurityCheck)
在System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔型 fillCache)
位于System.RuntimeType.CreateInstanceImpl(布尔publicOnly、布尔skipVisibilityChecks、布尔fillCache)
在System.Activator.CreateInstance(类型,布尔非公共)
在UserDefinedFunctions.GetRate(SqlString源代码\货币\名称,SqlString 目的地\货币\名称、SqlMoney金额、SqlBoolean模式)

函数似乎看不到已注册的COM组件(80040154)。clr程序集已注册为非限制程序集。我尝试使用“sa”或Windows集成模式调用UDF。没有区别

这是初始化COM组件的代码,该代码在SQL之外工作正常

Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("D039A99F-5D45-42C7-A53C-507913D8C6D6"), true))
有没有办法让这些人工作?无论如何,我需要一个UDF调用这个COM对象,或者至少通过这个UDF访问一些带有.NET远程处理的windows服务。每一个建议都会引导我走这条路,我将不胜感激


谢谢大家。

我猜你们是在将CLR程序集导入SQL Server?如果是这样,这可能是一个平台/架构问题。构建DLL时,您的目标平台是什么

确保根据正确的平台(即x86、x64)构建DLL

我建议您在Visual Studio中的项目属性中,将项目的平台从“任意CPU”修改为“X86”

然后使用
“DROP ASSEMBLY”
,然后使用
“CREATE ASSEMBLY”
,重新导入正确构建的dll

您可能还希望确保已进行以下更改:

  • 在下面找到COM对象GUID HKey_Classes_Root/Wow6432Node/CLSID
  • 找到后,添加一个新的REG_SZ(字符串)值。名字应该是 AppID和数据应该与您刚才使用的COM对象GUID相同 寻找
  • 在HKey_Classes_Root/Wow6432Node/AppID下添加一个新密钥。新钥匙 应与COM对象GUID调用相同
  • 在刚才添加的新键下,添加一个新的REG_SZ(字符串)值, 叫它DllSurrogate。将该值保留为空
  • 如果需要,请在HKey_Local_Machine/Software/Classes/AppID下创建新密钥 它还不存在
  • 同样,新键的调用应该与COM对象的相同 GUID。不需要在此键下添加任何值
  • 另一个解决方案是使用SQLCLR调用WCF服务。有关如何执行此操作,请参见下面的指南:


    一般来说,我不建议使用SQL CLR对象作为COM和SQL之间的桥梁。这里有很多潜在的警告,从安全性开始,到非常繁琐的发布过程结束,需要物理访问生产sql框,这可能很容易获得,也可能不容易获得

    我还注意到您正在使用Activator.CreateInstance,然后向其提供clsid。在您最初的帖子中,您暗示它是一个COM clsid。我不确定在SQL CLR中创建的AppDomain中工作的Activator是否能够找到com clsid的对象

    我尝试的方式是:

    • 为com创建托管代理
    • 确保签名并放入gac
    • 尝试从SQL CLR访问该托管代理
    但我严重怀疑它会起作用。任何远程处理解决方案WCF/WebServices/remoting甚至sqlbroker似乎都是更好的选择


    简言之,如果没有看到实际的.net和sql codez,就很难说出更多

    如果COM应用程序的网络版本“太棒了”,请在sys.dm_clr_属性中的sql select*上运行此cmd。只有当网络版本小于或等于时,返回cmd才会起作用

    检查这个链接@DJKRAZE我已经提到,代码在SQL之外运行良好。:)@BehnamEsmaili看来链接已经解决了在SQL外部启动COM对象的问题,我已经提到过,我对此没有问题。您是否检查过异常是否存在内部异常?没错,但“外部SQL”可能是与“内部SQL”不同的进程位先生,我在发帖之前也检查过这个问题。那不是我的问题。我确切地知道drop和create assembly是如何工作的,还可以看看注释@Simon Mourier提到了平台问题,我刚刚回答了这个问题。:)我还认为你没有回答。第一部分是所有的问题。每当有人对悬赏提出问题,这意味着他们需要的不仅仅是猜测和一些简单的细节。对不起,先生,你的回答没有给我更多的信息。不管我在关于该平台的评论中给了你们所有人多少信息,你们的答案只是关于创建和删除语句。我说得对吗,先生?我明白你的意思了。我说了对不起,但你的回答根本不是我的问题,因为检查目标平台和确保正确的装配注册是我检查v的一些简单错误