I'm trying to make a program that changes the registry key values on remote machines to block/allow users from personalizing their lock-screen images. It seems the key I need to create is at HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalizationwith a name of NoChangingLockScreen.
I could easily do this with a .reg file and merge any changes into their registry (I planned on creating a windows service to monitor for changes in the file), although it seems I cannot even modify any keys inside the HKEY_LOCAL_MACHINE class.
Please note:
I am a domain admin across our network, and all remote computers have admin rights
This issue does not just occur when modifying a remote PC's keys, but my own as well
I've created the RegistryKey object as writable (See below code)
It seems I cannot even use the OpenSubKey method, as reading the local_machine path just throws an object exception
I've checked the permissions inside the Registry for that specific class and made sure my account had full control
I have found very little documentation on other people having permissions issues
RegistryKey myKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Policies\Microsoft\Windows", true);
Registry.ClassesRoot is for HKEY_CLASSES_ROOT. You need to use Registry.LocalMachine field like this:
using (var registryKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Policies\Microsoft\Windows", writable: true))
{
...
}
Also note, that this is for local registry access. If you wish to open remote registry, you need to use another method:
using (var remoteBaseKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "RemoteMachineName"))
using (var registryKey = remoteBaseKey.OpenSubKey(#"SOFTWARE\Policies\Microsoft\Windows", writable: true))
{
...
}
Related
I have a web API which simply
clone a .docx file
convert that cloned .docx to a .pdf format
using DocumentFormat.OpenXml.Packaging;
[HttpPost("clone")]
public IActionResult CloneBillFromTemplate()
{
var templateFilePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "Bill", "PaymentTempl.docx");
var clonedFilePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "Bill", "ClonedBill.docx");
var pdfFilePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "Bill", "FinalBill.pdf");
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(templateFilePath, true))
{
var clonedDoc = wordDoc.Clone(clonedFilePath);
System.Threading.Thread.Sleep(500);
clonedDoc.Save();
clonedDoc.Close();
}
using (var converter = new OfficeConverter.Converter())
{
converter.Convert(clonedFilePath, pdfFilePath);
}
return Ok();
}
Everything works fine when debugging (for sure :3) and also on IIS
But when I deploy to Azure App service, I got this type of error (stack trace + exception message).
Could not read registry to check Word version
Could not find registry key Word.Application\CurVer
at OfficeConverter.Word..ctor()
at OfficeConverter.Converter.get_Word()
at OfficeConverter.Converter.Convert(String inputFile, String outputFile, Stream logStream) at ....
Could you guys help me on this? Thanks all!!!
**feel free to ask for more information you need to detect this issue
Update
Looks like this is the issue with the pdf converter pacakge I'm using, not the OpenXML
It seems your application is relying on the Windows registry in a way that is not supported. If you are running on a Linux App Service, that would be the first thing to swap out, though my guess is that you are already running on Windows.
Apps have read-only access to much (though not all) of the registry of the virtual machine they are running on. In practice, this means registry keys that allow read-only access to the local Users group are accessible by apps. One area of the registry that is currently not supported for either read or write access is the HKEY_CURRENT_USER hive.
Write-access to the registry is blocked, including access to any per-user registry keys.
https://learn.microsoft.com/en-us/azure/app-service/operating-system-functionality#registry-access
If you can't refactor your code to not rely on such dependencies, I would suggest you put your application inside a Windows docker container. If you can run that locally, it should run on App Service as well.
Is there any possibility to create a key in HKEY_LOCAL_MACHINE with out running the application in admin mode. If a key is not there then a new key should be created. If a key already exists it should be returned. I tried below code but it is not working. Any Ideas?
RegistryKey subRegKey = null;
string regVal = "";
try
{
subRegKey = Registry.LocalMachine.CreateSubKey(registryBit, RegistryKeyPermissionCheck.ReadSubTree);
regVal = subRegKey == null ? string.Empty : (string)subRegKey.GetValue(registryKey);
}
catch (Exception ex)
{
Console.WriteLine("Error :");
Console.WriteLine(" : " + ex.Message + "\n" + ex.StackTrace);
}
Hi Damien,
I have tried below as per your suggestions but could not succeed. Can you help?
As per your suggestion i have created 4 parent nodes by running a console application in admin mode in below ways,
subRegKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\DMK1\Default");
subRegKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\DMK2\Default",RegistryKeyPermissionCheck.Default);
subRegKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\DMK3\ReadSubTree",RegistryKeyPermissionCheck.ReadSubTree);
subRegKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\DMK4\ReadWriteSubTree",RegistryKeyPermissionCheck.ReadWriteSubTree);
and i tried to create sub keys on each of those parent nodes in below 4 ways from a console application (with out adminstrator),
subRegKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\DMK1\Default");
subRegKey =
Registry.LocalMachine.CreateSubKey("SOFTWARE\DMK1\Default",RegistryKeyPermissionCheck.Default);
subRegKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\DMK1\Default",RegistryKeyPermissionCheck.ReadSubTree);
subRegKey = Registry.LocalMachine.CreateSubKey("SOFTWARE\DMK1\Default",RegistryKeyPermissionCheck.ReadWriteSubTree);
But none of them created a subkey on parent key. If possible can you help me out what is the way to create parent and child nodes using C# code?
Yes, but.
Keys have permissions. It's certainly possible for a particular key somewhere in the tree descending from HKLM to have it's permissions set so that anyone can create values/subkeys within it.
For a specific application, this ought to be a (sub)key created specifically for this purpose, during software installation. Of course, the installation has to be performed by an administrator.
In an ad-hoc fashion, an administrator can create such a key and tell you about it.
But in general, the HKLM tree is meant for machine wide settings, and most of those are properly under the control of the machine's administrators. Most users should not be able to apply machine-wide setting changes, except for specifically scoped/anticipated changes for particular applications, which are covered by my above description.
Generally your software should not need to write into the HKLM hive. I cannot think of any reason to do so.
Maybe you are about to try to handle software setup within your App. You should leverage a setup program instead (WiX toolset for instance).
Maybe you would like to share some state information. Use %PROGRAMDATA% for this.
Secretly trying to alter machine wide configuration programmatically is an administrators nightmare and could be considered being malware behavior.
It was working after i changed "Changed User Account Control Settings" to never notify and restarted the machine to take the changes effect. After that i was able to create keys in custom software folder.
I am using below code for launch my program on startup:
RegistryKey rk = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
rk.SetValue(AppName, Application.ExecutablePath);
but when run my project this error occourrs:
System.UnauthorizedAccessException: 'Attempted to perform an unauthorized operation.'
There was this issue a long time ago.
first you need to set registry in HKCU\Software\Microsoft\Windows\CurrentVersion\Run make sure you have enough permissions!:
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
key.SetValue(AppName, Application.ExecutablePath);
}
Then follow the steps from this post:
Add it to the current user's Startup folder. This requires the least permissions for your app to run, and gives the user the most
control and feedback of what's going on. The down-side is that it's a
little more difficult determining whether to show the checkbox already
checked next time they view that screen in your program.
Add it to the HKey_Current_User\Software\Microsoft\Windows\CurrentVersion\Run
registry key. The only problem here is that it requires write access
to the registry, which isn't always available.
Create a Scheduled Task that triggers on User Login
Add it to the HKey_Local_Machine\Software\Microsoft\Windows\CurrentVersion\Run
registry key. The only problem here is that it requires write access
to the registry, which isn't always available.
Set it up as a windows service. Only do this if you really mean it, and you know for sure you want to run this program for all
users on the computer.
I am trying to write an application to be able to change a few registry values.Such as Dns Server,Defalut Gateway .I am using this code below for doing this
RegistryKey openSubKey = Registry.LocalMachine.OpenSubKey(path, true);
if (openSubKey != null)
{
//HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\Tcpip\Parameters\Interfaces\{F7DFBC05-B946-4C27-A58B-13BFB3FCC04E}
openSubKey.SetValue("IPAddress", "192.168.2.132");
openSubKey.SetValue("SubnetMask", "255.255.255.0");
openSubKey.SetValue("DefaultGateway", "192.168.2.2");
openSubKey.SetValue("NameServer", ""192.168.2.132,192.168.2.132"");
.Actually code works .I can see the new values in th registry as you can see
However when I check network connections I have realized that nothing changed
but NameServer.What am I doing wrong here.
My suggestion is instead of direct registry manipulation, use WMI. See this StackOverflow post or this Code Project article on using WMI to update the Network Configuration.
Mostly you will have to work with Win32_NetworkAdapterConfiguration WMI object.
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.