4

I am trying to get the last used Keyboard layout by the current user by reading the HKCU\Keyboard Layout\Preload\1 from my application. Every time the default keyboard is changed in the control panel I can see that the value at the above location changes(I can see this by having RegEdit open). But for some reason my application still reads the old value without taking into the account the latest refresh which I can see on RegEdit.

string KeyboardLayoutRegKey = "Keyboard Layout\\Preload";
pLastUsedKeyboard = RegistryAccessor.CurrentUser.OpenSubKey(KeyboardLayoutRegKey).GetValue("1").ToString(),

When I change the value from English-US to French the hexadecimal value in the registry changes from 409 to 40c which I can see in RegEdit, but my application still reads it as 409 until I reboot? Why does it do that? My application is targeted to AnyCPU.

EDIT

/// <summary>
/// Provides access to the registry. 
/// </summary>
public class RegistryAccessor : IRegistryAccessor
{
    /// <summary>
    /// Contains information about the current user preferences. This field reads the Windows registry base key HKEY_CURRENT_USER.
    /// </summary>
    public IRegistryKey CurrentUser
    {
        get
        {
            return new RegistryKeyWrapper(Registry.CurrentUser);
        }
    }

    /// <summary>
    /// Contains the configuration data for the local machine. This field reads the Windows registry base key HKEY_LOCAL_MACHINE.
    /// </summary>
    public IRegistryKey LocalMachine
    {
        get
        {
            return new RegistryKeyWrapper(Registry.LocalMachine);
        }
    }
    /// <summary>
    /// Contains the configuration data for the Users. This field reads the Windows registry base key HKEY_USERS.
    /// </summary>
    public IRegistryKey Users
    {
        get
        {
            return new RegistryKeyWrapper(Registry.Users);
        }
    }

}
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Sai
  • 682
  • 2
  • 12
  • 35
  • RegistryAccessor is what? – pm100 Sep 13 '16 at 20:10
  • @pm100 RegistryAccessor is a wrapper around Registry that helps with mocking during unit tests. – Sai Sep 13 '16 at 20:15
  • "but my application still reads it as 409 until I reboot?" -- so when you restart just the application it still reads the old value? And not until you reboot the OS then restart the program does it show the new value? – Quantic Sep 13 '16 at 20:15
  • Yes, the workflow is, I change the input language -> start the application ->find out that it reads the old value -> reboot the OS -> start the application -> it then reads the new value. – Sai Sep 13 '16 at 20:17
  • 1
    we are trusting you that this class doesnt do anything weird (like caching), you just showed one part. – pm100 Sep 13 '16 at 20:33
  • If you're doing this for unit testing then it has to be storing some kind of mock registry settings somewhere then right? I assume so you aren't messing up your actual registry. I don't know enough about the wrapper in question... – KSib Sep 13 '16 at 20:35
  • 1
    Is your app running as a service, are you doing any user impersonation, and is this system on a domain network? – Quantic Sep 13 '16 at 20:44
  • @Quantic Yes, the app is a combination of windows service + win forms, service runs as SYSTEM user and the PC is not on a domain. – Sai Sep 13 '16 at 20:46
  • 2
    If it's a service then [this post](http://stackoverflow.com/a/5353157/5095502) says that there "is no HKCU for the SYSTEM account", I don't know how you are getting values from it but I'm pretty sure this is the root of your problem. [This post](http://stackoverflow.com/a/6564184/5095502) shows how to impersonate a user and load his profile so that you can work directly with HKCU, but HKCU is just a symbolic link to a user so if you know the SID and have access I think you can just access the key directly -- read the post by "vcsjones" in the link about impersonating above. – Quantic Sep 13 '16 at 20:51
  • @Quantic You are right! Saved a lot of time and effort. Brilliant answer! I suggest making your comment an answer to help benefit future references. – Sai Sep 13 '16 at 22:47

1 Answers1

0

Registry values can't be "refreshed" without restarting your application. If you need to get notified when registry key value is changed while your app is running for that purpose you can use WMI to implement RegistryValueChangeEvent. You can refer to this answer that can help you implementing it in your application