Программно определить, какие iFilters установлены.
Вопрос
У меня возникла проблема: Adobe PDF iFilter не работает стабильно.Поэтому нам нравится использовать тот, который из Фоксит.Проблема в том, что если мы установим Foxit iFilter, а затем клиент решит переустановить Adobe Reader, он может перезаписать Foxit iFilter.
Мы можем использовать такие инструменты, как Обозреватель фильтров чтобы просмотреть это, но мне нужен способ сделать это в приложении и предупредить пользователя/клиента о том, что iFilter изменился.
Есть ли способ проверить iFilters из кода (С#)?Или другие возможные решения этой проблемы?
Решение
Поскольку foxit IFilter реализует интерфейс IPersistStream, я думаю, вы можете попробовать получить этот интерфейс от IFilter и запросить его CLSID, чтобы узнать, принадлежит ли он интерфейсу foxit.Foxit IFilter имеет CLSID {987f8d1a-26e6-4554-b007-6b20e2680632}
, который представляет собой столбец «Зарегистрированные надстройки постоянных обработчиков» в IFilter Explorer.
Adobe IFilter, похоже, не реализует этот интерфейс.
Другие советы
Я бы ожидать что IFilters хранятся в реестре, поэтому вы можете использовать Монитор процессов чтобы увидеть, какие ключи проверяет IFilter Explorer.
Тогда проверь MSDN что это соответствует документации.
Затем сделайте то же самое, используя типы реестра .NET в своем приложении.
Судя по поиску этого ответа, регистрация может существовать как на уровне системы, так и на уровне пользователя, поэтому вам, вероятно, придется перечислить несколько ключей реестра.
Немного странный ответ;) но в качестве альтернативы можно использовать внешнее консольное приложение. Фильтррег.exe от Windows 7 SDK делегировать ему эту работу.
Я использую эту небольшую функцию для выдачи списка.Он просто использует расширение, а НЕ тип документа!В большинстве случаев это нормально и может быть легко изменено здесь.
/// <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;
}
}