C# Windows 注册表 GetValue 错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4364134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:44:24  来源:igfitidea点击:

C# Windows registry GetValue Error

c#windowsregistry

提问by JavaNoob

I have a program which outputs the various registry values from "Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedMRU".

我有一个程序可以从“Software\Microsoft\Windows\CurrentVersion\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".

但是,该程序在 GetValue 部分或程序的 s 变量处无法隐式将类型“对象”转换为“字符串”时输出错误!并且程序输出错误“也无法访问关闭的注册表项”。

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();
        }
    }
}
}

采纳答案by Jon Skeet

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

除了 Matti 的建议,您还不清楚为什么要查看所有子值。为什么不直接得到你想要的呢?像这样的东西:

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.)

(注意 using 语句以确保始终关闭注册表项。)

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

你可能希望把一些测试,以确保重点和存在的价值,当然。

回答by Matti Virkkunen

Here's some advice on the codes:

这里有一些关于代码的建议:

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

GetValue 返回一个object,而不是一个string。您需要将其转换为字符串,或者调用ToString它(如果您知道它实际上是一个字符串,请始终使用前者)。

回答by jvanrhyn

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

使用一种Convert.ToString()方法将 转换object为字符串。您也可以使用,.ToString()但如果键不存在,可能会导致空引用异常。

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

其次,在例外情况下,您获得了封闭的钥匙。更改for each循环并将 rk.Close() 调用移到循环外。

    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();

回答by Jared Beach

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:

我正在使用结构并尝试执行此操作。当我想要字符串时,我一直在返回对象,而当我执行 .ToString() 时,整个程序就死机了。我意识到我想要检索的属性也是字段。我花了一整天才弄明白:

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

That worked perfectly for me.

这对我来说非常有效。

回答by Nayan

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;

回答by DGH

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:

我相信 GetValue 需要一个小写的 's' 字符串,它是一个原始字符串,而不是一个大写的 'S' 字符串,它是一个对象。尝试这个:

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

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

或者通常将“字符串”的用法替换为“字符串”,除非“字符串”是合适的。