C# 使用代码实现非托管dll、OCX动态注册

一般我们注册VB的ocx控件或者其他的dll需要手动在控制台命令中用regsvr32来注册,其实就是调用dll中的DllRegisterServer方法,用c#的DllImport也可以调用该方法,但是DllImport的路径必须是静态字段,不能动态的,我们可以使用kernel32中的两个函数来实现动态调用:LoadLibrary和GetProcAddress,调用完成之后再FreeLibrary就可以了,先上代码:

  /// <summary>
    /// 动态加载DLL
    /// </summary>
    public class DynamicLoadDll
    {
        /// <summary>
        /// 根据非托管库的句柄,函数名称和指定委托类型,返回委托
        /// </summary>
        /// <param name="dllModule"></param>
        /// <param name="functionName"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        private static Delegate GetFunctionAddress(int dllModule, string functionName, Type t)
        {
            int address = Kernel32Helper.GetProcAddress(dllModule, functionName); //得到地址
            if (address == 0)
                return null;
            else
                return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);//将非托管函数指针转换为委托。
        }
        /// <summary>
        /// 根据dll的路径,dll中的方法名,动态调用非托管dll的方法
        /// </summary>
        /// <param name="dllPath">dll的路径</param>
        /// <param name="functionName">要调用的dll的方法名称</param>
        /// <param name="delegateType">要将对应非托管dll中的方法名映射为C#的签名一致的委托类型</param>
        /// <param name="msg">执行过程中的错误信息</param>
        /// <param name="par">执行方法的参数</param>
        /// <returns></returns>
        public static object DynamicInvoke(string dllPath, string functionName,Type delegateType,out string msg,params object[] par)
        {
            msg = "";
            int address = 0;
            try
            {
                address = Kernel32Helper.LoadLibrary(dllPath);
                if (address == 0)
                {
                    msg = "加载dll失败,dll路径:" + dllPath;
                    return null;
                }
                Delegate d1 = GetFunctionAddress(address, functionName, delegateType);
                if (d1 == null)
                {
                    msg = "获取函数名称失败,函数名称:" + functionName;
                    return null;
                }
                object result= d1.DynamicInvoke(par);
                Kernel32Helper.FreeLibrary(address);
                return result;
            }
            catch (Exception e)
            {
	            if (address != 0)
                {
                    Kernel32Helper.FreeLibrary(address);
                }
                msg = e.Message;
                return null;
            }
        }
    }


    public class Kernel32Helper
    {
        /// <summary>
        /// API LoadLibrary
        /// </summary>
        [DllImport("kernel32")]
        public static extern int LoadLibrary(string funcName);

        /// <summary>
        /// API GetProcAddress
        /// </summary>
        [DllImport("kernel32")]
        public static extern int GetProcAddress(int handle, string funcName);

        /// <summary>
        /// API FreeLibrary
        /// </summary>
        [DllImport("kernel32")]
        public static extern int FreeLibrary(int handle);
    }

使用:

class Program
    {
        public delegate int DllRegisterHandler();
        public delegate int DllUnregisterHandler();
        
        static void Main(string[] args)
        {
            string msg = "";
            string dllFunction = "DllRegisterServer";

            string[] dllPathList = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory,"*.ocx", System.IO.SearchOption.TopDirectoryOnly);
            if (dllPathList != null && dllPathList.Length > 0)
            {
                foreach (var dllPath in dllPathList)
                {

                    object o = DynamicLoadDll.DynamicInvoke(dllPath, dllFunction, typeof(DllRegisterHandler), out msg);
                    if (o != null && (int)o >= 0)
                    {
                        Console.WriteLine(dllPath + "注册成功!");
                    }
                    else
                    {
                        Console.WriteLine(dllPath + "注册失败" + msg);
                    }
                }
            }

            Console.Read();
        }
    }

上面的代码就是获取程序目录下的ocx文件,然后注册这些获取到的ocx文件,
需要注意的是:编译的时候不能选择Any CPU,要选择x86,不然LoadLibrary会不成功!!这是用经验走过的坑
github下载地址:https://github.com/lishuangquan1987/OneKeyRegister

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值