I am trying to write a C# code, which will block exe files from running. I found a question about the same topic: example question. In the question suggested method is using these registry lines as below:
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\notepad.exe]
"Debugger"="calc.exe"
However, this code doesn't look like any C# code I have ever seen. The answer talks about "adding a registry key" and "exported registry key". However, when I search those terminologies on the internet, I could not find any clear explanation about the topic for a beginner Windows developer like me.
For example this question add registry key question wrote a C# function with two inputs.
void exportRegistry(string strKey, string filepath)
I tried to use this function inside my main Winform constructor as below, but nothing happened - I could still open notepad.exe with no problem (which is the main aim of the code)
this.exportRegistry("\"Debugger\" = \"calc.exe\"", "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe]");
What am I doing wrong? I really thought I have enough coding skill for this problem, but I am stuck.
After I searched for some time, I found a way to achieve it. I can know stop programs running by changing the registery for windows. This code stops notepad.exe from running. It does it by adding several registery keys with the C# code. The logic behind it given in this link Explanation. It might not be the best way but it does stop programs running.
RegistryKey key = Registry.CurrentUser.OpenSubKey("Software", true);
key.CreateSubKey("Microsoft");
key = key.OpenSubKey("Microsoft", true);
key.CreateSubKey("Windows");
key = key.OpenSubKey("Windows", true);
key.CreateSubKey("CurrentVersion");
key = key.OpenSubKey("CurrentVersion", true);
key.CreateSubKey("Policies");
key = key.OpenSubKey("Policies", true);
RegistryKey explorerKey = key.CreateSubKey("explorer");
key = key.OpenSubKey("explorer", true);
explorerKey.SetValue("DisallowRun", 0x00000001, RegistryValueKind.DWord);
RegistryKey disallowRun = key.CreateSubKey("DisallowRun");
key = key.OpenSubKey("DisallowRun", true);
disallowRun.SetValue("1", "notepad.exe", RegistryValueKind.String);
Related
I'm trying to use this registry hack I found online:
;Disables F1 key - Help and Support - in Windows 10
;Ramesh Srinivasan, Winhelponline.com
[HKEY_CURRENT_USER\SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win32]
#=""
[HKEY_CURRENT_USER\SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win64]
#=""
When I run it as a .reg command via Windows Explorer and watch the registry with regedit, it works as intended. Removing it is another registry file that simply removes the \0 subkey (and win32 and 64 with it). I'm trying to emulate this function with C# in a Winform using .net CORE:
private void CheckF1()
{
// Registry data from ;Ramesh Srinivasan, Winhelponline.com
RegistryKey F1key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Classes\TypeLib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0");
// EGADS! It's active!
if (F1key == null)
{
fckF1RestoreBtn.Enabled = false;
fckF1KillBtn.Enabled = true;
fckF1Status.Text = "That creepy bugger is waiting and watching.";
}
else
{
fckF1RestoreBtn.Enabled = true;
fckF1KillBtn.Enabled = false;
fckF1Status.Text = "The F1-Help function had been put in it's place.";
}
}
private void fckF1KillBtn_Click(object sender, EventArgs e)
{
Registry.CurrentUser.CreateSubKey(#"SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win32");
Registry.CurrentUser.CreateSubKey(#"SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0\win64");
CheckF1();
}
private void fckF1RestoreBtn_Click(object sender, EventArgs e)
{
Registry.CurrentUser.DeleteSubKeyTree(#"SOFTWARE\Classes\Typelib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0");
CheckF1();
}
Weirdly the code "sees" a setting and responds like it should. Even to the point that whichever toggle position it was in on close it remembers when I load the file again. It's almost like it's playing along to screw with me. Regardless, when I watch the registry, none of my code has any actual effect though by all appearances it seems to work otherwise (it doesn't actually of course because the registry change isn't happening).
NOTE: I have already updated my manifest file for the project to include elevated permissions:
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Here's the breakpoint on the test statement to see if the subkeys are there that shows they are:
Meanwhile the registry location for the exact path shown in the debug doesn't have the 1.0\0 path at all:
I don't know how the code is reading phantom values. Someone closed my previous question pointing to another answer that didn't have any effect (Registry key deleted but still getting value from registry c#):
"Prefer 32 bit" was never checked for my project in the first place
Modifying my code as recommended had no effect
var key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)
.OpenSubKey(#"SOFTWARE\WOW6432Node\Classes\TypeLib\{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0");
Adding "Wow64Node" to the path makes no difference in execution.
EXPECTED BEHAVIOR
Checking to see if the HKEY_CURRENT_USER\SOFTWARE\Classes\Typelib{8cec5860-07a1-11d9-b15e-000d56bfe6ee}\1.0\0 path is present should return null if the \0 path is not present
Adding and removing the subkeys should show in the registry
So apparently HKEY_CURRENT_USERS is an alias. When the above code runs, it updates in HKEY_USERS under the specific logged in user. There's a question that talks about this behavior here: write registry to hkey_current_user instead of hkey_users
That said, the code appears to work, it's just that the registry doesn't update HKCU like when you run .reg commands. To verify it was working, I'd run the toggle that kills the keys then click them in Regedit and it would say they didn't exist. When I toggled back, I could click on them. So basically, it works (not sure if it required the "using" blocks as others suggested, but I see no reason to take them out).
Now my problem is that it points to the admin user and NOT the regular user because I'm running it and regedit as admin. It took forever to determine this based on running regedit as user in one case and admin in another. Bottom line, this won't work and I'll probably end up running .reg files in the command line instead.
I am trying to change certain value in the registry programmatically (C#) but I am constantly running into Unauthorized-Access-Exceptions.
The registry-keys that I am trying to modify have been created by a driver-installer for an USB-audio-Device. This device (a LogiLink USB Sound Box 7.1) sometimes “forgets” its settings and I am looking for a quick way to re-set the settings automatically.
Reading the values with the usual Microsoft.Win32.Registry-methods is no problem, but trying to overwrite certain values seems to be difficult.
However, doing the changes manually (using regedit) is no problem. I do have admin rights as a User and I am starting all my C# programs that ought to modify the values “as Administrator”, but to no avail.
Here are a few things I have tried:
-Giving my application Admin-rights in the app.manifest.
-Tring to open the Key with the Microsoft.Win32-methods with the writable = true. Here I get an System.UnauthorizedAccessException.
RegistryKey key =
RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine,
RegistryView.Registry64);
key = key.OpenSubKey(regPath,true);
-Exporting the key into a *.reg-file using reg. (always works)
String strCmdText = "/C REG EXPORT <KeyPath> <ExportPath> /reg:64";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
Then I can modify the resulting file and try to import it using various methods.
String strCmdText = "/C REG IMPORT <PathToReg> /reg:64";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
Or
String strCmdText = <PathToReg>;
System.Diagnostics.Process.Start("REGEDIT.exe", strCmdText);
I tried those methods in other places in the registry and they work flawlessly, however they fail if I want to apply them to the keys of the USB-audio-Device. The Processes always end with return-code 0.
Manually importing the exported and modified *.reg-file always works and the Device-Settings are changed as expected. Even using the CMD-Console manually yields the desired result. However, if I try to do the exact same thing in C#, no change is happening (even with admin-rights).
I would be very glad if someone had an idea about this. Thank you.
I am working on a project that will allow me to delete the registry key from a Windows 7 PC. Specifically I am trying to make a program that will allow me to delete a profile from the machine via the ProfileList key. My problem is no matter what I try I can't seem to read the key correctly which I want to do before I start randomly deleting stuff. My code is
RegistryKey OurKey = Registry.LocalMachine;
OurKey = OurKey.OpenSubKey(#"SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ProfileList", true);
foreach (string Keyname in OurKey.GetSubKeyNames())
{
MessageBox.Show(Keyname);
}
This code runs but doesn't return anything (No MessageBox). Any ideas why not?
EDIT:
I got the top level keys to load thanks to you all but it does only show the folder/key names (Ex: S-1-5-21-3794573037-2687555854-1483818651-11661) what I need is to read the keys under that folder to see what the ProfilePath is. Would there be a better way to go about that?
As pointed out by Lloyd, your path should use "Windows NT". In case of doubt, always use regedit to go inspect the registry manually.
Edit: To go with your edit, you can simply GetValue on the keys you find, the following code should do what you're looking for:
RegistryKey OurKey = Registry.LocalMachine;
OurKey = OurKey.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList", true);
foreach (string Keyname in OurKey.GetSubKeyNames())
{
RegistryKey key = OurKey.OpenSubKey(Keyname);
MessageBox.Show(key.GetValue("KEY_NAME").ToString()); // Replace KEY_NAME with what you're looking for
}
Windows NT
Please do not miss space
I'm trying to write to the registry using my C# app.
I'm using the answer given here: Writing values to the registry with C#
However for some reason the key isn't added to the registry.
I'm using the following code:
string Timestamp = DateTime.Now.ToString("dd-MM-yyyy");
string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\"+Application.ProductName+"\\"+Application.ProductVersion;
string valueName = "Trial Period";
Microsoft.Win32.Registry.SetValue(key, valueName, Timestamp, Microsoft.Win32.RegistryValueKind.String);
The Application.name and Application.version 'folders' don't exists yet.
Do I have to create them first?
Also, I'm testing it on a 64b Win version so I think if I want to check the registry for the key added I have to specifically check the 32bit registry in: C:\Windows\SysWOW64\regedit.exe don't I?
First of all if you want to edit key under LocalMachine you must run your application under admin rights (better use CurrentUser it's safer or create the key in installer). You have to open key in edit mode too (OpenSubKey method) to add new subkeys. I've checked the code and it works. Here is the code.
RegistryKey key = Registry.LocalMachine.OpenSubKey("Software",true);
key.CreateSubKey("AppName");
key = key.OpenSubKey("AppName", true);
key.CreateSubKey("AppVersion");
key = key.OpenSubKey("AppVersion", true);
key.SetValue("yourkey", "yourvalue");
You can use the following code to create and open the required registry keys.
RegistryKey SoftwareKey = Registry.LocalMachine.OpenSubKey("Software",true);
RegistryKey AppNameKey = SoftwareKey.CreateSubKey("AppName");
RegistryKey AppVersionKey = AppNameKey.CreateSubKey("AppVersion");
AppVersionKey.SetValue("yourkey", "yourvalue");
You can basically use CreateSubKey for all your application settings, as it will open the key for write access, if it already exists, and create it otherwise. There is no need to create first, and then open. OpenSubKey comes in handy when you are absolutely certain the key already exists, like in this case, with "HKEY_LOCAL_MACHINE\SOFTWARE\"
Also check if your registry calls are getting virtualised. See here for more information.
It can happen if your application is not UAC aware and occurs for compatibility reasons.
Real path
HKEY_LOCAL_MACHINE\Software\FooKey
Virtual path
HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\FooKey
Try to open HKLM\Software first. Then create key for your program, and then create key for version. Howewer, your key could be placed at HKLM\software\WOW6432Node. Check this.
The problem is you don't have enough privileges. Here is a way that works for my:
RegistryKey myKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
myKey = myKey.OpenSubKey(subkey, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl);
if (myKey != null)
{
myKey.SetValue("DefaultPrinterId", ldiPrinters[e.RowIndex].id, RegistryValueKind.String);
myKey.Close();
}
With RegistryKey.OpenBaseKey you open the correct registry, because when you don't have permissions the registry that you write, it does in another location.
By default, your changes will be written to HKLM\SOFTWARE\WOW6432Node\... because of registry redirection. This can be quite confusing.
In order to write to HKLM\SOFTWARE\..., you need to use RegistryKey.OpenBaseKey to open the 64-bit registry:
var path = #"SOFTWARE\...";
var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var key = baseKey.CreateSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree);
key.SetValue(name, value, RegistryValueKind.String);
Also, you need to have permission to write to the specified registry key.
You can get permission either by assigning permissions to specific users or service accounts or by running your app in elevated mode.
I have already looked at existing topics, so please try to refrain from dropping links here.
I want to get the value of a registry key - plain and simple. Here is what I have so far.
Registry:
1) Made a key under
Current_User\Software\Custom_Subkey\Custom_Value\Custom_key\string_value
I am trying to find the string_value
string reg_subKey = "Software\\Custom_Subkey\\Custom_Value";
RegistryKey root = Registry.CurrentUser.CreateSubKey(reg_subKey);
foreach (string keyname in root.GetValueNames())
{
textBox4.AppendText(keyname.ToString() + Environment.NewLine);
// Appends the following data to textBox4 once the foreach is completed:
// Header1
// Header2
// Header3
// Header4
// Header5
// Now I want to get the VALUES of each header:
using (RegistryKey key = root.OpenSubKey(keyname))
{
**// THIS LINE GETS HIGHLIGHTED WITH THE FOLLOWING ERROR:
"Object reference not set to an instance of an object.**"
MessageBox.Show(key.ValueCount.ToString());
}
}
Hopefully this is a simple fix. I look forward to hearing your responses.
Thanks,
Evan
I believe you want root.GetSubKeyNames() in the loop not GetValueNames()
While values is working to get the values I would suggest the following loop:
foreach(string keyname in root.GetSubKeyNames())
{
// use key to get value and set textbox4
using (RegistryKey key = root.OpenSubKey(keyname))
{
MessageBox.Show(key.ValueCount.ToString());
}
}
The OpenSubKey method does not throw an exception if the specified subkey is not found. Instead, it simply returns null. It's your responsibility as a programmer to ensure that the appropriate key was found and opened by checking the return value of the method call.
Thus, my suspicion is that the registry key that you've specified is invalid. Open up Registry Editor (regedt32.exe), and verify that you can find the key in the registry exactly as written.
If you find that the registry key is indeed located exactly where you thought it was, then the problem may be related to the WOW64 subsystem, which allows 64-bit versions of Windows to run 64-bit apps. If the value was written to the registry by a 32-bit program, you won't be able to read it with the above code from a 64-bit program (or vice versa). The simplest way to check this is to change the compilation settings for your project. For example, if you're currently compiling for x86, then change to compiling for x64, or vice versa. Registry redirection may also be getting in your way; this will check for that as well.
I wanted the very same thing and your code helped me, but as you said, it didn't work properly. So, I made some modifications and I think it works fine now! Try this:
//Just make the reference until "custom_subkey", not to the next one ("custom value")
string reg_subKey = "Software\\Custom_Subkey";
RegistryKey root = Registry.CurrentUser.CreateSubKey(reg_subKey);
//Use GetSubKeyNames, instead of GetValueNames, because now you are in a higher level
foreach (string keyname in root.GetSubKeyNames())
{
using (RegistryKey key = root.OpenSubKey(keyname))
{
foreach (string valueName in key.GetValueNames())
{
MessageBox.Show(valueName);
MessageBox.Show(key.GetValue(valueName).ToString() );
}
}
}