Click here to Skip to main content
15,900,818 members
Please Sign up or sign in to vote.
1.80/5 (2 votes)
See more:
There are a number of posts already on Code Project but I just can't get this program to read the path from the Registry where Adobe Acrobat is installed.

Here's the code:

C#
       private void Form1_Load(object sender, EventArgs e)
        {

           RegistryKey adobe = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Adobe");
            RegistryKey acroRead = adobe.OpenSubKey("Acrobat Reader");
            string[] acroReadVersions;
            string vnumber = "";
            if (adobe != null)
            {
                acroReadVersions = acroRead.GetSubKeyNames();
                foreach (string versionNumber in acroReadVersions)
                {
                    switch (versionNumber)
                    {
                        case "9.0":  //do something;
                            vnumber = versionNumber;
                            break;
                        case "10.0":  //do something;
                            vnumber = versionNumber;
                            break;

                        default:
                            break;
                    }

                }

            }

            RegistryKey acroVersion = acroRead.OpenSubKey(vnumber);
            RegistryKey acroPath = acroVersion.OpenSubKey("InstallPath");
            acroPath = acroPath;
// following returns null. Should return C:\Program Files (x86)\Adobe\Reader 10.0  \Reader on my system
            string path = (string)acroPath.GetValue("Default"); 
            path = path;      


What's wrong with this code?
Posted

The (Default) value is special. To retrieve it, specify either an empty string ("") or null:
C#
string path = (string)acroPath.GetValue(null);


That should solve the problem you've asked about.

A few other tips:

1) You don't need to open each individual subkey in turn - you can specify the complete path, or any part thereof in this case, thus with one call you can do this:
C#
RegistryKey acroRead = Registry.LocalMachine.OpenSubKey(@"Software\Adobe\Acrobat Reader");


2) The above might help you to avoid some errors - for example you are checking that "adobe" is not null, when you should be testing against acroRead:
C#
if (acroRead != null)
{
    acroReadVersions = acroRead.GetSubKeyNames();


3) RegistryKey is disposable, so ideally you should wrap the use of it in a "using" block. Opening fewer keys will mean you need to do this less often (and presently, doing OpenSubKey().OpenSubKey() you can't specify a using statement for each one!)

4) Not sure what your extra assignments are for at the end (path = path; etc. These don't do anything).

5) In testing I noted that I have version 11.0 of Adobe Reader, so you might want to add that in.

6) I assume Adobe's installation removes earlier version registry keys? If that cannot be assumed you may want to check for the highest value rather than the first one encountered.

Taking the liberty of re-working your code slightly then, apart from item 6 - and allowing for this to work on 32-bit windows (targeting x86 or AnyCPU) or 64-bit windows (targeting x86, x64 or AnyCPU):
C#
RegistryKey acroRead = Registry.LocalMachine.OpenSubKey(@"Software\Adobe\Acrobat Reader");
if (null == acroRead)
{
    acroRead = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Adobe\Acrobat Reader");
}
if (acroRead != null)
{
    using (acroRead)
    {
        string vnumber = "";
        string[] acroReadVersions = acroRead.GetSubKeyNames();
        foreach (string versionNumber in acroReadVersions)
        {
            switch (versionNumber)
            {
                case "9.0":  //do something;
                    vnumber = versionNumber;
                    break;
                case "10.0":  //do something;
                    vnumber = versionNumber;
                    break;
                case "11.0":  //do something;
                    vnumber = versionNumber;
                    break;
                default:
                    break;
            }
        }
        if (!string.IsNullOrEmpty(vnumber))
        {
            using (RegistryKey acroVersion = acroRead.OpenSubKey(vnumber))
            {
                using (RegistryKey acroPath = acroVersion.OpenSubKey("InstallPath"))
                {
                    string path = (string)acroPath.GetValue(null);
                    // Do something with path, or return it, or else declare it outside the "using" blocks :)
                }
            }
        }
        else
        {
            // Error - version number not found
        }
    }
}
else
{
    // Error - adobe key not found
}



Regards,
Ian.
 
Share this answer
 
v2
Comments
Ian A Davidson 13-May-13 19:23pm    
PS. If compiling to run on x86, you don't need to worry about the Wow6432Node - windows will automatically look there instead. However, if you are compiling for x64 or "Any CPU", then you will need to. The best answer would be to look in both places. I'll update the code above with this change. Ian.
If the application you're looking for is a 32-bit app on a 64-bit system, the registry path will be HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Adobe\...
 
Share this answer
 
I tried using the path HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Adobe\Acrobat Reader
an exception is thrown "Object reference not set to amn instance of an object. "
 
Share this answer
 
Thank you this works perfectly!
 
Share this answer
 
Comments
Ian A Davidson 13-May-13 20:01pm    
Glad to hear it Steven. Could you please use the "Question or Comment?" button to reply, rather posting comments as solutions - I only saw this by chance! - and mark the solution as answered, if indeed it is. Thank you! And all the best with your program.
Regards,
Ian.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900