1

我正在努力在 Windows 窗体中获取和设置注册表值。

我的代码如下所示:

Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("SmogUser");
if (((Guid)key.GetValue("DeviceId", Guid.Empty)) == Guid.Empty)
{
    Guid deviceId = Guid.NewGuid();
    key.SetValue("DeviceId", deviceId);
    key.Close();
}
else
{
    Guid deviceId = (Guid)key.GetValue("DeviceId");
}

我第一次运行程序时,它进入了 if 子句并设置了deviceId,但是当我第二次运行时,程序没有继续,也没有异常。

问题是什么?

4

3 回答 3

2

我不太明白为什么RegistryKey.GetValue()方法行为是错误的,但是我使用以下代码解决了您的问题:

        Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("SmogUser");
        if (key != null)
        {
            var value = key.GetValue("DeviceId", null) ?? Guid.Empty;

            if (Guid.Empty.Equals(value))
            {
                Guid deviceId = Guid.NewGuid();
                key.SetValue("DeviceId", deviceId);
                key.Close();
            }
            else
            {
                var deviceId = (Guid)key.GetValue("DeviceId");
            }
        }

似乎如果您将null其作为默认值传递,则该方法不会崩溃。然后,您可以检查 null 并将Guid变量值设置为Guid.Empty.

于 2013-04-17T08:00:50.370 回答
1

Guid.Empty您在第二个参数中传递默认值key.GetValue("DeviceId", Guid.Empty),然后将其与Guid.Empty.

第一次没有键时,Guid.Empty返回并进入if块。然后返回另一个值(DeviceId)并输入else

考虑 msdn 以获取有关RegistryKey.GetValue参数的信息。签名是

public Object GetValue(
    string name,
    Object defaultValue)

RegistryKey.CreateSubKey“创建一个新的子项或打开一个现有的子项”。

当注册表中没有键时,您可以看到第二个参数将被返回。请注意,注册表在您的程序执行之间持续存在


这里的问题是您正在读取注册表两次。

RegistryKey key = Registry.CurrentUser.CreateSubKey("SmogUser");
Guid regValue = Guid.Parse(key.GetValue("DeviceId", Guid.Empty).ToString());
if (value == Guid.Empty)
{
    regValue = Guid.NewGuid();
    key.SetValue("DeviceId", regValue);
    key.Close();
}
//here you have Guid in regValue, which is exactly the same
//as in registry. No need to call GetValue again
于 2013-04-17T07:52:22.693 回答
1

您正在尝试从对象转换为 Guid,这是导致错误的原因。这有效 -

Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("SmogUser");
if ((new Guid(key.GetValue("DeviceId", Guid.Empty).ToString()) == Guid.Empty))
{
    Guid deviceId = Guid.NewGuid();
    key.SetValue("DeviceId", deviceId);
    key.Close();
}
else
{
    Guid deviceId = new Guid(key.GetValue("DeviceId").ToString());
}

基本上我正在转换为字符串,然后从字符串创建一个新的 Guid 对象。第二次直接从对象转换为 Guid 不起作用,因为正在返回 Guid 字符串值。

至于没有抛出异常的问题,这发生在 64 位的 Visual Studio 上,请参阅同一主题的其他帖子 -

Visual Studio 2010 调试器不再因错误而停止 VS2010 在 64 位版本的 Windows 上的 WinForms 应用程序中不显示未处理的异常消息

最好的解决方案是围绕您的代码进行尝试

于 2013-04-17T08:05:40.287 回答