Cannot read a registry value in Windows 8 - c#

I have following C# code, which reads the UAC state from registry in Windows 7
object obj = Registry.LocalMachine.GetValue(#"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA", (long)1);
It works perfectly on Windows 7 with admin/not-admin accounts.
It always returns the default value I provide it under Windows 8.
The registry key is there. I can see its value with regedit. But the C# code does not read it. Can anybody tell why? It is a .net 4 application. The user account is unelevated admin.

It returns the default value (on both Windows 7 and 8). Here's the code that reads the correct Registry value on both Windows 7 and 8, without running as administrator.
object obj = Registry.GetValue(
#"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\",
"EnableLUA",
(long)1);
Note that we call GetValue method on Registry, not on Registry.LocalMachine, and we pass key and value name as two separate parameters.

You need to require administrative privileges at least to be able to access the registry by default. Windows 8 developers possibly thinks it's safer to keep it that way.

Related

Cant getValueNames() from HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

I want to read all Values out of the Registry that are in the
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
I am trying to do this with the following Code:
RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", false);
string[] values = key.GetValueNames();
But my values String is always empty.
The interesting part about that is, if I change the Code to
RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion", false);
string[] values = key.GetValueNames();
I get the correct amount of ValueNames in CurrentVersion. Why does it not work in \Run?
If I change from LocalMachine to CurrentUser the \Run path works too.
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", false);
string[] values = key.GetValueNames();
Can someone tell me why my first CodeExample does not work? Thanks!
You don't provide details on whether your C# application is 32-bit (x86) or 64-bit (x64). If the application is 32-bit running on 64-bit Windows, registry calls for HKLM\Software are redirected to HKLM\Software\Wow6432Node. Microsoft call this the Registry Redirector. Only certain keys are redirected, the details are in the linked article.
If your application is 64-bit, these registry calls are not redirected.
You can test this by manually adding a single REG_SZ entry of say "TestWOW" to HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run. Your 32-bit code should read this value (even though you actually asked for another registry key!).
If you can, re-compile your application as 64-bit. Now the same code will return the expected values from HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.
Unfortunately, I'm not aware of a mechanism to force Windows to NOT re-direct your registry calls to the Wow64 node for 32-bit applications running on a 64-bit OS.

windows: XP -> current: how to tell if in CONSOLE or RDP session?

I have a messy collection of Windows platforms in various labs. Everything from XP to the latest. I have a simple C#/.NET app that runs at user login and logout. I need to differentiate between true Console logins and RDP sessions. I am using
System.Diagnostics.Process.GetCurrentProcess().SessionId
to get a sessionId but I don't see anything that says "you are on the Console" or "you are in an RDP session". Is there such a thing?
For my needs it turns out that the windows environment variable %sessionname% holds the info I am looking for. In my C# code I can say:
string sessionName = Environment.GetEnvironmentVariable("SESSIONNAME")
?? "CONSOLE";
%sessionname% seems to hold either the string "console" or "rdp-(something)#(number)", ex "rdt-tcp#1234". I don't know the whole range of possible values but it looks like it will work for my needs.
You can determine which session ID (if any) is currently attached to the physical console by calling the WTSGetActiveConsoleSessionId() function.

How to change screen saver timeout and screensaverissecure in windows using c#

How to change screen saver timeout and screensaverissecure using user32.dll for the current user (or) any other users in windows through C# code, as my application is running with SYSTEM privileges in the background process.
When we change the value of this registry using c# or scripting HKEY_CURRENT_USER\Control Panel\Desktop\ScreensaverTimeout
and HKEY_CURRENT_USER\Control Panel\Desktop\ScreenSaverIsSecure
this effect is showing only after reboot of machine.
when we change the registry value using c# code with SYSTEM privileges those changes are not effecting with new values.
Q1: ...this effect is showing only after reboot of machine:
After updating registry, you can call UpdatePerUserSystemParameters to force Windows to reread the configuration from the registry (so the update takes effect immediately).
rundll32.exe user32.dll, UpdatePerUserSystemParameters
Q2: ...with SYSTEM privileges those changes are not effecting with new values:
You need to launch a new process which is running in the same session as the current log on user, and update the registry values from the new process. This is good question to get started.
After you change windows settings like this you need to call the WinApi SendNotifyMessage with a WM_SETTINGCHANGE message to all windows. This is why your settings are not being updated until reboot. (I think you would find a logoff-on would achieve the same for that user).
WinApi
https://msdn.microsoft.com/en-us/library/windows/desktop/ms725497%28v=vs.85%29.aspx
C# wrapper over send message
http://www.pinvoke.net/default.aspx/user32.sendnotifymessage

How to use C# to check if WUA is set to "Install updates automatically (recommended)?"

We have a server running a 6 day job that just reset, because Windows Update Agent (WUA) automatically rebooted the machine to install updates.
I would like to alter my C# app to warn the user if this setting is on in the future, so we don't end up suffering from random reboots, which forces a restart of said 6-day job, wasting 4 days of CPU time.
Does any know if it is possible to check within WUA that "Important Updates" is set to "Install updates automatically (recommended)", within C#?
There is an API for the Windows Update Agent (WUA), its general use is described at:
Install Windows Update Using C#
Here is the C# code:
// See http://techforum4u.com/entry.php/11-Install-Windows-Update-Using-C
var auc = new WUApiLib.AutomaticUpdatesClass();
if (auc.Settings.NotificationLevel ==
AutomaticUpdatesNotificationLevel.aunlScheduledInstallation)
{
Console.Write("{0}Warning W20120307-1107. Windows Update Agent (WUA) is capable of rebooting the PC automatically. Recommend switching this off for the duration of this 6-day batch process.\n", NPrefix());
}
After adding c:\WINDOWS\system32\wuapi.dll, if you get a compile error, see Interop type cannot be embedded.
Note that this approach will only work on Windows 7, add a try/catch around it to prevent a crash on Windows XP. See the forums for how to get it working on XP (you have to reference WUA version 1, WUA for Windows 7 is version 2).

Getting back "ResolveIOD" while trying to open HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\ on Windows 7?

I'm trying to get at the UserData registry subkeys on a C# 3.5 application so I can look up the installed location of an external program to start it.
Doing something like this:
RegistryKey installerKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
and then
RegistryKey userDataKey = installerKey.OpenSubKey("UserData");
returns null; if I go back and call installerKey.GetSubKeyNames() to figure out which subkey names are present under Installer it only returns one subkey name: ResolveIOD. I haven't been able to find what only being able to find this key indicates.
regedit does not show the ResolveIOD key being there, and it shows that much more than just that one key is present - UserData, Folders, Secure, etc are all there and not returned by GetSubKeyNames() either.
This is my first time accessing anything in the Installer section of the registry hive, so I've probably done something wrong. Is there some kind of special permission I have to request in order to read these (probably sensitive, security-wise) keys from a client application, or is this generally not an acceptable thing to do on Windows 7 and I should find an alternative way of figuring out where the program is located?
Because I'm seeing this mentioned on other registry questions: This is running as a 32-bit application on 64-bit Windows.
First, to ensure you are accessing the 64-bit registry rather than the Wow6432Node sandbox, use the RegOpenKeyEx function with KEY_WOW64_64KEY (http://msdn.microsoft.com/en-us/library/ms724878%28v=vs.85%29.aspx) included as one of the access options.
pinvoke.net has a C# example: http://www.pinvoke.net/default.aspx/advapi32/RegOpenKeyEx.html
Also note that with UAC enabled, an unelevated app will, at best, only have read access to HKLM.

Categories

Resources