Расположение раздела реестра Adobe Acrobat Reader постоянно меняется - PullRequest
2 голосов
/ 16 декабря 2010

Мое требование - прочитать конкретный раздел реестра, связанный с 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 ]

2 голосов
/ 16 декабря 2010

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

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

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

0 голосов
/ 03 июля 2014

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

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

  • Acrobat.exe
  • AcroRD32.exe
  • и т. Д.

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

  • HKEY_CLASSES_ROOT \ Applications \ XXXX \ shell \ Open \ command
  • HKEY_CLASSES_ROOT \ Applications \ XXXX \shell \ Read \ command

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

Вот код C #:

</p>

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

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"
0 голосов
/ 20 июля 2013

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

...