开发者

C# Windows registry GetValue Error

开发者 https://www.devze.com 2023-01-28 20:28 出处:网络
I have a program which outputs the various registry values from \"Software\\Microsoft\\Windows\\CurrentVersio开发者_Python百科n\\Explorer\\ComDlg32\\LastVisitedMRU\".

I have a program which outputs the various registry values from "Software\Microsoft\Windows\CurrentVersio开发者_Python百科n\Explorer\ComDlg32\LastVisitedMRU".

However the program outputs an error on Cannot implicity convert type'object' to 'string' at the s variable at the GetValue portion or the program! And the program outputs an error of "Cannot access a closed registry key too".

Can someone please give advise on the codes? Thanks!

The Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;

namespace RegKeys
{
class ConsoleApplication1
{
    static void Main(string[] args)
    {
        try
        {
            RegistryKey rk = Registry.CurrentUser;

            rk = rk.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedMRU", false);
            PrintKeys(rk);
        }

        catch (Exception MyError)
        {
            Console.WriteLine("An error has occurred: " + MyError.Message);
        }
    }

    static void PrintKeys(RegistryKey rk)
    {
        if (rk == null)
        {
            Console.WriteLine("No specified registry key!");
            return;
        }

        String[] names = rk.GetValueNames();

        Console.WriteLine("Subkeys of " + rk.Name);
        Console.WriteLine("-----------------------------------------------");

        foreach (String s in names)
        {
            try
            {
                if (s == "MRUList")
                {
                    continue;
                }

                else
                {
                    String val = rk.GetValue(s);
                    Console.WriteLine(s + " Contains the value of : " + val);
                }

                rk.Close();
            }

            catch (Exception MyError)
            {
                Console.WriteLine("An error has occurred: " + MyError.Message);
            }

            Console.WriteLine("-----------------------------------------------");
            rk.Close();
        }
    }
}
}


As well as Matti's advice, it's not clear why you're looking through all the subvalues. Why not just get the one you want? Something like this:

using System;
using Microsoft.Win32;

class Test
{
    static void Main()
    {
        using (var key = Registry.CurrentUser.OpenSubKey
               (@"Software\Microsoft\Windows\CurrentVersion\" + 
                @"Explorer\ComDlg32\LastVisitedMRU", false))
        {
            string value = (string) key.GetValue("MRUList");
            Console.WriteLine(value);            
        }
    }
}

(Note the using statement to make sure you always close the registry key.)

You might also want to put in some tests to make sure the key and value exist, of course.


Here's some advice on the codes:

GetValue returns an object, not a string. You need to either cast it to string, or call ToString on it (always use the former if you know it's actually a string).


If you are sure that the expected result is string, just typecast it.

String val = (String) rk.GetValue(s);
//or
String val = rk.GetValue(s) as String;


I believe GetValue is expecting a lowercase 's' string, which is a primitive, as opposed to an uppercase 'S' String which is an object. Try this:

String val = rk.GetValue(s.toString());

Or in general replace your usage of 'string' with 'String' except where 'String' is appropriate.


Use a Convert.ToString() method to convert the object to string. You can also use .ToString() but it may result in a null reference exception if the key does not exist.

Secondly, on the exception you get with the closed key. Change your for each loop and move the rk.Close() call outside the loop.

    foreach (String s in names)
    {
        try
        {
            if (s == "MRUList")
            {
                continue;
            }

            else
            {
                String val = rk.GetValue(s);
                Console.WriteLine(s + " Contains the value of : " + val);
            }


        }

        catch (Exception MyError)
        {
            Console.WriteLine("An error has occurred: " + MyError.Message);
        }

        Console.WriteLine("-----------------------------------------------");

    }
    rk.Close();


I'm using a struct and trying to do this. I kept getting objects returned when I wanted strings and when I did .ToString() the whole program just froze up. I realized that the properties I wanted to retrieve are also fields. It took me all day to figure it out:

string value = myObjectInstance.GetType().
   GetField("myFieldName").GetValue(newEntry) as string;

That worked perfectly for me.

0

精彩评论

暂无评论...
验证码 换一张
取 消