背景:
因项目需要,在我们的系统中增加一个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才能正常运行;