The sample code can be found here:
http://msdn.microsoft.com/en-us/library/cc197002(v=vs.85).aspx
The code is about a third of the way down on the page, immediately underneath "Community Content" "IERegCreateKeyEx now working in c#, Please can you help with RegCloseKey"
Thanks for any help. I've tried for several days to use this. It compiles perfectly but I can't manage to call the public SetRegValue and CreatRegKey functions exposed in the public static class ProtectedModeHelper.
Any IE key value can be used in the sample; feel free to use your own in an example, e.g., HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Settings.
Since you are programming in C#, you could use the RegistryKey class to perform such tasks. Below is a sample code from MSDN showing how to create keys and set their values:
static void Main()
{
// Create a subkey named Test9999 under HKEY_CURRENT_USER.
RegistryKey test9999 =
Registry.CurrentUser.CreateSubKey("Test9999");
// Create two subkeys under HKEY_CURRENT_USER\Test9999. The
// keys are disposed when execution exits the using statement.
using(RegistryKey
testName = test9999.CreateSubKey("TestName"),
testSettings = test9999.CreateSubKey("TestSettings"))
{
// Create data for the TestSettings subkey.
testSettings.SetValue("Language", "French");
testSettings.SetValue("Level", "Intermediate");
testSettings.SetValue("ID", 123);
}
}
To modify an existing key you have to open it using the RegistryKey.OpenSubKey Method specifying that you want write access to be applied to the key, then you can call SetValue like showed above.
Related
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);
I ran into a bizarre issue when I upgraded some machines to Windows 10 where incorrect permissions on RuntimeBroker caused problems. I found a solution online that recommended changing permissions (first in the registry, then in DCOM configuration), and I'm trying to write a small .NET application to automate the process.
Presently the owner of the relevant registry keys is NT SERVICE\TrustedInstaller and I'm trying to change it to COMPUTER\Administrators. I have a simple WPF application with the requestedExecutionLevel set to "requireAdministrator," but I'm still running into problems. Here's a snippet of code to illustrate the problem:
using System.Security.AccessControl;
using System.Security.Principal;
using Microsoft.Win32;
namespace PermissionFixer
{
public class Fixer
{
public void Fix()
{
var subKey = Registry.ClassesRoot.OpenSubKey(#"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", true);
if (subKey != null)
{
var admins = new NTAccount("Administrators");
var ac = subKey.GetAccessControl();
ac.SetOwner(admins);
ac.AddAccessRule(new RegistryAccessRule(admins, RegistryRights.FullControl, AccessControlType.Allow));
subKey.SetAccessControl(ac);
}
}
}
}
The trouble is that it doesn't even get past the call to OpenSubKey() before hitting a SecurityException that says "Requested registry access is not allowed." I think that's because Administrators doesn't yet have the access (remember it belongs to TrustedInstaller), but it becomes a bit of a chicken and egg problem. The strange thing is that when I use regedit by hand I am allowed to change the owner to Administrators, and I'm pretty sure my instance of regedit is running as Administrators.
How can I get this working in .NET?
I figured it out, and fortunately it is possible to achieve with the .NET classes. Here is how you have to call OpenSubKey:
var subKey = Registry.ClassesRoot.OpenSubKey(#"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership);
Then you have to nix the call to AddAccessRule()... you can't modify that until you have ownership; and you have to do those two operations in serial. So take ownership first, then re-open the key with different access rights to add the access rule.
EDIT: I discovered today that you must first manipulate the token with which your application is running, by hooking into P/Invoke calls. I found a class called TokenManipulator referenced in another Stack Overflow question. Include that class in your project, and then grant Backup, Restore, and TakeOwnership privileges to your token before calling OpenSubKey. So your method will end up looking something like this:
try
{
TokenManipulator.AddPrivilege("SeRestorePrivilege");
TokenManipulator.AddPrivilege("SeBackupPrivilege");
TokenManipulator.AddPrivilege("SeTakeOwnershipPrivilege");
var subKey = Registry.ClassesRoot.OpenSubKey(#"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership);
// code to change owner...
}
finally
{
TokenManipulator.RemovePrivilege("SeRestorePrivilege");
TokenManipulator.RemovePrivilege("SeBackupPrivilege");
TokenManipulator.RemovePrivilege("SeTakeOwnershipPrivilege");
}
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() );
}
}
}
How do I change the credentials used by a scheduled task using C#.NET?
Instead of using code, you can do it using 'SCHTASKS' command, run it using System.Diagnostic.Process.Start method with the parameters required. It's easy and not much effort required.
Someone has written a task scheduler class library on codeproject.com, it might be what your after...
:)
You must call RegisterTaskDefintion for the task's definition with the new username and password to change just the password.
Code fragment
// Add COM-Reference to "TaskScheduler 1.1 Type Library" to the project
using TaskScheduler;
// code in function X
TaskSchedulerClass TaskClass = new TaskSchedulerClass();
TaskClass.Connect();
// access one task (or search for it or enumerate over all tasks)
IRegisteredTask lTask = null;
lTask = TaskClass.GetFolder("\\").GetTasks(0)[0];
// provide domain\\username and password (ask user for it, use encryption)
string lUsername = "TestDomain\\TestUsername"; // TestDomain can be the hostname for a local user
string lPassword = "xyzPassword";
RegisterTaskDefinition(lTask.Path, lTask.Definition, (int)_TASK_CREATION.TASK_UPDATE, lUsername, lPassword, lTask.Definition.Principal.LogonType, Type.Missing);
Original source for answer:
http://taskscheduler.codeplex.com/discussions/215362
Check out this library for working with TaskSheduler. It's written in VB, but I referenced it easily and called it from C#.
Some programs read the company name that you entered when Windows was installed and display it in the program. How is this done? Are they simply reading the name from the registry?
If you want the registered company name as entered in the registry, you can get it from:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\RegisteredOrganization
Using the Registry class you can do something along these lines:
string org = (string)Microsoft.Win32.Registry.GetValue(#"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion", "RegisteredOrganization", "");
You can read this Using WMI, it looks to me like you're after the Win32_OperatingSystem class and the Organization element of that class holds the company name.
The code below is a console app that shows the registered user and organization. To get it to run you'll need to add a reference to System.Management.dll to the project. There should only be one management object so the foreach is probably redundant, not quite sure what best practice for that would be:
using System;
using System.Management;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ManagementClass c = new ManagementClass("Win32_OperatingSystem");
foreach (ManagementObject o in c.GetInstances())
{
Console.WriteLine("Registered User: {0}, Organization: {1}", o["RegisteredUser"], o["Organization"]);
}
Console.WriteLine("Finis!");
Console.ReadKey();
}
}
}
Windows stores the registered company name in the registry at :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\RegisteredOrganization
Import the following :
using Microsoft.Win32;
Read the value of the registry key required, like so:
RegistryKey hklm = Registry.LocalMachine;
hklm = hklm.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
Object obp = hklm.GetValue("RegisteredOrganization");`
Console.WriteLine("RegisteredOrganization :{0}",obp);`
Or a one liner, as suggested by Xiaofu.
However, the correct way is to use a double backslash. This is because the backslash is the C# escape character - that is, you can insert a newline character using \n, or tab using \t therefore to let C# know that we want a plain backslash and not some escaped character, we have to use two backslashes (\) or use # in front of the string like (#"\somestring") :
string org = (string)Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\\Software\\Microsoft\\Windows NT\\CurrentVersion", "RegisteredOrganization", "");
Note: The RegisteredOrganization key is not guaranteed to contain a value, as it may not have been filled in during the OS installation. So always use a try/catch block or check the returned value.
Check the API SystemParametersInfo and a constant named SPI_GETOEMINFO
int details = SystemParametersInfo(SPI_GETOEMINFO, OEMInfo.Capacity, OEMInfo, 0);
if (details != 0)
{
MessageBox.Show(OEMInfo.ToString());
}
That will return the companyname for the OEM. I dont think you have to enter company name when installing windows, only computer name ( I can be wrong here)
You can see all the constants and examples here:
http://pinvoke.net/default.aspx/Enums.SystemMetric
I couldn't find a method or property in .NET that gets you the information, but I found a technote that tells what registry key contains the info:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\RegisteredOrganization
http://support.microsoft.com/kb/310441
I don't like to have text-y registry calls in my business code, and I'm not a fan of utility classes, so I wrote an extension method that gets the company name from the registry.
using Microsoft.Win32;
namespace Extensions
{
public static class MyExtensions
{
public static string CompanyName(this RegistryKey key)
{
// this string goes in my resources file usually
return (string)key.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion").GetValue("RegisteredOrganization");
}
}
}
Then I can easily get that value:
RegistryKey key = Registry.LocalMachine;
return key.CompanyName();
It's nothing fancy, just a prettier way of dealing with oft-retrieved registry values.