Programmatically determine which iFilters are installed

一笑奈何 提交于 2019-12-03 15:03:40

问题


I have a problem whereby the Adobe PDF iFilter doesn't work consistently for us. As such, we like to use the one from Foxit. The problem is, if we install the Foxit iFilter and then later the client decides to reinstall Adobe Reader it may overwrite the Foxit iFilter.

We can use tools such as IFilter Explorer to view this but I'd like a way to do this in the application and warn the user/client that the iFilter has changed.

Is there a way to check iFilters from code (C#)? Or other potential solutions to this problem?


回答1:


Since the foxit IFilter implements IPersistStream interface, I think you can try get this interface from the IFilter, and query for its CLSID to see if it is the one from foxit. Foxit IFilter has a CLSID of {987f8d1a-26e6-4554-b007-6b20e2680632}, which is the "Persistent Handlers Addins Registered" column in IFilter Explorer.

Adobe's IFilter doesn't seem to be implementing this interface.




回答2:


I would expect that IFilters are stored in the registry, therefore you could use Process Monitor to see what keys IFilter Explorer is checking.

Then check on MSDN that this is consistent with the documentation.

Then do the same thing using .NET's registry types in your application.

Based on hunting for this answer, the registration can exist at both System and User level, so you are likely going to need to enumerate multiple registry keys.




回答3:


A little strange answer ;) but as alternative way can be used external console app Filtreg.exe from Windows 7 SDK to delegate this job to it.




回答4:


I'm using this small function to give out a list. It just uses the extension NOT the document type! In the most cases this is ok and could be easily changed here.

/// <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;
    }

}


来源:https://stackoverflow.com/questions/1394356/programmatically-determine-which-ifilters-are-installed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!