我遇到问题,Adobe PDF iFilter不能一直为我们工作。因此,我们喜欢使用Foxit中的那个。问题是,如果我们安装Foxit iFilter,然后客户决定重新安装Adobe Reader,它可能会覆盖Foxit iFilter。以编程方式确定安装哪些iFilters
我们可以使用诸如IFilter Explorer这样的工具来查看这个,但我想在应用程序中这样做,并警告用户/客户端iFilter已经改变。
有没有办法从代码(C#)中检查iFilters?或者解决这个问题的其他方法?
我遇到问题,Adobe PDF iFilter不能一直为我们工作。因此,我们喜欢使用Foxit中的那个。问题是,如果我们安装Foxit iFilter,然后客户决定重新安装Adobe Reader,它可能会覆盖Foxit iFilter。以编程方式确定安装哪些iFilters
我们可以使用诸如IFilter Explorer这样的工具来查看这个,但我想在应用程序中这样做,并警告用户/客户端iFilter已经改变。
有没有办法从代码(C#)中检查iFilters?或者解决这个问题的其他方法?
由于福禄的IFilter实现IPersistStream接口,我认为你可以尝试从IFilter获取这个接口,并查询它的CLSID来查看它是否是来自foxit的接口。 Foxit IFilter的CLSID为{987f8d1a-26e6-4554-b007-6b20e2680632}
,它是IFilter Explorer中的“Persistent Handlers Addins Registered”列。
Adobe的IFilter似乎没有实现这个接口。
我会给这个检查正确的答案,因为它尽可能接近。似乎没有简单的方法来枚举所有的iFilters,但Smithy是对的,如果你知道你在找什么,你可以挖掘并确定它是否被安装(假设它暴露了一个接口等) – 2011-02-12 18:43:18
谢谢你的检查。我刚刚从我的Windows SDK中发现了FiltReg.exe命令行实用程序。它为您提供了系统中已安装的IFilter的完整列表。如果你可以解析它的输出...... – Smithy 2011-02-14 15:55:04
我会预计 IFilter存储在注册表中,因此您可以使用Process Monitor来查看IFilter资源管理器正在检查的键。
然后检查MSDN,这与文档一致。
然后在您的应用程序中使用.NET注册表类型做同样的事情。
基于寻找此答案,注册可以存在于系统和用户级别,因此您可能需要枚举多个注册表项。
我正在使用这个小函数来给出一个列表。它只是使用扩展名而不是文档类型!在大多数情况下,这是好的,可以在这里轻松更改。
/// <summary>
/// Implements a Function to get all available IFilters currently registered in this system
/// </summary>
public string GetFilterList()
{
//Our resulting string. We give back a ';' seperated list of extensions.
string result = @"";
string persistentHandlerClass;
RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"Software\Classes");
if (rk == null)
return null;
using (rk)
{
foreach(string subKeyName in rk.GetSubKeyNames())
{
if (subKeyName[0] == '.') //possible Extension
{
RegistryKey sk = Registry.LocalMachine.OpenSubKey(@"Software\Classes\" + subKeyName + @"\PersistentHandler");
if (sk == null)
continue;
using (sk)
{
persistentHandlerClass = (string)sk.GetValue(null);
}
if (persistentHandlerClass != null)
{
string filterPersistClass = ReadStrFromHKLM(@"Software\Classes\CLSID\" + persistentHandlerClass +
@"\PersistentAddinsRegistered\{89BCB740-6119-101A-BCB7-00DD010655AF}");
string dllName = ReadStrFromHKLM(@"Software\Classes\CLSID\" + filterPersistClass + @"\InprocServer32");
// skip query.dll results, cause it's not an IFilter itself
if (dllName != null && filterPersistClass != null && (dllName.IndexOf("query.dll") < 0))
{
//result = result + subKeyName + @"[" + dllName + @"] - persistentHandlerClassAddin: " + persistentHandlerClass + "\r\n"; //[C:\Windows\system32\query.dll]
//result = result + subKeyName + @"[" + dllName + @"];"; //[C:\Windows\system32\query.dll]
result = result + subKeyName.ToLower() + @";";
}
}
}
}
return result;
}
}
有点怪的答案;),但作为替代方式,可以从Windows 7 SDK使用外部控制台应用程序Filtreg.exe到这项工作委托给它。
我也会对这个问题的答案感兴趣! – 2009-10-28 14:37:37
Sooooo ..你有没有想过如何检查代码中是否存在iFilter? – Skadoosh 2010-10-19 17:23:18
@KP - 不,我没有。放弃了,而不是在代码中完成它已经留给用户和文档来处理,而不是一个真正的解决方案,但我们现在可以做的最好。 – 2010-10-20 00:38:29