在C#下利用COM组件提供给第三方调用,无需强命名,通过CurrentDomain_AssemblyResolve方式的解决的过程

来源:互联网 发布:怎么分析一只股票数据 编辑:程序博客网 时间:2024/05/17 02:51

背景:

         因项目需要,在我们的系统中增加一个COM组件供第三方调用,这个DLL我们命名为:ShareUtilCOM.DLL(C#),他是一个COM组件,依赖SafeUtilCPlus.DLL(C++ CLR);SafeUtilCPlus.DLL主要是封装参数和加密算法;SafeUtilCPlus.DLL是通过C++ CLR编写,调用系统中的Core.util.DLL(C#);VS环境为VS2010;XP下,WIN7下均运行正常。

     

       一般情况下,对于ShareUtilCOM.DLL这个COM我们强签名后,通过regasm和gasutil后可以给第三方程序使用,但是强签名的DLL应用的所有DLL必须都要强签名,但是因为系统中依赖的DLL好多第三方库都没有强签名,所以我果断放弃了强签名的做法,转而寻求其他方法,最终通过CurrentDomain_AssemblyResolve方式实现了。

OKOK,不废话了,我们 现在来整理下

      第三方程序 我们叫:CallCom.exe;C#的COM组件叫:ShareUtilCOM.DLL,C++ CLR的DLL叫:SafeUtilCPlus.DLL,而核心的C#DLL叫:Core.util.DLL(C#)



其中SafeUtilCPlus.dll的配置

常规菜单:


ShareUtilCOM.DLL(C#)应用程序--》应用程序集

ShareUtilCOM.DLL(C#)生成



其他的均默认

ShareUtilCOM.DLL(C#)的

 [Guid("10B31ECF-9799-4A9C-AFBB-48C231CB3A55")]
    [ComDefaultInterface(typeof(IShareUtilCOM))]
    [ComSourceInterfaces(typeof(IShareUtilCOM))]
    public class ShareUtilCOM: IShareUtilCOM
    {
        static ShareUtilCOM()
        {
            //解决COM组件不进行强签名也可以调用的问题,调用程序必须要与本DLL在同一个目录下,而本DLL依赖的DLL可以通过如下方式来引入
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }

       
      //通过注册表获取业务系统路径,并将依赖的DLL通过Assembly.LoadFrom导入,注意不是LOADFILE

       private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
         {
             RegistryKey registryKeyNewApp= Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\myApp.exe", false);
             string path = "";
             if (registryKeyNewApp!= null)
             {
                 path = registryKeyNewApp.GetValue("Path").ToString();
                 path = path + @"\Bin\";
             }
             string strFielName = args.Name.Split(',')[0];
             path = string.Format(@"{0}{1}.dll", path, "SafeUtilCPlus");
             return Assembly.LoadFrom(path);
         }

      以下代码省略;


还有一点要非常注意,不要将ShareUtilCOM.DLL放到应用系统目录,不然无法触发CurrentDomain_AssemblyResolve;

最终目录结构应该是这样

业务系统下:

     ,C++ CLR的DLL叫:SafeUtilCPlus.DLL,而核心的C#DLL叫:Core.util.DLL(C#)

而第三方调用目录下:

   CallCom.exe;ShareUtilCOM.DLL;ShareUtilCOM.tlb; 在这个目录里用regasm来注册ShareUtilCOM.DLL,注册脚本如下:

请将下面代码放到BAT执行文件里去

set mypath=D:\project\testcom\
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /u "%mypath%ShareUtilCOM.dll"
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe  "%mypath%ShareUtilCOM.dll" /tlb:ShareUtilCOM.tlb
pause

怎么调用COM组件,我就不写了,网上很多;


然后试试调用CallCom吧,看是否成功了!


另外推荐1个工具depends.exe,可以查看SafeUtilCPlus.DLL依赖的包,必须要解决这个DLL缺少的DLL才能正常运行;





0 0