.net比较完美的动态注册com组件
来源:互联网 发布:linux命令system 编辑:程序博客网 时间:2024/05/11 17:56
.net中经常需要使用com组件,怎么样注册com组件呢?
在.net中可以直接执行cmd命令如下:
问题来了,那怎么去检查一个dll已经注册了呢?不能每次都注册吧!我们知道每一个com组件都有一个clsid,如果已经注册了,那么在系统注册表里面会有注册信息的。 csharp代码如下:
似乎通过上面的代码已经解决了所有问题,但是我个人并不满足上面的方案,原因如下:
不喜欢直接在.net中调用cmd命令
当检查是否注册时,必须预先知道com的clsid。
那么有么有方法解决上面2个问题呢?答案当然是肯定的! 通过查询资料得知:
regsvr32 name.dll 实际上就是调用name.dll中的一个方法:DllRegisterServer。
在.net中我们可以通过pinvoke直接调用dll这个方法就可以了,代码如下:
然后在.net中直接通过NameDll.DllRegisterServer();即可完成注册。 这个办法不需要在.net中调用cmd命令,但是有个缺点。
每一个dll都需要这么定义下。因为[DllImport("name.dll")]这个路径不能动态给。所以也不是很好。其实在.net中有可以动态加载dll并根据需要调用dll中方法的代码如下:
这个方法避免了每一个com组件要定义个类的弊端。而且完全可以根据com路径动态注册。但是大家别忘了,上面还有一个问题没解决。
那就是在检查com是否注册时,怎么动态得知指定路径com的clsid。 废话也不多说。代码如下
上面这个方法可以获取给定路径的dll中的clsid列表。 老实讲:这个方法我是真的费尽心力,网上几乎没.net的资料。
至此所有问题都已经解决。我们完全可以根据指定路径注册动态注册com组件,并能判断是否已经注册。我简单封装一下代码:
完毕,希望对大家有用!
一般想到的当然是直接通过系统cmd 调用regsvr32注册程序去注册,如下:
regsvr32 name.dll
在.net中可以直接执行cmd命令如下:
System.Diagnostics.Process.Start("regsvr32.exe","name.dll");
问题来了,那怎么去检查一个dll已经注册了呢?不能每次都注册吧!我们知道每一个com组件都有一个clsid,如果已经注册了,那么在系统注册表里面会有注册信息的。 csharp代码如下:
private static bool IsExistRegister(Guid guid){RegistryKey rkTest = Registry.ClassesRoot.OpenSubKey(String.Format("CLSID\\{{{0}}}\\InprocServer32", guid.ToString()));if (rkTest != null){var val = rkTest.GetValue("");//获取注册表中注册的dll路径if (val != null){return System.IO.File.Exists(val.ToString());}}return false;}
似乎通过上面的代码已经解决了所有问题,但是我个人并不满足上面的方案,原因如下:
不喜欢直接在.net中调用cmd命令
当检查是否注册时,必须预先知道com的clsid。
那么有么有方法解决上面2个问题呢?答案当然是肯定的! 通过查询资料得知:
regsvr32 name.dll 实际上就是调用name.dll中的一个方法:DllRegisterServer。
在.net中我们可以通过pinvoke直接调用dll这个方法就可以了,代码如下:
static class NameDll{[DllImport("name.dll")]public static extern int DllRegisterServer();[DllImport("name.dll")]public static extern int DllUnregisterServer();}
然后在.net中直接通过NameDll.DllRegisterServer();即可完成注册。 这个办法不需要在.net中调用cmd命令,但是有个缺点。
每一个dll都需要这么定义下。因为[DllImport("name.dll")]这个路径不能动态给。所以也不是很好。其实在.net中有可以动态加载dll并根据需要调用dll中方法的代码如下:
public class Win32DllWrap : IDisposable{[DllImport("kernel32.dll")]private extern static IntPtr LoadLibrary(String path);[DllImport("kernel32.dll")]private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);[DllImport("kernel32.dll")]private extern static bool FreeLibrary(IntPtr lib);private IntPtr hLib;public Win32DllWrap(String DLLPath){hLib = LoadLibrary(DLLPath);}/// <summary>/// 根据函数名获取dll中的函数指针,并转化为指定的TDelegate类型/// </summary>/// <typeparam name="TDelegate"></typeparam>/// <param name="name"></param>/// <returns></returns>public TDelegate GetFunc<TDelegate>(String name) where TDelegate : class{IntPtr api = GetProcAddress(hLib, name);return Marshal.GetDelegateForFunctionPointer(api, typeof(TDelegate)) as TDelegate;}public void Dispose(){FreeLibrary(hLib);}}/*using(var dll = new Win32DllWrap(path)){ var method = dll.GetFunc<Action>("DllRegisterServer");//根据名字获取方法,并返回对于的委托 method();//完成注册}*/
这个方法避免了每一个com组件要定义个类的弊端。而且完全可以根据com路径动态注册。但是大家别忘了,上面还有一个问题没解决。
那就是在检查com是否注册时,怎么动态得知指定路径com的clsid。 废话也不多说。代码如下
private static List<Guid> GetClsids(string path){if (!System.IO.File.Exists(path)){throw new Exception(path + "文件不存在");}List<Guid> list = new List<Guid>();ITypeLib lib;IntPtr attrPtr;ITypeInfo info;LoadTypeLib(path, out lib);if (lib == null){throw new Exception(path + "不是com组件");}var n = lib.GetTypeInfoCount();for (int i = 0; i < n; i++){lib.GetTypeInfo(i, out info);if (info != null){info.GetTypeAttr(out attrPtr);if (attrPtr != null){var v = (System.Runtime.InteropServices.ComTypes.TYPEATTR)Marshal.PtrToStructure(attrPtr, typeof(System.Runtime.InteropServices.ComTypes.TYPEATTR));if (v.typekind == System.Runtime.InteropServices.ComTypes.TYPEKIND.TKIND_COCLASS){list.Add(v.guid);}info.ReleaseTypeAttr(attrPtr);}}}return list;}
上面这个方法可以获取给定路径的dll中的clsid列表。 老实讲:这个方法我是真的费尽心力,网上几乎没.net的资料。
至此所有问题都已经解决。我们完全可以根据指定路径注册动态注册com组件,并能判断是否已经注册。我简单封装一下代码:
/// <summary>/// Com组件注册类/// </summary>public class ComRegHelp{ private delegate void comDelegate();/// <summary>/// 注册指定路径的dll,如果已经注册,就不注册/// </summary>/// <param name="dllPath"></param>public static void Registe(string dllPath){if (!IsRegistered(dllPath)){using (var dll = new Win32DllWrap(dllPath)){dll.GetFunc<comDelegate>("DllRegisterServer")();}}}/// <summary>/// 取消注册指定路径的dll/// </summary>/// <param name="dllPath"></param>public static void UnRegiste(string dllPath){using (var dll = new Win32DllWrap(dllPath)){dll.GetFunc<comDelegate>("DllUnregisterServer")();}}private static List<Guid> GetClsids(string path){if (!System.IO.File.Exists(path)){throw new Exception(path + "文件不存在");}List<Guid> list = new List<Guid>();ITypeLib lib;IntPtr attrPtr;ITypeInfo info;LoadTypeLib(path, out lib);if (lib == null){throw new Exception(path + "不是com组件");}var n = lib.GetTypeInfoCount();for (int i = 0; i < n; i++){lib.GetTypeInfo(i, out info);if (info != null){info.GetTypeAttr(out attrPtr);if (attrPtr != null){var v = (System.Runtime.InteropServices.ComTypes.TYPEATTR)Marshal.PtrToStructure(attrPtr, typeof(System.Runtime.InteropServices.ComTypes.TYPEATTR));if (v.typekind == System.Runtime.InteropServices.ComTypes.TYPEKIND.TKIND_COCLASS){list.Add(v.guid);}info.ReleaseTypeAttr(attrPtr);}}}return list;}[DllImport("oleaut32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]static extern int LoadTypeLib(string fileName, out ITypeLib typeLib);/// <summary>/// 判断指定路径dll是否已经注册/// </summary>/// <param name="path"></param>/// <returns></returns>public static bool IsRegistered(string path){var guids = GetClsids(path);foreach (var item in guids){if (IsExistRegister(item)){return true;}}return false;}private static bool IsExistRegister(Guid guid){RegistryKey rkTest = Registry.ClassesRoot.OpenSubKey(String.Format("CLSID\\{{{0}}}\\InprocServer32", guid.ToString()));if (rkTest != null){var val = rkTest.GetValue("");if (val != null){return System.IO.File.Exists(val.ToString());}}return false;}}
完毕,希望对大家有用!
来源:http://www.cnblogs.com/tianqiq/p/4538194.html
1 0
- .net比较完美的动态注册com组件
- COM组件与.Net组件的比较
- .net 注册COM+应用组件的步骤
- 1、COM组件与.Net组件的比较
- 将.net组件注册为com组件
- .Net编译的COM+组件的注册测试
- 如何注册.net 的类库dll 为com组件
- 利用RegSvr32来注册.NET COM组件
- 利用RegSvr32来注册.NET COM组件
- com组件的注册and反注册
- 使用regasm注册.net com组件出现不是有效的.net程序集的解决办法
- 创建COM组件的实现(或者叫作注册Com组件)
- 两种注册COM组件的方法
- com+组件的注册,卸载和管理
- 手工加载未注册的 COM 组件
- C#写的com组件注册脚本
- 调用DllRegisterServer进行COM组件的注册
- 注册COM组件命令
- Android NDK开发之 Android系统开发中LOG的使用
- CF Mike and Feet (求连续区间内长度为i的最小值)单调栈
- RT5350的IO引脚的操作
- cell的侧滑效果
- CentOS7安装QT
- .net比较完美的动态注册com组件
- 第三章第二题魔方
- Android详细笔记
- 使用UliPad进行Django项目开发
- 关于JAVA 并发类的Executor误用导致的线程数量异常
- js正则匹配
- postgresql pg_rman的简单使用
- iOS 常用宏定义汇总 【持续更新】
- Asp.net Mvc中利用ValidationAttribute实现xss过滤