1

I am working on getting and setting registry values in Windows Forms.

My code looks like this:

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

When I run the program the first time, it enters into the if clause and sets deviceId, but when I run the second time, the program is not continuing and there is no exception.

What is the problem?

John Willemse
  • 6,608
  • 7
  • 31
  • 45
Mehmet Ince
  • 4,059
  • 12
  • 45
  • 65

3 Answers3

2

I don't understand well why RegistryKey.GetValue() method behavior is wrong, but I fixed your problem using this code:

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

It seems that if you pass null as default value the method doesn't crash. Then, you can check for null and set Guid variable value to Guid.Empty.

HuorSwords
  • 2,225
  • 1
  • 21
  • 34
1

You pass default value as Guid.Empty in second parameter at key.GetValue("DeviceId", Guid.Empty) and then compare it to Guid.Empty.

First time when there is no key, Guid.Empty is returned and you enter if block. Then another value is returned (DeviceId) and you enter else block

Consider msdn for information regarding parameters at RegistryKey.GetValue. Signature is

public Object GetValue(
    string name,
    Object defaultValue)

RegistryKey.CreateSubKey will "Create a new subkey or open an existing subkey."

Which you can see second parameter will be returned, when there will be no key in the registry. Note that registry persists between execution of your program


The problem here is that you are reading registry twice.

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
Ilya Ivanov
  • 23,148
  • 4
  • 64
  • 90
  • I don't understand, while key.GetValue("blabla", default) is working first time, why key.GetValue("blabla", default) is not working? – Mehmet Ince Apr 17 '13 at 07:58
  • @MehmetInce because you already wrote some value into it. Windows registry stays the same between program execution, it persists – Ilya Ivanov Apr 17 '13 at 08:01
  • But I exited program and ran it second time. – Mehmet Ince Apr 17 '13 at 08:06
  • @MehmetInce yes, registry **stays** the same when you exit your program. It is like file system - if you write to it, then you can read it even if you restart your program – Ilya Ivanov Apr 17 '13 at 08:41
1

You are trying to cast from object to Guid which is the cause of the error. This works -

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

Basically I'm converting to string and then creating a new Guid object from the string. Casting to Guid directly from object does not work the second time because the Guid string value is being returned.

As for the problem where there is no exception thrown, this happens with Visual Studio on 64 bit, See other posts on the same topic -

Visual Studio 2010 debugger is no longer stopping at errors VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows

The best solution is to have a try-catch around your code

Community
  • 1
  • 1
Arun
  • 969
  • 7
  • 17