Changing registry values in C
I suggest the following changes:
char* number = 0x00000001
is not how to declare aDWORD
. You wantDWORD value = 0x00000001
. And then pass(BYTE*)&value
toRegSetValueEx
.- You should check the return value of
RegSetValueEx
againstERROR_SUCCESS
. - You need to add a manifest to your executable. That will ensure that you do not run virtualized. And you will also need to add the
requireAdministrator
option to ensure that the process is elevated. - You are probably also being tricked by the registry redirector. Include the
KEY_WOW64_64KEY
flag when callingRegOpenKeyEx
to access the 64 bit registry view.
The following program should do the trick:
#include <stdio.h>
#include <windows.h>
int main(void)
{
DWORD number = 0x00000001;
HKEY key;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\LogonUI\\Background", 0, KEY_SET_VALUE | KEY_WOW64_64KEY, &key) == ERROR_SUCCESS)
{
printf("Key location open successful \n");
if (RegSetValueExW(key, L"OEMBackground", 0, REG_DWORD, (LPBYTE)&number, sizeof(DWORD)) == ERROR_SUCCESS)
{
printf("Key changed in registry \n");
}
else{
printf("Key not changed in registry \n");
printf("Error %u ", (unsigned int)GetLastError());
}
RegCloseKey(key);
}
else
{
printf("Unsuccessful in opening key \n");
printf("Cannot find key value in registry \n");
printf("Error: %u ", (unsigned int)GetLastError());
}
return 0;
}
Make sure that you link a proper application manifest to the program with the requireAdministrator
to ensure elevation.
How to add/modify registry keys with C#?
First, does the call "fail" or does it succeed but you do not see the key afterwards? If any of the calls in the code you've shown fail, they should be throwing an exception.
Second, you've got the syntax for the SetValue call wrong. The second parameter is supposed to be the object to set the value to, not a string representing the value and its type which is what you look to be doing. In other words, change it to either this:
key.SetValue("Startupdelayinmsec", 0);
or if you want to specify the exact type of the new value, then this:
key.SetValue("Startupdelayinmsec", 0, RegistryValueKind.DWord);
Also, as others have stated in comments, you will need rights to change the registry. Logging in as an admin may not be enough. You may need to run your app as an admin also.
Using C++ to edit the registry
Open the registry : RegOpenKeyEx
Query the value : RegQueryValueEx
/* do something with value*/
Set the value back : RegSetValueEx
close the registry : RegCloseKey
Not able to edit the registry in c#?
You can't update Registry.LocalMachine
entries unless your program is running as an administrator. You need to add a manifest to your program and make it require administrator privileges to launch.
It is also is possible that you have a 32 bit program trying to access a 64 bit regestery key. Replace Registry.LocalMachine
with Registry.LocalMachine(RegistryHive.LocalMachine, RegistryView.Registry64)
to force it to use the 64 bit registry even if your app is running as 32 bit.
You also could compile your program as 64 bit instead of 32 bit or AnyCpu to force it to be 64 bit.
Editing Registry using C Giving warnings and not editing registry keys
With RegSetValueExA api you cant just put 1 because its need var pointer with BYTE type just declare your var with dword type then convert it to BYTE here example:
HKEY key;
DWORD Num = 1;
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\Setup", 0, KEY_ALL_ACCESS, &key);
RegSetValueExA(key, "SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&Num, sizeof(1));
RegCloseKey(key);
Changing a registry value with C++? (system command failed)
Some extra work is needed to write string literals that contain special characters. For example, in your code, the "
after ADD
is the end of the string.
You need to put a backspace before each special character (includes quotes and backspaces) to make sure they are put into the string instead of being processed by the compiler. This is called escaping.
The result will look like this:
system("REG ADD \"HKCU\\Control Panel\\Desktop\" /V Wallpaper /T REG_SZ /F /D \"C:\\background.bmp\"");
Using the Registry API is a better option for your task, of course, but you also needed to know how to write string literals properly.
How to add a String Value/ Name Data pair in Windows Registry Editor key using C++ and Windows Registry API's
KEY_ALL_ACCESS
requires admin rights. All you really need in this situation is KEY_SET_VALUE
instead. Don't ask for more permissions than you actually need. But, you do still need admin rights to write to HKEY_LOCAL_MACHINE
to begin with. So make sure you are running your code as an elevated user.
In any case, your string literals have a few \
that don't belong. But more importantly, your use of RegSetValueA()
is completely wrong for this task. It is a deprecated API that can only write to the (Default)
string and nothing else (and, you are not even calling it correctly anyway, you would need strlen(Value)+1
instead of sizeof(Value)
- not that it matters because that parameter is ignored anyway).
In order to create your Debugger
string value, you need to use RegSetValueEx()
instead, eg:
#include <Windows.h>
#include <iostream>
int main()
{
HKEY hkey;
LPCTSTR Directory = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\chrome.exe");
LSTATUS ReturnValue = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Directory, 0, KEY_SET_VALUE, &hkey);
if (ERROR_SUCCESS != ReturnValue)
{
printf("RegOpenKeyEx failed: %u\n", GetLastError());
return -1;
}
LPCTSTR Value = TEXT("ntsd -c q");
ReturnValue = RegSetValueEx(hkey, TEXT("Debugger"), 0, REG_SZ, (const BYTE*)Value, (lstrlen(Value)+1) * sizeof(TCHAR));
if (ERROR_SUCCESS != ReturnValue)
{
printf("RegSetValueExA failed: %u\n", GetLastError());
RegCloseKey(hkey);
return -1;
}
ReturnValue = RegCloseKey(hkey);
if (ERROR_SUCCESS != ReturnValue)
{
printf("RegCloseKey failed: %u\n", GetLastError());
return -1;
}
return 0;
}
How to edit value in C++Builder Registry?
Run Windows' built-in Registry Editor, regedit.exe
(Start > Run > type regedit
> press Enter, answer Yes if prompted).
In the left-hand pane, navigate down to the HKEY_CURRENT_USER\Software\Embarcadero\BDS\9.0\Repository\New Console Application
key.
In the right-hand pane, if ConsoleApp
does not already exist, right-click in a blank area (or use the "Edit" menu in the upper toolbar), choose "New > String value", and enter ConsoleApp
.
Now double-click on ConsoleApp
and type True
or False
as needed.
The change will take effect the next time the Console Application wizard is opened.
Related Topics
Rvalue to Lvalue Conversion Visual Studio
Why Sizeof(Int) Is Not Greater Than -1
Remove an Array Element and Shift the Remaining Ones
Insert VS Emplace VS Operator[] in C++ Map
How to See the Assembly Code for a C++ Program
Can the Use of C++11's 'Auto' Improve Performance
Std::Auto_Ptr to Std::Unique_Ptr
What Would Be C++ Limitations Compared C Language
How Boost::Function and Boost::Bind Work
Pimpl Idiom VS Pure Virtual Class Interface
Passing Shared Pointers as Arguments
In C++, Is It Still Bad Practice to Return a Vector from a Function
Super High Performance C/C++ Hash Map (Table, Dictionary)
"If Constexpr" in C++17 Does Not Work in a Non-Templated Function
Are C++ Templates Just MACros in Disguise
Is a Constexpr Array Necessarily Odr-Used When Subscripted
What Is the Best Practice for Combating the Console Closing Issue