I know there are lots of sites about this. I've been testing out different ideas for about 6 hours now. I'm trying to get a 32bit app to modify the 64bit registry. I need to set the permissions to HKLM\Software\Microsoft\Windows\Current Version\Installer\UserData\ If you are wondering why, it's because our software throws an error if the permissions aren't correct.
Here is what I'm trying
static bool SetRegistryPermissions(string hkLmKey, string userAccount)
{
//this will force the app to see the 64bit registry instead of being redirected
RegistryKey localMachineX64View = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey rk = localMachineX64View.OpenSubKey(hkLmKey, true);
//This redirects to the Wow6432Node in the registry
//RegistryKey rk = Registry.LocalMachine.OpenSubKey(hkLmKey, true);
The program was working fine on a test key in WoW6432Node prior to changing the key to localMachineX64. Now I get a security exception when debugging on the OpenSubKey.
Any advice is welcome and Thanks for your time.
P.S. Any suggestions for books that contain good info writing NT permissions in C# would be a bonus.
Could you create a small 64 bit application that could set the 64 bit permissions? You could then call the exe from your installer's post install event.
I'm unsure if there is a .NET approach to this, but the Windows API definitely provides a solution. You can 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. This will allow your 32 bit app to access the full registry, not just the Wow6432Node sandbox.
Edit: pinvoke.net has a C# example ready to go: http://www.pinvoke.net/default.aspx/advapi32/RegOpenKeyEx.html
Related
Why this code is not working
RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
RegistryKey key = baseKey.OpenSubKey(REGISTY_NOTIFICATION_ROOT_PATH, true);
key.SetValue("NOC_GLOBAL_SETTING_ALLOW_TOASTS_ABOVE_LOCK", bytes, RegistryValueKind.DWord);
After this i am calling close to flush the changes.
key.Close();
Tried baseKey .Close(); also but no luck
Ideally it should update the notification setting but it is not. Is there any other way to update DWORD value in c#
Just to make it clear
I am using AppServiceConnection to actually communicate with win32 app and my win32 app is actual updating the Registry.
My question is above code is not updating the registry value, It's not throwing any error but not updating the value also.
Thank
You can't access registry with uwp directly. Please check this case reply
You can read registry values from a Win32 runFullTrust background process launched from a UWP application, and you can write values in registry from an "elevated" Win32 application launched from that runFullTrust process.
For details steps please refer UWP sends request to desktop extension blog. This is code sample.
work on C# window application.I want to write on registry.i know how to write on registry.I use bellow syntax to write on registry.
Microsoft.Win32.RegistryKey key;
key = Microsoft.Win32.Registry.CurrentUser.cre.CreateSubKey("asb");
key.SetValue("asb", "Isabella");
key.Close();
But problem is i fail to write on specified location .i want to write on bellow location
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
On this location want to add string value="abc" and ValueData="efd"
If have any query plz ask.thanks in advance.
For HKCU:
string keyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
RegistryKey rk = Registry.CurrentUser.OpenSubKey(keyName, true);
rk.SetValue("abc", "efd");
rk.Close();
For HKLM you need to do it with administrative privileges. That requires adding a manifest to your program to invoke the UAC prompt on Vista or Win7.
Writing to HKEY_LOCAL_MACHINE requires administrative privileges. And if you're running on Windows Vista or 7, it also requires process elevation, lest you run afoul of UAC (User Account Control).
The best thing is only to write to this registry key during installation (where you will have full administrative privileges). You should only read from it once your application is installed.
Save all regular settings under HKEY_CURRENT_USER. Use the Registry.CurrentUser field to do that. Or, better yet, abandon the registry altogether and save your application's settings in a config file. Visual Studio has built-in support for this, it's very simple to do from C#. The registry is no longer the recommended way of saving application state.
RegistryKey reg = Registry.LocalMachine.
OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Run", true);
// set value of "abc" to "efd"
reg.SetValue("abc", "efd", RegistryValueKind.DWord);
// get value of "abc"; return 0 if value not found
string value = (string)reg.GetValue("abc", "0");
I'm writing an application that needs to create a special user account hidden from login screens and the Control Panel users applet. By writing a DWORD value of 0 with the user name to the registry key below, I'm able to accomplish this goal:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Winlogon\SpecialAccounts\UserList
The problem is that under Windows 7 with UAC on, no matter what I try, I cannot programmatically write a value to the key above.
It is my understanding that writing to certain keys this is not allowed on Windows 7 with UAC on, unless you are running with Administrative privileges. I've added an application manifest requestedExecutionLevel level="requireAdministrator" uiAccess="false", I accept the UAC prompt when my program is run, my account is a member of Administrators, yet I am still unable to write to the above registry key.
What more do I need to do? How is it possible, in any application configuration, to write keys and values under HKEY_LOCAL_MACHINE\SOFTWARE?
Further information ... When my program runs, no errors are thrown and it seems to write values. My guess is that Windows is virtualizing the location to which I am writing. I need to write to the actual location, not a virtual one, if I am to hide this special user account.
Probably the program runs as 32-bit program on the 64-bit operation system? In the case I recommend you to search the values which you created under Wow6432Node subkey of the HKEY_LOCAL_MACHINE\SOFTWARE.
You can read more about such kind of virtualization here. You can use KEY_WOW64_32KEY flag in some API to be able to work with full registry without virtualization.
Write Value to Registry
string user = Environment.UserDomainName + "\\" + Environment.UserName;
RegistrySecurity rs = new RegistrySecurity();
rs.AddAccessRule(new RegistryAccessRule(user,
RegistryRights.WriteKey | RegistryRights.ChangePermissions,
InheritanceFlags.None, PropagationFlags.None, AccessControlType.Deny));
RegistryKey rk = null;
try
{
rk = Registry.CurrentUser.CreateSubKey("SOFTWARE\\TEST",
RegistryKeyPermissionCheck.Default, rs);
rk.SetValue("NAME", "IROSH);
rk.SetValue("FROM", "SRI LANKA");
}
This could have something to do with the redirection they added in Vista. I would be curious if you tried to read that registry value from your code, if you would get back the value you were expecting. You may also want to fire up RegMon to see if you can see where the redirection may be forcing you.
RegistryKey rk = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Run",true);
rk.SetValue("Name", "Value");
I am using the below code to disable the task manager for a kiosk application which works perfectly
public void DisableTaskManager()
{
RegistryKey regkey;
string keyValueInt = "1";
string subKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
try
{
regkey = Registry.CurrentUser.CreateSubKey(subKey);
regkey.SetValue("DisableTaskMgr", keyValueInt);
regkey.Close();
}
catch (Exception ex)
{
MessageBox.Show("DisableTaskManager" + ex.ToString());
}
}
But when i run this in OS hardened machine i get the following error,
DisableTaskManagerSystem.UnauthorizedAccessException:
Access to the registry key 'HKey_Current_User\Software\Mictrosoft\Windows\CurrentVersion\Policies\System' is denied.
at Microsoft.win32.RegistryKey.win32Error(int32 errorcode, String str)
How can i overcome this ? I need to do this for a Kiosk application.
take a look at this, im not yet a good enough C# Developer to comment but i know that during my work with other developers they came accross the UAC In windows 7, If thats what were talking about here.
http://www.aneef.net/2009/06/29/request-uac-elevation-for-net-application-managed-code/
Well the guy that set up that machine basically asked the reverse... "How do I prevent a non-administrator from messing with group policy". So rather engaging in a group policy arms race, you can either do it at install time when running as an admin, or just skip that part of the code when not running as a user that has permission to do so.
Don't have your application disable task manager but instead use a windows service or scheduled task. Your application is going to run in the context of the current user and won't have rights to the registry key. Instead you can create either a windows service or a scheduled task which can run as a user with higher privileges and can write to the registry.
With a windows service you can communicate it through any IPC mechanism such as custom service messages, Sockets, .NET Remoting, WCF, or whatever, to tell it to turn task manager on/off.
the code requires an elevated privilege to access registry. However there is just a fragment of code that requires these extra permission. To handle such scenarios impersonation is used i.e. you will execute this application as normal user only but that particular piece of code will be executed as if you were an Administrator.
http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx
I have Application settings stored under HKEY_LOCAL_MACHINE\SOFTWARE\MyCompany branch. Settings must be same for different users and that is the reason why settings are not under HKEY_CURRENT_USER. Registry values are only read during use of application.
Now, in Windows Vista and due to UAC you can't anymore use following code to read registry values:
RegistryKey myKey = Registry.LocalMachine.CreateSubKey
("SOFTWARE\\MyCompany\\MyAppName");
How can I read the values from LocalMachine branch in my code (C#)?
The problem is that you are trying to create a key not read it. You should be able to read values from HKLM just fine on Vista if you use the appropriate API.
RegistryKey myKey = Registry.LocalMachine.OpenSubKey(
#"Software\MyCompany\MyAppName",
false);
Notice the false parameter in the above. This has the effect of opening the key in a read only mode. This is the default setting for OpenSubKey but I prefer to be explicit (mainly because I can't ever remember the default).