如何查找文件的IFilter

IFilter接口定义了Windows平台扫描文件文本的操作,不同的IFilter实现存储在注册表中。通过以下三个步骤获取:

1、注册表HKEY_LOCAL_MACHINE\SOFTWARE\Classes\{文件扩展名}\PersistentHandler\下存储了文件扩展名持久化处理器,获取它的ClassName。以.docx为例:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.docx\PersistentHandler
默认值为{D3B41FA1-01E3-49AF-AA25-1D0D824275AE}
2、没有PersistentHandler项的情况下需要查找文档类型。注册表HKEY_LOCAL_MACHINE\SOFTWARE\Classes\{文件扩展名}\下的默认值存储了文档类型。在找到文档类型的情况下根据HKEY_LOCAL_MACHINE\SOFTWARE\Classes\{文档类型}\CLSID\存储的ClassName前往HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{ClassName}\PersistentHandler\获取ClassName。
3、查找文档类型失败的情况下访问HKEY_LOCAL_MACHINE\SOFTWARE\Classes\{文件扩展名}\的Content Type值,在Windows平台MIME会存储对应Content Type的Extension。访问HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type\{Content Type}\的Extension值并重复第一、第二步。以.sln为例:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.sln\PersistentHandler\项不存在
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.sln\的默认值为VisualStudio.Launcher.sln
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\VisualStudio.Launcher.sln\CLSID的值为{68681A5C-C22A-421d-B68B-5BA9D01F35C5}
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{68681A5C-C22A-421d-B68B-5BA9D01F35C5}\PersistentHandler项不存在
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.sln\的Content Type值为text/plain
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type\text/plain\的Extension值为.txt
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.txt\PersistentHandler\的默认值为{5e941d80-bf96-11cd-b579-08002b30bfeb}
4、找到PersistentHandler的ClassName后前往HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{PersistentHandler ClassName}\PersistentAddinsRegistered\{89BCB740-6119-101A-BCB7-00DD010655AF}\获取默认值,这个值得存放了持久化的ClassName。以.txt为例:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{5e941d80-bf96-11cd-b579-08002b30bfeb}\PersistentAddinsRegistered\{89BCB740-6119-101A-BCB7-00DD010655AF}\默认值为{c1243ca0-bf96-11cd-b579-08002b30bfeb}。
5、根据这个持久化ClassName获取HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{PersistentHandler ClassName}\InprocServer32\的默认值,它存放了对应的dll路径。
以.txt为例:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{c1243ca0-bf96-11cd-b579-08002b30bfeb}\InprocServer32\默认值为%systemroot%\system32\query.dll。
6、根据对应的dll路径,可以通过LoadLibrary函数加载该模块。使用GetProcAddress获取DllGetClassObject函数指针,调用DllGetClassObject获取IClassFactory接口,由它的CreateInstance函数创建IFilter接口实例,简单示例如下:

 1 #include “stdafx.h”
 2 #include <windows.h>
 3 #include <unknwn.h>
 4 #include <atlbase.h>
 5 #include <atlcom.h>
 6 #include <filter.h>
 7 
 8 using namespace ATL;
 9 
10 TCHAR szFileName[] = _T(“C:\\Windows\\System32\\query.dll”);
11 TCHAR szClsid[] = _T(“{c1243ca0-bf96-11cd-b579-08002b30bfeb}”);
12 
13 HMODULE hModule = LoadLibrary(szFileName);
14 
15 typedef HRESULT (*DllGetClassObjectFunc)(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID FAR* ppv);
16 
17 DllGetClassObjectFunc dllGetClassObjectPtr = reinterpret_cast(GetProcAddress(hModule, “DllGetClassObject”));
18 
19 CComPtr<IClassFactory> pClassFactory;
20 
21 if (dllGetClassObjectPtr) {
22   HRESULT hr = S_OK;
23   IID clsid;
24 
25   hr = CLSIDFromString(szClsid, &clsid);
26   hr = dllGetClassObjectPtr(clsid, IID_IClassFactory, (void**)(&pClassFactory));
27 
28   CComPtr<IFilter> pFilter;
29 
30   hr = pClassFactory->CreateInstance(NULL, IID_IFilter, (void**)(&pFilter));
31 
32 }
posted @ 2012-08-10 10:11 junchu25 阅读(...) 评论(...) 编辑 收藏