In my application, when I first set the key-value using RegSetValueEx() it works, but when I try to change the value using the same function it doesn't work, the value remains same. What am I doing wrong ?
Here is the code :
SetSZValue( "MyAppData", "versionInfo", "1.0.0" );
HKEY CreateKey( string regkey )
{
HKEY hKey ;
DWORD disValue ;
char msg[512] ;
string _key = "HKEY_LOCAL_MACHINE\\" ;
_key += regkey ;
LONG retValue = RegCreateKeyEx( HKEY_LOCAL_MACHINE, regkey.c_str(), 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &disValue ) ;
if (retValue != ERROR_SUCCESS)
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, &msg[0], 512, 0 ) ;
MessageBox( 0, &msg[0], "CreateKey", MB_OK | MB_ICONEXCLAMATION );
}
return hKey ;
}
void SetSZValue( string regkey, string keyName, string keyValue )
{
HKEY hKey;
DWORD disValue;
char msg[512];
hKey = CreateKey(regkey);
if (hKey)
{
LONG retValue = RegSetValueEx( hKey, keyName.c_str(), 0, REG_SZ, ( const BYTE* )( keyValue.c_str() ), keyValue.size()+1 );
if ( retValue != ERROR_SUCCESS )
{
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, &msg[0], 512, 0 );
MessageBox( 0, &msg[0], "SetSZValue", MB_OK | MB_ICONEXCLAMATION );
}
RegCloseKey ( hKey );
}
}
RegSetValueEx accepts the name of the value inside the key to change; not the name of the key. Supply the value name instead; the key name comes from the HKEY itself.
Is your app a 32-bit process running on a 64-bit Windows version? If so, does your app have a UAC manifest with a "requestedExecutionLevel" value in it? If not, your key may be getting virtualized to another section of the Registry and you are simply not looking in the right place. Registry Virtualization is a feature of WOW64 so legacy 32-bit and 64-bit processes do not step over each other in the Registry. You should install SysInternals Process Monitor, it will show you which keys and values your app is actually accessing.
Related
i'm trying to read the graphics card used by the system from the registry. Therefor i'm accessing the registry with the szRegKey/szSubKEy listed below.
The RegQueryValueEx exits with Error 0x02 (ERROR_FILE_NOT_FOUND).
If i'm trying to access the key via the cmd with reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winsat" /v PrimaryAdapterString it succeeds succesfully. Can you help me with my problem?
HKEY hKey;
WCHAR szRegKey[]= L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winsat";
WCHAR szSubKey[] = L"PrimaryAdapterString";
WCHAR *buf;
DWORD dwBufSize = 0;
DWORD dwType = REG_SZ;
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) {
return false;
}
if(RegQueryValueExW(hKey, szSubKey, 0, &dwType, NULL, &dwBufSize) != ERROR_SUCCESS) {
return false;
}
Using this code snippet:
TCHAR buf[255] = {0};
DWORD dwBufSize = sizeof(buf);
HKEY hKey = 0;
DWORD dwType = REG_DWORD;
if ( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("Software\\Developer\\KGReader"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
if( RegQueryValueEx( HKEY_CURRENT_USER, TEXT("Software\\Developer\\KGReader\\ComPort"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )
{
nrPort = _wtoi(buf);
}
if( RegQueryValueEx( HKEY_CURRENT_USER, TEXT("Software\\Developer\\KGReader\\KGID"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )
{
nrCentrala = _wtoi(buf);
}
}
No value is passed to hKey using RegOpenKeyEx method.
Although RegOpenKeyEx returns an ERROR_SUCCES, RegQueryValueEx returns 2 (ERROR_FILE_NOT_FOUND). KGID and ComPort do exist,i added them myself, i double checked the paths.
Pass the hKey obtained from the RegOpenKeyEx() call to the RegQueryValueEx() functions instead of HKEY_CURRENT_USER. The second argument to RegQueryValueEx() is the name of the value, not a path.
For example:
if( RegQueryValueEx(hKey,
TEXT("ComPort"),
0,
&dwType,
(LPBYTE)buf,
&dwBufSize ) == ERROR_SUCCESS )
Remember to reset buf and dwBufSize before the second call to RegQueryValueEx:
memset(buf, 0, sizeof(buf));
dwBufSize = sizeof(buf);
For error reporting purposes you should save the return value of the RegOpenKeyEx() and RegQueryValueEx() functions so the failure reason can be made known.
The posted code may be incomplete but ensure RegCloseKey(hKey) is called if the call to RegOpenKeyEx() was successful.
The first argument to RegQueryValueEx should be the HKEY opened by RegOpenKeyEx. In addition, the second argument should just be a value name, not the full path:
if( RegQueryValueEx( hKey, TEXT("ComPort"), 0, &dwType,
(LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )
System: Windows 7 32bit
Language: C++
I have tried to access register HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0, key Driver (type REG_SZ) -- no problem.
The same for reading from HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM, all keys (types REG_SZ) got slashes, for example \Device\Serial0.
While reading such keys it always returns 2 (no such file) with following example code:
HKEY hKey = 0;
DWORD dwType = REG_SZ;
char buf[255] = {0};
DWORD dwBufSize = sizeof(buf);
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
auto ret = RegQueryValueEx( hKey, TEXT("\Device\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize );
// ret always == 2 for key with slashes
--- CUT ---
What is the proper way to read key values with slashes in name?
Above has been properly answered by Cody Gray.
Below another issue.
Im getting the same problem when Im using variable instead of a text string.
Iv considered both approaches with single and double slashes:
HKEY hKey = 0;
DWORD keyType = REG_SZ;
TCHAR buf[255] = {0};
DWORD bufSize = sizeof(buf);
QSettings winReg("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM", QSettings::NativeFormat);
auto comsKey = winReg.allKeys();
FOREACH( auto com, comsKey )
{
// FOREACH - boost macro
// comsKey = QList<QString> (list of key names) [from Qt framework]
// com = QString (single key name) [from Qt framework]
if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
wchar_t* keyw = new wchar_t();
//com.replace("/", "\\\\"); <- checked both variants commented and not commented; com == /Device/Serial0 so im converting to \\Device\\Serial0
int size = com.size();
mbstowcs( keyw, com.toStdString().data(), size );
//auto ret = RegQueryValueEx( hKey, TEXT("\\Device\\Serial0"), 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this works!
auto ret = RegQueryValueExW( hKey, (LPCWSTR)&keyw, 0, &keyType, (LPBYTE)buf, &bufSize ); // <- this one not works!
I have tried all variants with "\Device..", "/Device", "\Device", etc.
You have to escape the slashes, just like you did in the first line...
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )
{
auto ret = RegQueryValueEx( hKey, TEXT("\\Device\\Serial0"), 0, &dwType, (LPBYTE)buf, &dwBufSize );
// ret always == 2 for key with slashes
If you don't, the RegQueryValueEx function can't find the specified key, and it returns ERROR_FILE_NOT_FOUND (== 2).
But there's another problem. You should be declaring the buffer array as type wchar_t (or TCHAR), rather than char:
TCHAR buf[255] = {0};
Otherwise, the RegQueryValueEx function is going to attempt to fill the array with a Unicode string read from the specified registry key, and you're going to get something unreadable.
I am Creating the Registry Key using following code:
LPCTSTR lpNDS= TEXT("SOFTWARE\\myKEY");
if(OK==ERROR_SUCCESS)
{
MessageBox ( NULL, "Success",
_T("SimpleShlExt"),
MB_ICONINFORMATION );
}
else
{
MessageBox ( NULL, "Failed" ,
_T("SimpleShlExt"),
MB_ICONINFORMATION );
}
LONG openRes = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
lpNDS,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hRegKey,
NULL);
if (openRes!=ERROR_SUCCESS)
MessageBox ( NULL, "Registry Createion Failed",
_T("SimpleShlExt"),
MB_ICONINFORMATION );
Now I am writing up to the Key using:
CSimpleShlExt::WriteToRegistry(LPSTR lpRegKeyVal)
{
LONG setRes = RegSetValueEx (hRegKey, "NDS", 0, REG_SZ, (LPBYTE)lpRegKeyVal, strlen(lpRegKeyVal)+1);
CloseRegistryKey();
}
Now I am trying read the registry key value that I have created using WriteToRegistry function. I have tried with
RegOpenKeyEx(hRegKey,lpNDS,0,KEY_QUERY_VALUE,&hRegKey);
But this is failing.
Which function shall I use to read the value contained inside the key?
You can try something like :
TCHAR szValue[TEMP_STR_SIZE] = {0};
DWORD dwStorageSize = TEMP_STR_SIZE;
LPBYTE lpStorage = reinterpret_cast<LPBYTE>(szValue);
// In case of registry value retrieval failure
if (ERROR_SUCCESS != RegQueryValueEx(hRegKey, _T("NDS"), 0, 0, lpStorage, &dwStorageSize))
{
// Prompt error
}
Edit:
Just noticed there are no subkey, changed my sample code
Which function shall I use to read the value contained inside the key?
Try RegQueryValue and/or RegEnumValue. Read the documentation to see which one suits your needs the best.
I want to edit key "HKEY_LOCAL_MACHINE\Software\company name\game name\settings\value" to "1" (DWORD)
This is my code:
HKEY hkey;
DWORD dwDisposition;
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\company name\\game name\\settings"), 0, NULL, 0, 0, NULL, &hkey, &dwDisposition) == ERROR_SUCCESS){
DWORD dwType, dwSize;
dwType = REG_DWORD;
dwSize = sizeof(DWORD);
DWORD rofl = 1;
RegSetValueEx(hkey, TEXT("value"), 0, dwType, (PBYTE)&rofl, dwSize); // does not create anything
RegCloseKey(hkey);
}
But it doesnt do anything. RegCreateKeyEx() is the only function that actually does something: creates the "folders" in the registry only. So once again how im failing? How i can create "files" in the registry?
Always check the return value of API functions. You'll see that RegSetValueEx() returns 5, access denied. You didn't ask for write permission. Fix:
if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,
TEXT("Software\\company name\\game name\\settings"),
0, NULL, 0,
KEY_WRITE, NULL,
&hkey, &dwDisposition) == ERROR_SUCCESS) {
// etc..
}
You probably need to pass in KEY_WRITE as the value of the samDesired arugment to RegCreateKeyEx() function (sixth argument).
This is a copy and edit from an actual code, may contain errors.
LONG
SetRegValue
(
const wchar_t* path
,const wchar_t *name
,const wchar_t *value
)
{
LONG status;
HKEY hKey;
status = RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_ALL_ACCESS, &hKey);
if ( (status == ERROR_SUCCESS) && (hKey != NULL))
{
status = RegSetValueEx( hKey, name, 0, REG_SZ, (BYTE*)value, ((DWORD)wcslen(value) + 1)*sizeof(wchar_t));
RegCloseKey(hKey);
}
return status;
}