ComHelper.cs
上传用户:huiyue
上传日期:2022-04-08
资源大小:1429k
文件大小:4k
源码类别:

搜索引擎

开发平台:

ASP/ASPX

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. namespace EPocalipse.IFilter
  6. {
  7.   [ComVisible(false)]
  8.   [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000001-0000-0000-C000-000000000046")]
  9.   internal interface IClassFactory
  10.   {
  11.     void CreateInstance([MarshalAs(UnmanagedType.Interface)] object pUnkOuter, ref Guid refiid, [MarshalAs(UnmanagedType.Interface)] out object ppunk);
  12.     void LockServer(bool fLock);
  13.   }
  14.   /// <summary>
  15.   /// Utility class to get a Class Factory for a certain Class ID 
  16.   /// by loading the dll that implements that class
  17.   /// </summary>
  18.   internal static class ComHelper
  19.   {
  20.     //DllGetClassObject fuction pointer signature
  21.     private delegate int DllGetClassObject(ref Guid ClassId, ref Guid InterfaceId, [Out, MarshalAs(UnmanagedType.Interface)] out object ppunk);
  22.     //Some win32 methods to loadunload dlls and get a function pointer
  23.     private class Win32NativeMethods
  24.     {
  25.       [DllImport("kernel32.dll", CharSet=CharSet.Ansi)]
  26.       public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
  27.       [DllImport("kernel32.dll")]
  28.       public static extern bool FreeLibrary(IntPtr hModule);
  29.       [DllImport("kernel32.dll")]
  30.       public static extern IntPtr LoadLibrary(string lpFileName);
  31.     }
  32.     /// <summary>
  33.     /// Holds a list of dll handles and unloads the dlls 
  34.     /// in the destructor
  35.     /// </summary>
  36.     private class DllList
  37.     {
  38.       private List<IntPtr> _dllList=new List<IntPtr>();
  39.       public void AddDllHandle(IntPtr dllHandle)
  40.       {
  41.         lock (_dllList)
  42.         {
  43.           _dllList.Add(dllHandle);
  44.         }
  45.       }
  46.       ~DllList()
  47.       {
  48.         foreach (IntPtr dllHandle in _dllList)
  49.         {
  50.           try
  51.           {
  52.             Win32NativeMethods.FreeLibrary(dllHandle);
  53.           }
  54.           catch { };
  55.         }
  56.       }
  57.     }
  58.     static DllList _dllList=new DllList();
  59.     /// <summary>
  60.     /// Gets a class factory for a specific COM Class ID. 
  61.     /// </summary>
  62.     /// <param name="dllName">The dll where the COM class is implemented</param>
  63.     /// <param name="filterPersistClass">The requested Class ID</param>
  64.     /// <returns>IClassFactory instance used to create instances of that class</returns>
  65.     internal static IClassFactory GetClassFactory(string dllName, string filterPersistClass)
  66.     {
  67.       //Load the class factory from the dll
  68.       IClassFactory classFactory=GetClassFactoryFromDll(dllName, filterPersistClass);
  69.       return classFactory;
  70.     }
  71.     private static IClassFactory GetClassFactoryFromDll(string dllName, string filterPersistClass)
  72.     {
  73.       //Load the dll
  74.       IntPtr dllHandle=Win32NativeMethods.LoadLibrary(dllName);
  75.       if (dllHandle==IntPtr.Zero)
  76.         return null;
  77.       //Keep a reference to the dll until the processAppDomain dies
  78.       _dllList.AddDllHandle(dllHandle);
  79.       //Get a pointer to the DllGetClassObject function
  80.       IntPtr dllGetClassObjectPtr=Win32NativeMethods.GetProcAddress(dllHandle, "DllGetClassObject");
  81.       if (dllGetClassObjectPtr==IntPtr.Zero)
  82.         return null;
  83.       //Convert the function pointer to a .net delegate
  84.       DllGetClassObject dllGetClassObject=(DllGetClassObject)Marshal.GetDelegateForFunctionPointer(dllGetClassObjectPtr, typeof(DllGetClassObject));
  85.       //Call the DllGetClassObject to retreive a class factory for out Filter class
  86.       Guid filterPersistGUID=new Guid(filterPersistClass);
  87.       Guid IClassFactoryGUID=new Guid("00000001-0000-0000-C000-000000000046"); //IClassFactory class id
  88.       Object unk;
  89.       if (dllGetClassObject(ref filterPersistGUID, ref IClassFactoryGUID, out unk)!=0)
  90.         return null;
  91.       //Yippie! cast the returned object to IClassFactory
  92.       return (unk as IClassFactory);
  93.     }
  94.   }
  95. }