Расположение ключа реестра Adobe Acrobat Reader постоянно меняется

Мое требование состоит в том, чтобы прочитать конкретный ключ реестра, связанный с Adobe Acrobat Reader, и принять решение на основе значения этого ключа.

Хотя это кажется простым, так как мне нужно запросить ключ с помощью класса реестра (для .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 выпускает новую версию, я должен убедиться, что мне нужно обращаться с ней по-другому. Любые предложения для лучшего подхода.

Спасибо


person this-Me    schedule 16.12.2010    source источник


Ответы (3)


вам лучше всего открыть раздел реестра, содержащий номера версий, затем перечислить каждый подключ, возможно, проверив, что он выглядит как номер версии, а затем найти в каждом из этих подразделов то, что вы хотите. Возможно, вы захотите использовать только версию с наибольшим номером, которую вы найдете.

Очевидно, это будет работать только в том случае, если то, что вы хотите, всегда содержится в одной и той же записи реестра относительно ключа версии или всегда в записи с одним и тем же именем (и тогда вам придется перечислять каждый элемент в подразделе в поисках того, что вы хотите ).

если вещь, которую вы хотите, меняет имя и местоположение в каждом выпуске, у вас возникнет проблема, если только вы не сможете каким-то образом распознать ее из данных, и в этом случае перечислите каждый элемент и посмотрите на данные 4 и попытайтесь решить, является ли это тем, что вы хотите , но этот подход, вероятно, будет чреват опасностью или ложными срабатываниями.

person Sam Holder    schedule 16.12.2010

Что ж, у меня точно такая же проблема, и, поскольку я знаю, что 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 в будущем ... (вы никогда не знаете, с этими людьми ... .)

person NoOne    schedule 20.07.2013

Я думаю, вы можете применить следующую логику: ассоциации файлов Adobe хранятся в реестре — вы можете прочитать их в HKEY_CLASSES_ROOT \ .pdf \ OpenWithList

Эти подразделы являются именами приложений (если есть):

  • Acrobat.exe
  • AcroRD32.exe
  • и т.п.

Используйте их для комбинирования и чтения ключей (должен присутствовать элемент Открыть или Чтение).

  • HKEY_CLASSES_ROOT\Приложения\XXXX\оболочка\Открыть\команда
  • HKEY_CLASSES_ROOT\Applications\XXXX\shell\Read\command

Если они присутствуют, они будут похожи на «C:\Program Files (x86)\Adobe\Acrobat 7.0\Acrobat\Acrobat.exe» «%1», откуда вы можете удалить %1 и получить путь к приложению Adobe.

Here is C# code:

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"
person Sasha Bond    schedule 03.07.2014