FilterLoader.cs
上传用户:huiyue
上传日期:2022-04-08
资源大小:1429k
文件大小:9k
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Microsoft.Win32;
- using System.IO;
- using System.Runtime.InteropServices.ComTypes;
- using System.Runtime.InteropServices;
- namespace EPocalipse.IFilter
- {
- /// <summary>
- /// FilterLoader finds the dll and ClassID of the COM object responsible
- /// for filtering a specific file extension.
- /// It then loads that dll, creates the appropriate COM object and returns
- /// a pointer to an IFilter instance
- /// </summary>
- /// <remarks>
- /// Developing IFilter Add-ins
- /// http://msdn2.microsoft.com/en-us/library/aa965717.aspx
- /// </remarks>
- static class FilterLoader
- {
- #region CacheEntry
- private class CacheEntry
- {
- public string DllName;
- public string ClassName;
- public CacheEntry(string dllName, string className)
- {
- DllName=dllName;
- ClassName=className;
- }
- }
- #endregion
- static Dictionary<string, CacheEntry> _cache=new Dictionary<string, CacheEntry>();
- #region Registry Read String helper
- static string ReadStrFromHKLM(string key)
- {
- return ReadStrFromHKLM(key,null);
- }
- static string ReadStrFromHKLM(string key, string value)
- {
- RegistryKey rk=Registry.LocalMachine.OpenSubKey(key);
- if (rk==null)
- return null;
- using (rk)
- {
- return (string)rk.GetValue(value);
- }
- }
- #endregion
- /// <summary>
- /// finds an IFilter implementation for a file type
- /// </summary>
- /// <param name="ext">The extension of the file</param>
- /// <returns>an IFilter instance used to retreive text from that file type</returns>
- private static IFilter LoadIFilter(string ext)
- {
- string dllName, filterPersistClass;
- //Find the dll and ClassID
- if (GetFilterDllAndClass(ext, out dllName, out filterPersistClass))
- {
- //load the dll and return an IFilter instance.
- return LoadFilterFromDll(dllName, filterPersistClass);
- }
- return null;
- }
- internal static IFilter LoadAndInitIFilter(string fileName)
- {
- return LoadAndInitIFilter(fileName,Path.GetExtension(fileName));
- }
- internal static IFilter LoadAndInitIFilter(string fileName, string extension)
- {
- IFilter filter=LoadIFilter(extension);
- if (filter==null)
- return null;
- IPersistFile persistFile=(filter as IPersistFile);
- if (persistFile!=null)
- {
- persistFile.Load(fileName, 0);
- IFILTER_FLAGS flags;
- IFILTER_INIT iflags =
- IFILTER_INIT.CANON_HYPHENS |
- IFILTER_INIT.CANON_PARAGRAPHS |
- IFILTER_INIT.CANON_SPACES |
- IFILTER_INIT.APPLY_INDEX_ATTRIBUTES |
- IFILTER_INIT.HARD_LINE_BREAKS |
- IFILTER_INIT.FILTER_OWNED_VALUE_OK;
- iflags =
- IFILTER_INIT.CANON_HYPHENS |
- IFILTER_INIT.CANON_PARAGRAPHS |
- IFILTER_INIT.CANON_SPACES |
- IFILTER_INIT.HARD_LINE_BREAKS |
- IFILTER_INIT.FILTER_OWNED_VALUE_OK |
- IFILTER_INIT.APPLY_INDEX_ATTRIBUTES |
- IFILTER_INIT.APPLY_CRAWL_ATTRIBUTES |
- IFILTER_INIT.APPLY_OTHER_ATTRIBUTES |
- IFILTER_INIT.FILTER_OWNED_VALUE_OK; // added [CD]
- if (filter.Init(iflags, 0, IntPtr.Zero, out flags)==IFilterReturnCode.S_OK)
- return filter;
- }
- //If we failed to retreive an IPersistFile interface or to initialize
- //the filter, we release it and return null.
- Marshal.ReleaseComObject(filter);
- return null;
- }
- private static IFilter LoadFilterFromDll(string dllName, string filterPersistClass)
- {
- //Get a classFactory for our classID
- IClassFactory classFactory=ComHelper.GetClassFactory(dllName, filterPersistClass);
- if (classFactory==null)
- return null;
- //And create an IFilter instance using that class factory
- // http://msdn2.microsoft.com/en-us/library/aa965717.aspx
- // The first identifies all filters' persistent handler, IID_IFilter, which is {89BCB740-6119-101A-BCB7-00DD010655AF}. This CLSID is constant for all filters that implement IFilter.
- Guid IFilterGUID=new Guid("89BCB740-6119-101A-BCB7-00DD010655AF");
- Object obj;
- classFactory.CreateInstance(null, ref IFilterGUID, out obj);
- return (obj as IFilter);
- }
- private static bool GetFilterDllAndClass(string ext, out string dllName, out string filterPersistClass)
- {
- if (!GetFilterDllAndClassFromCache(ext, out dllName, out filterPersistClass))
- {
- string persistentHandlerClass;
- persistentHandlerClass=GetPersistentHandlerClass(ext,true);
- if (persistentHandlerClass!=null)
- {
- GetFilterDllAndClassFromPersistentHandler(persistentHandlerClass,
- out dllName, out filterPersistClass);
- }
- AddExtensionToCache(ext, dllName, filterPersistClass);
- }
- return (dllName!=null && filterPersistClass!=null);
- }
- private static void AddExtensionToCache(string ext, string dllName, string filterPersistClass)
- {
- lock (_cache)
- {
- _cache.Add(ext.ToLower(), new CacheEntry(dllName, filterPersistClass));
- }
- }
- private static bool GetFilterDllAndClassFromPersistentHandler(string persistentHandlerClass, out string dllName, out string filterPersistClass)
- {
- dllName=null;
- filterPersistClass=null;
- //Read the CLASS ID of the IFilter persistent handler
- filterPersistClass=ReadStrFromHKLM(@"SoftwareClassesCLSID" + persistentHandlerClass +
- @"PersistentAddinsRegistered{89BCB740-6119-101A-BCB7-00DD010655AF}");
- if (String.IsNullOrEmpty(filterPersistClass))
- return false;
- //Read the dll name
- dllName=ReadStrFromHKLM(@"SoftwareClassesCLSID" + filterPersistClass +
- @"InprocServer32");
- return (!String.IsNullOrEmpty(dllName));
- }
- private static string GetPersistentHandlerClass(string ext, bool searchContentType)
- {
- //Try getting the info from the file extension
- string persistentHandlerClass=GetPersistentHandlerClassFromExtension(ext);
- if (String.IsNullOrEmpty(persistentHandlerClass))
- //try getting the info from the document type
- persistentHandlerClass=GetPersistentHandlerClassFromDocumentType(ext);
- if (searchContentType && String.IsNullOrEmpty(persistentHandlerClass))
- //Try getting the info from the Content Type
- persistentHandlerClass=GetPersistentHandlerClassFromContentType(ext);
- return persistentHandlerClass;
- }
- private static string GetPersistentHandlerClassFromContentType(string ext)
- {
- string contentType=ReadStrFromHKLM(@"SoftwareClasses"+ext,"Content Type");
- if (String.IsNullOrEmpty(contentType))
- return null;
-
- string contentTypeExtension=ReadStrFromHKLM(@"SoftwareClassesMIMEDatabaseContent Type"+contentType,
- "Extension");
- if (ext.Equals(contentTypeExtension, StringComparison.CurrentCultureIgnoreCase))
- return null; //No need to look further. This extension does not have any persistent handler
-
- //We know the extension that is assciated with that content type. Simply try again with the new extension
- return GetPersistentHandlerClass(contentTypeExtension, false); //Don't search content type this time.
- }
- private static string GetPersistentHandlerClassFromDocumentType(string ext)
- {
- //Get the DocumentType of this file extension
- string docType=ReadStrFromHKLM(@"SoftwareClasses"+ext);
- if (String.IsNullOrEmpty(docType))
- return null;
-
- //Get the Class ID for this document type
- string docClass=ReadStrFromHKLM(@"SoftwareClasses" + docType + @"CLSID");
- if (String.IsNullOrEmpty(docType))
- return null;
- //Now get the PersistentHandler for that Class ID
- return ReadStrFromHKLM(@"SoftwareClassesCLSID" + docClass + @"PersistentHandler");
- }
- private static string GetPersistentHandlerClassFromExtension(string ext)
- {
- return ReadStrFromHKLM(@"SoftwareClasses"+ext+@"PersistentHandler");
- }
- private static bool GetFilterDllAndClassFromCache(string ext, out string dllName, out string filterPersistClass)
- {
- string lowerExt=ext.ToLower();
- lock (_cache)
- {
- CacheEntry cacheEntry;
- if (_cache.TryGetValue(lowerExt, out cacheEntry))
- {
- dllName=cacheEntry.DllName;
- filterPersistClass=cacheEntry.ClassName;
- return true;
- }
- }
- dllName=null;
- filterPersistClass=null;
- return false;
- }
- }
- }