Adobe Acrobat reader注册表项位置不断变化

时间:2010-12-16 09:12:58

标签: c# registry acrobat

我的要求是阅读与Adobe Acrobat reader相关的特定注册表项,并根据该项的值做出决定。

虽然这看起来很简单,但我需要使用Registry类查询密钥(对于.NET) 然后根据价值做出决定。

然而,我现在面临的问题是,几乎每个新版本的Adobe Acrobat Reader中的注册表键位置都在不断变化。

我现在能想到的就是在我的代码中设置一个用于处理所有不同Adobe版本的开关盒。

RegistryKey adobe = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Adobe");
            if (adobe != null)
            {
                RegistryKey acroRead = adobe.OpenSubKey("Acrobat Reader");
                if (acroRead != null)
                {
                    string[] acroReadVersions = acroRead.GetSubKeyNames();
                    Console.WriteLine("The following version(s) of Acrobat Reader are installed: ");
                    foreach (string versionNumber in acroReadVersions)
                    {
                        switch(versionNumber)
                        {
                           case 1.x = //do something;
                                      //break;    
                           case 2.x = //do something;
                                      //break;
                           case 6.x = //do something;
                                      //break;
                           case 9.x = //do something;
                                      //break;
                        }  
                    }
                }
            }

但有些人对此方法不满意。每次Adobe发布新版本时,我都必须确保我必须以不同的方式处理它。任何有关更好方法的建议。

谢谢

3 个答案:

答案 0 :(得分:2)

你最希望打开包含版本号的注册表项,然后枚举每个子键,可能验证它看起来像版本号,然后在每个子键中查找你想要的东西。您可能只想使用找到的最高版本。

显然,只有当你想要的东西总是包含在相对于版本密钥的相同注册表项中,或者总是在同一个命名条目中时,这才会起作用(然后你必须枚举子键下的每个元素来寻找你想要的东西)。

如果您想要的东西在每个版本中更改名称和位置,那么您将遇到问题,除非您可以从数据中以某种方式识别它,在这种情况下枚举每个元素并查看4数据并尝试确定它是否是你想要什么,但这种方法很可能充满危险或误报。

答案 1 :(得分:0)

嗯,我有完全相同的问题,因为我知道Adobe的决策和材料并不是那么出色,我想我会尝试这种方法:

    public static string AcrobatReaderPath
    {
        get
        {
            var paths = new List<string>()
                    {
                        Registry.GetValue(@"HKEY_CLASSES_ROOT\Software\Adobe\Acrobat\Exe", "", @"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe") as string
                    };
            var files = Directory.GetFileSystemEntries(@"C:\Program Files (x86)\Adobe\", @"*Acr*R*d*32.exe", SearchOption.AllDirectories);
            paths.AddRange(files);
            foreach(var path in paths) if (File.Exists(path)) return path;
            return "";
        }
    }

我的注册表与Acrobat没有任何关系:

HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\

..所以看来Adobe正在整个注册表中移动他们的注册表项,时间过去了...... 我希望他们将来避免将Acrobat本身移到Program Files文件夹之外......(你永远不会跟这些人有所了解......)

答案 2 :(得分:0)

我认为您可以应用以下逻辑: adobe文件关联保存在注册表中 - 您可以在下面阅读它们 HKEY_CLASSES_ROOT \ .pdf \ OpenWithList

这些子项是应用程序名称(如果有):

  • Acrobat.exe
  • AcroRD32.exe

使用它们来组合和读取键(打开读取应该存在)

  • HKEY_CLASSES_ROOT \应用程序\ XXXX \壳\打开\命令
  • HKEY_CLASSES_ROOT \应用程序\ XXXX \壳\读\命令

如果存在,它们将类似于 “C:\ Program Files(x86)\ Adob​​e \ Acrobat 7.0 \ Acrobat \ Acrobat.exe”“%1” 从那里你可以剥离%1并获得adobe应用程序路径。

这是C#代码:

private void AddShellCommandDefault(List<string> lst, RegistryKey shell, string reg  KeyOpenRead)
{
    var shellOpen = shell.OpenSubKey(regKeyOpenRead);
    if (shellOpen == null) return;

    var shellOpenCommand = shellOpen.OpenSubKey("command");
    if (shellOpenCommand == null) return;

    var defaultVal = shellOpenCommand.GetValue(null);
    if (defaultVal == null) return;

    int kex = defaultVal.ToString().LastIndexOf(".exe", StringComparison.OrdinalIgnoreCase);
    if (kex < 0) return;

    lst.Add(defaultVal.ToString().Substring(0, kex).Replace("\"", "") + ".exe");
}

public List<string> GetAdobeApps()
{
    var addobeList = new List<string>();

    // HKEY_CLASSES_ROOT\.pdf\OpenWithList\Acrobat.exe
    // HKEY_CLASSES_ROOT\Applications\Acrobat.exe\shell\Open\command
    //  default "C:\Program Files (x86)\Adobe\Acrobat 7.0\Acrobat\Acrobat.exe" "%1"

    var adobe = Registry.ClassesRoot.OpenSubKey(".pdf");
    if (adobe == null) return addobeList;

    var openWith = adobe.OpenSubKey("OpenWithList");
    if (openWith == null) return addobeList;

    var apps = Registry.ClassesRoot.OpenSubKey("Applications");
    if (apps == null) return addobeList;

    foreach (string sLong in openWith.GetSubKeyNames())
    {
        string s = sLong.Split(@"\/".ToCharArray()).Last();
        var adobeApp = apps.OpenSubKey(s);
        if (adobeApp == null) continue;

        var shell = adobeApp.OpenSubKey("shell");
        if (shell == null) continue;

        AddShellCommandDefault(addobeList, shell, "Read");
        AddShellCommandDefault(addobeList, shell, "Open");
    }

    return addobeList;
}        

When run GetAdobeApps, it returns collection similar to Count = 2 [0]: "C:\\Program Files (x86)\\Adobe\\Acrobat 7.0\\Acrobat\\Acrobat.exe" [1]: "C:\\Program Files (x86)\\Adobe\\Reader 9.0\\Reader\\AcroRd32.exe"