C#:实现OCX 控件的注册与卸载

源代码
RegSvr32.cs

/* ----------------------------------------------------------
 * 文件名称:RegSvr32.cs
 * 
 * 作者:秦建辉
 * 
 * 微信:splashcn
 * 
 * 博客:http://www.firstsolver.com/wordpress/
 * 
 * 开发环境:
 *      Visual Studio V2017
 *      .NET Framework 4 Client Profile
 * 
 * 版本历史:
 *      V1.0	2017年12月14日
 *              OCX 控件注册与卸载
------------------------------------------------------------ */
using System;
using System.Runtime.InteropServices;

namespace Com.FirstSolver.Splash
{
    public class RegSvr32
    {
        private static UIntPtr HKEY_CLASSES_ROOT = new UIntPtr(0x80000000u);
        private static int KEY_READ = 131097;

        /// <summary>
        /// 注册委托声明
        /// </summary>
        /// <returns>错误代码</returns>
        private delegate int DllRegisterServer();

        /// <summary>
        /// 反注册委托声明
        /// </summary>
        /// <returns>错误代码</returns>
        private delegate int DllUnregisterServer();

        /// <summary>
        /// 注册OCX控件
        /// </summary>
        /// <param name="FileName">控件文件名称</param>
        /// <returns>true:成功 false:失败</returns>
        public static bool Register(string FileName)
        {
            IntPtr hModule = LoadLibrary(FileName);
            if (hModule == IntPtr.Zero) return false;

            IntPtr FP = GetProcAddress(hModule, "DllRegisterServer");
            if (FP == IntPtr.Zero) return false;

            DllRegisterServer P = (DllRegisterServer)Marshal.GetDelegateForFunctionPointer(FP, typeof(DllRegisterServer));
            bool IsOK = (P() >= 0);
            FreeLibrary(hModule);
            return IsOK;
        }

        /// <summary>
        /// 反注册OCX控件
        /// </summary>
        /// <param name="FileName">控件文件名称</param>
        /// <returns>true:成功 false:失败</returns>
        public static bool Unregister(string FileName)
        {
            IntPtr hModule = LoadLibrary(FileName);
            if (hModule == IntPtr.Zero) return false;

            IntPtr FP = GetProcAddress(hModule, "DllUnregisterServer");
            if (FP == IntPtr.Zero) return false;

            DllUnregisterServer P = (DllUnregisterServer)Marshal.GetDelegateForFunctionPointer(FP, typeof(DllUnregisterServer));
            bool IsOK = (P() >= 0);
            FreeLibrary(hModule);
            return IsOK;
        }

        /// <summary>
        /// 判断 OCX 控件是否已注册
        /// </summary>
        /// <param name="lpSubKey">OCX 控件注册表项</param>
        /// <returns>true:成功 false:失败</returns>
        public static bool IsRegistered(string lpSubKey)
        {
            UIntPtr hkResult;
            return RegOpenKeyEx(HKEY_CLASSES_ROOT, lpSubKey, 0, KEY_READ, out hkResult) == 0;
        }

        /// <summary>
        /// 加载动态库
        /// </summary>
        /// <param name="lpFileName">文件名</param>
        /// <returns>动态库句柄</returns>
        [DllImport("Kernel32.dll", SetLastError = true)]
        private static extern IntPtr LoadLibrary(string lpFileName);

        /// <summary>
        /// 卸载动态库
        /// </summary>
        /// <param name="hModule">动态库句柄</param>
        /// <returns>true:成功 false:失败</returns>
        [DllImport("Kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool FreeLibrary(IntPtr hModule);

        /// <summary>
        /// 获取动态库方法句柄
        /// </summary>
        /// <param name="hModule">动态库句柄</param>
        /// <param name="lpProcName">方法名称</param>
        /// <returns>动态库方法句柄</returns>
        [DllImport("Kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

        [DllImport("Advapi32.dll", CharSet = CharSet.Auto)]
        private static extern int RegOpenKeyEx(UIntPtr hKey, string lpSubKey, int ulOptions, int samDesired, out UIntPtr phkResult);
    }
}

调用示例

using Com.FirstSolver.Splash;
using System.Windows;

namespace Splash
{
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {   // 检测 OCX 是否已经注册
            if (!RegSvr32.IsRegistered("ESCANNERCTRL.EScannerCtrlCtrl.1\\CLSID"))
            {   // 必须以管理员身份注册 OCX 控件
                if (RegSvr32.Register("EScannerCtrl.ocx"))
                {
                    MessageBox.Show("EScannerCtrl.ocx注册成功!请恢复普通人员身份运行。", "祝贺", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                else
                {
                    MessageBox.Show("EScannerCtrl.ocx注册失败!请重新以管理员身份运行一次。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                App.Current.Shutdown(); // 程序退出
            }
            else
            {
                base.OnStartup(e);
            }
        }
    }
}

Comments are closed.