C# 코드로 관리되지 않는 dll, OCX 동적 등록

4470 단어 C#
일반적으로 우리는 VB의ocx컨트롤이나 다른 dll을 등록하려면 컨트롤러 명령에서regsvr32로 수동으로 등록해야 한다. 사실은 dll의 DllRegisterServer 방법을 호출하고 c#의 DllImport로도 이 방법을 호출할 수 있다. 그러나 DllImport의 경로는 정적 필드이어야 하며 동적일 수 없다. 우리는kernel32의 두 함수를 사용하여 동적 호출을 실현할 수 있다. LoadLibrary와 GetProcAddress,FreeLibrary 를 실행하기 전에 호출을 완료하면 됩니다.
  /// 
    ///     DLL
    /// 
    public class DynamicLoadDll
    {
        /// 
        ///          ,           ,    
        /// 
        /// 
        /// 
        /// 
        /// 
        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);//             。
        }
        /// 
        ///   dll   ,dll     ,       dll   
        /// 
        /// dll   
        ///     dll     
        ///        dll        C#          
        ///           
        ///        
        /// 
        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
    {
        /// 
        /// API LoadLibrary
        /// 
        [DllImport("kernel32")]
        public static extern int LoadLibrary(string funcName);

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

        /// 
        /// API FreeLibrary
        /// 
        [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

좋은 웹페이지 즐겨찾기