I have developed a 32-bit application (build for x86) which will later be deployed on a 64-bit machine. I have set some configuration in registry so when the application starts on a 32-bit machine there is no problem reading its value, but when deployed on a 64-bit machine I can not read the value properly as the path of the registry is changed. To make things clear,
on a 32-bit machine I have the registry entry as follows.
[HKEY_LOCAL_MACHINE\SOFTWARE\MyApplication\InstallationPath]
"folder"="C:\Program Files\MyApplication"
But when I look on a 64-bit machine, this is shifted to:
[HKEY_LOCAL_MACHINE\SOFTWARE\**Wow6432Node**\MyApplication\InstallationPath]
"folder"="C:\Program Files\MyApplication"
Inside my application I have to query the value of the installation path. The obvious thing I have done is query the value with the hardcoded string "HKLM\SOFTWARE\MyApplication\InstallationPath", but which is not valid for a 64-bit machine.
How do I overcome this problem?
I don't really understand your problem: the Wow6432Node is transparent from the caller's point of view.
That means the registry key HKEY_LOCAL_MACHINE\SOFTWARE\MyApplication\InstallationPath will be automatically mapped to HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MyApplication\InstallationPath when accessed from a 32-bit application running on a 64-bit machine.
So your code should work out of the box.
Have a look at the REGSAM samDesired argument of RegOpenKeyEx and many of the other registry APIs.
The important one for you is KEY_WOW64_64KEY: "Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. For more information, see Accessing an Alternate Registry View."
You can use that in a 32-bit app to force it to inspect registry keys in the "native" 64-bit areas on a 64-bit system. (You might want to check that you're running on 64-bit Windows and only pass the flag then; I'm not sure what it would do on a 32-bit machine. Pass zero for samDesired when you want the default handling.)
You shouldn't have to do anything special in your code. 32-bit applications transparently access the portion of the registry under Wow6432Node.
To convince yourself of this, launch the 32-bit build of regedit.exe (available under Windows\SysWOW64) and take look around the registry.
Related
I have a VSTO addin which will not install on 32bit machines. (the error popup on install is: "This installation package is not supported by this processor type. Contact your product vendor.")
The addin uses Installshield to do the install.
The application builds with "AnyCPU".
It seems to force to 64bit if anything within installshield references a 64bit. (eg I have registry entries for my addin which are its Description, friendlyName, LoadBehavior and Manifest. These are located in HKLM/Software (64bit)/Wow6432Node/Microsoft/Office/Outlook/Addins/myAddin)
I don't really know if this needed?
So my fix is to have two releases... where one doesn't have any 64bit registry references.
How would I fix this? I've been toying around with the notion of ditching Installshield LE and moving to vs2017 with some other installer...
I have a VSTO addin which will not install on 32bit machines.
Do you mean the addin is not loaded by Office? or the install package itself fails to install?
I'll assume the addin is not loaded. I don't know how installshield controls the the package components bitness, but I will try to provide an answer that you can apply to any tool, as long as the following options are configurable in the tool.
With MSI packages installing VSTO addins you need to make sure your registry entries end up in the right registry hive, based on the bitness of your installed Office version, not the one of the OS.
So, for machines with Office x86 you have these registry:
on x86 OS: HKLM/Software/Microsoft/Office/Outlook/Addins/myAddin
on x64 OS & 32-bit Office: HKLM/Software/Wow6432Node/Microsoft/Office/Outlook/Addins/myAddin
The two paths above represent a single configuration in your MSI. i.e. if you create a standard MSI that installs the standard x86 registry entries on a 32 bit machine that same MSI will automatically be redirected to Wow6432Node for a x64 machine and everything should work if that machine has a 32-bit office installed.
If you have a x64 machine with a 64-bit office than you need to force the installation of that registry outside of the Wow6432Node, i.e. directly under: HKLM/Software/Microsoft/Office/Outlook/Addins/myAddin
This can be done from a 32-bit MSI too, if you mark the registry MSI component as a 64-bit (don't know where this option is in IS but I am sure you can find it). This will force the OS to stop the redirection to Wow6432Node for those registry entries. And the MSI should also work on 32 bit machines, where this flag will be ignored.
However, you should know that marking the component as 64-bit in a 32 bit MSI package will trigger some ICE errors/warning.
These are located in HKLM/Software (64bit)/Wow6432Node/Microsoft/Office/Outlook/Addins/myAddin)
FYI, this is the 32 bit area of registry on a 64-bit machine, not the 64-bit one. Only 32 bit applications can read registry from this location.
I am wrestling with an issue I cannot understand. We have a ClickOnce deployment of a WPF application in Azure blob storage. The processor architecture is everywhere "msil" in this deployment. When it gets run from IE, it runs as a 32bit application on AMD64 computers. The desired behavior would be to run as 64 bit. Could someone please enlighten on where should I look to fix this problem?
I already managed to go through the hoops to build the assemblies as x64 and create the ClickOnce deployment as amd64. This combo will run as 64 bit. The desired behavior is to still have it "msil" so it can run as either 32-bit or 64-bit, depending on the operating system it will be running on.
I use around 15-20 legacy 32-bit C++ COM DLLs in my web app, some of these 32-bit DLLs have 3rd party dependencies which are further DLL's COM or native.
I am considering moving to Windows Azure which I understand is a 64-bit platform. Can anyone advise whether my 32-bit DLLs will work? (I know that it is now possible to regsvr32 them).
With a week or two’s work I could recompile my DLLs to 64-bit however this is not possible for the 3rd party dependencies as I don’t have the source.
I understand that Windows Azure uses 64-bit so I am wondering what would be the best approach here to migrate my app?
i.e. should I move the 32-bit DLLs over and rely on WoW64 – will this even work? I don’t mind a small performance hit.
Or would be it better to recompile my 64-bit apps and somehow use the 32-bit DLLs?
The answer is yes. Windows Azure is just like a normal Windows Server 2008 x64, and it has 32-bit subsystem. The only limitation here is that the web role and worker role hosting process is 64 bit.
With this in mind, you will have to do some sort of interop between 64-bit host process and 32-bit DLLs. Of course, inproc COM objects will not work in this case. It is hard to give more specific advise here without knowing details:
What type of COM interfaces (automation compatible or not)?
What kind of marshaling they support (inproc only or out-of-proc)
If marshaling works across processes, do you have control on how to register objects (inproc or out-of-proc).
How easy is it to create managed wrapper for your object (like a custom C++/CLI interop assembly that is hosted by 32-bit process and able to communicate to 64-bit host using either WCF or COM automation)
I don't know if it would work, but another option to consider is try to coerse your application pool to run as 32 bit process. You will need to run in IIS mode with full trust and run this as your role startup task:
appcmd apppool set /apppool.name: /enable32BitAppOnWin64:true
You will have to determine name of application pool your app will be used. And again, I'm not sure that would work at all, but I guess it worth a try, because if it works it would be the easiest option for you.
This lab "Advanced Web and Worker Roles" in the Windows Azure Training Kit covers using a Legacy COM dll in Azure.
We have a 32-bit ATL out-proc COM server. In order to register itself in the registry it calls CComModule::UpdateRegistryFromResource() and passes an id of a .rgs file compiled into the resources of the same executable.
Works great on 32-bit systems, but not on 64-bit ones. Obviously when a 32-bit .exe runs on a 64-bit Windows its registry accesses are redirected and so it registers itself in "32-bit HKCR" and so 64-bit programs don't see its registration.
How do I register the same out-proc server in the 64-bit HKCR the cheapeast and most reliable way?
As far as I can tell/remember you don't actually have to do anything special.
I have checked a 32-bit ATL COM EXE server which I wrote specifically to be called from 64-bit code ( http://www.pretentiousname.com/adobe_pdf_x64_fix/index.html ) and the registration code is completely boilerplate (unless I forgot and today cannot see something I had to change).
Unless the code on the 64-bit side calling CoCreateInstance(Ex) is specifically passing CLSCTX_ACTIVATE_64_BIT_SERVER, COM should automatically check the 32-bit registry if needed. (Even if CLSCTX_ACTIVATE_64_BIT_SERVER is passed it may still do. MSDN isn't entirely clear if that flag is a preference or a requirement. I'm assuming it isn't being passed anyway.)
Perhaps the problem isn't how the COM server is registered but something else. Or perhaps there is a broken 64-bit version of the server registered, maybe from earlier in development/testing, which is being chosen over the 32-bit server and failing?
By the way, there are differences in which parts of the registry are 32/64-bit split on Windows 7 vs earlier OS versions, but I know from experience that you don't need to do anything special on Vista, Windows 7 and Server 2008 R2. I haven't personally tested on other OS versions (e.g. XPx64).
I am moving to a 64 bit Windows workstation, and will be developing both 32 and 64 bit applications. I will need to maintain different PATH environment variables when running a 32 vs. 64 bit version of my application.
What is the best way to do this? It seems like it should be possible with all of the registry redirection that goes on.
Thanks,
Dave
This isn't directly possible since system-wide environment variables are stored in HKLM\System\CurrentControlSet\Control\Session Manager\Environment, and there is no WOW64 redirection of the SYSTEM hive.
If your program installs under Program Files, you could add your path based off of %ProgramFiles% to the PATH environment variable - %ProgramFiles% expands to the 32-bit program files when running under WOW64.
I found a "trick" which is based on the redirection magic that Windows does with its system32/SysWOW64 folder. It works quite well for my 32 and 64-bit Oracle Clients.
I have documented the procedure on my website: Use 32 and 64bit Oracle Client in parallel on Windows 7 64-bit for e.g. .NET Apps
Relevant parts:
Open an elevated console and in %windir%\system32 create a soft link to the 64-bit oracle client installation, while in %windir%\SysWOW64 you make a soft link to the 32-bit installation.
Edit your PATH environment variable and add the following path to it: c:\windows\system32\11g. Please note that %WINDIR% will not be expanded in %PATH%.