I have a problem with the registry in Windows x64. I need to get a value added through file.reg:
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\My Soft]
"Str1" = "Assa"
"Str2" = "142Z5214GGAAVGA"
In the code, I do:
RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\My Soft", 0,NULL,0, KEY_READ | KEY_WOW64_64KEY,NULL,&hKey,&dwDis))
/*
Get the value by RegQueryValueEx...
*/
In a 32-bit Windows is good. In a 64-bit value is empty.
PS:
Sorry for my English by Google Translate ^_^
You say you need to get a value, but you're calling RegCreateKeyEx. Do you actually need to create it? If so, it's probably created in HKLM/Software/Wow6432Node.
Have you tried HKEY_LOCAL_MACHINE\Software\WOW6432Node ?
The default 64-bit version of Registry Editor (Regedit.exe) that is included with 64-bit versions of Windows displays both 64-bit keys and 32-bit keys. The WOW64 registry redirector presents 32-bit programs with different keys for 32-bit program registry entries. In the 64-bit version of Registry Editor, 32-bit keys are displayed under the following registry key.
Source
Related
I have a 32 bit program which is running in two lanes in the same store. The program tries top open a registry key for query. The operating system is Windows 8.1 64 bit.
On one lane it succeeds, and on the other it fails and regopenkeyex returns 2. GetLastError returns 0.
The key it tries to open is under WOW6432Node.
The program is running under the same Windows user on both machines, the key exists on both. the UAC is set to "Never notify" (lowest), windows version is the same. Everything is supposed to be the same...
I am deliberately not specifying KEY_WOW64_64KEY because the code is supposed to work without it. But even when I do use it I get the same result.
What could be causing this?
The code:
rc = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
szKey,
0,
KEY_QUERY_VALUE,
&m_hKey);
Thank you.
You actually need to read about the functions you are using on MSDN. The registry functions return the error code directly, they do not use GetLastError!
2 is ERROR_FILE_NOT_FOUND so whatever you are hiding in szKey is not a valid subkey path.
WOW6432Node is a reserved key name that you really should not be using, use KEY_WOW64_32KEY if you need to access the 32-bit registry view in a 64-bit application. A 32-bit application reads keys under the WOW6432Node key by default.
Use Process Monitor to make sure you are accessing the correct key.
I am trying to display a new Word document inside a Widget, using OLE. This works fine as long as I compile my application under x86 architecture. Now I tried porting my application to x64 and it stopped working. The call to OleCreate() fails with REGDB_E_CLASSNOTREG.
CLSID clsID;
IUnknown* pIUnknown;
HRESULT res = CLSIDFromProgID(L"Word.Document.8", &clsID);
if (SUCCEEDED(res)) {
res = OleCreate(clsID, IID_IUnknown, OLERENDER_DRAW, NULL, NULL, storage, reinterpret_cast<void**>(&pIUnknown));
}
After some research I came across some solutions, but none of them were applicable.
I can't set my compiler to x86 when I'm trying to port my application to x64 so following Post hasn't solved my problem.
I tried calling regsvr32.exe withC:\Windows\System32\ole32.dll but it didn't change the result.
I tried installing the hotpatch, which was shipped by microsoft to fix the same problem with OleCreateFromFile(). Sadly it doesn't fix the problem for OleCreate() - hotfix
The only solution, which worked so far was to copy the content of HKLM\SOFTWARE\SysWow64\Classes\CLSID\<CLSID of Word Document> into HKLM\SOFTWARE\Classes\CLSID\<CLSID of Word Document> but this is more of a hack than a fix, because I would have to modify the registry of every machine on which I want to run my application. Since this task requires administrator privileges, I can't do this from inside my application.
I need a solution which works and doesn't force me to manually alter registry entries.
I'm running my application on a Windows 7 Professional SP1 64-Bit machine with a 32-Bit Office 2010.
After some more testing I found the solution to the problem, which was to use Word.Document instead of Word.Document.8 as progID.
I have don't know why this seems to be a problem with 64-Bit compilation. The thing, I noticed though was that CLSIDFromProgID() now resolves to a different CLSID.
I have a problem with RegOpenKeyEx() function.
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKeyName, 0, KEY_READ, &hkMon);
Function return error code 2 (file not found), but this key exist in registry.
I try this on Windows 7 64-bit and Windows Xp 32bit.
When working with the registry you have to be aware of UAC registry virtualization (VirtualStore redirection for compatibility) and WOW64 (32/64 bit separation and registry redirection/reflection). Because of these features you sometimes end up in a different place in the registry and it will not match up with what you see in Regedit.
In cases like these the best thing to do is to use Process Monitor so you can see which key you are really accessing...
i have a 32 com library and would like to use its functionality by a 64 bits application , i 've searched on the internet and managed to get this workaround
Locate your COM object GUID under the HKey_Classes_Root\Wow6432Node\CLSID\[GUID]
Once located add a new REG_SZ (string) Value. Name should be AppID and data should be the same COM object GUID you have just searched for
Add a new key under HKey_Classes_Root\Wow6432Node\AppID\
The new key should be called the same as the com object GUID
Under the new key you just added, add a new REG_SZ (string) Value, and call it DllSurrogate. Leave the value empty
Create a new Key under HKey_Local_Machine\Software\Classes\AppID\
but it does not work on Windows 7 64 bits , the main problem is when i do the step 6
i found the key already existed, any body knows why ? or how can i overcome it ?
the documentation here is very brief
So, what you need to do here is start up this 32bit COM component in its own process, ie by calling CoCreateInstance with CLSCTX_LOCAL_SERVER.
Either this will be straight forward with the existing DLL, or if not you should wrap it with your own 32bit simple COM component which supports running as a local server...
Trying to tweak the registry is a no-win game - use the Dll as it was intended and save yourself the pain.
It could be caused by registry virtualization. Ive had problems like this in the past. The biggest annoyance is that you cant see the values or keys that the editor is complaining already exist. They actually exist in a different part of the registry (likely the users hive).
Good luck
64-bit executable cannot call a 32-bit DLL (and vice versa). You should compile your 64-bit application as 32-bit. That way you will be able to use the DLL and run all that on 32-bit and 64-bit OS.
Registry is just a suitable way to locate required dll.
If you know path to the 32bit dll on each system or you can pass it with your application, and you control the code of your 64bit app, then you can use following techniques:
1) SxS mechanism + manifests allows to load dll from a local folder without registring it and create COM components from it
2) Make this manually http://www.codeproject.com/Articles/18433/Emulating-CoCreateInstance
The 2nd solution is much simpler...
I have a dll made in cpp which tries to read/write some Registry Keys. This code runs perfectly fine in Windows XP (32 bit environment) but it fails in Windows 7(64 bit environment).
The registry keys which this application accesses is the shared registry keys. These keys are not part of 32 bit registry cache(wow32 bit) or 64 bit registry cache.
Please provide your valuable inputs on this.
Thanks in advance.
Jits
when you say "shared" you mean for example under HKLM? Only elevated applications are allowed to write to those on Windows 7 and Vista. If this is news to you I suggest searching on User Account Control or UAC.
Check out this: RegQueryValueEx Function
And this: Registry Key Security and Access Rights
IMO you have to check your permission settings that you use to open the key. Either remove the settings that require elevated privileges or run your app in elevated mode.
Maybe you should initialize the value of "lpcbData", the last parameter of RegQueryValueEx.