Windows 64-bit registry v.s. 32-bit registry - com

I heard on Windows x64 architecture, in order to support to run both x86 and x64 application, there is two separate/different sets of Windows registry -- one for x86 application to access and the other for x64 application to access? For example, if a COM registers CLSID in the x86 set of registry, then x64 application will never be able to access the COM component by CLSID, because x86/x64 have different sets of registry?
So, my question is whether my understanding of the above sample is correct? I also want to get some more documents to learn this topic, about the two different sets of registry on x64 architecture. (I did some search, but not found any valuable information.)

I ran into this issue not long ago. The short answer is that if you run a 32 bit application on a 64 bit machine then it's registry keys are located under a Wow6432Node.
For example, let's say you have an application that stores its registry information under:
HKEY_LOCAL_MACHINE\SOFTWARE\CompanyX
If you compile your application as a 64 bit binary and run it on a 64 bit machine then the registry keys are in the location above. However, if you compile your application as a 32 bit binary and run it on a 64 bit machine then your registry information is now located here:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\CompanyX
This means that if you run both the 32 bit and 64 bit versions of your application on the same machine then they will each be looking at a different set of registry keys.

Your understanding is correct. There wouldn't be any need for a x64 app to access the x86 CLSIDs since it could never load those components anyway and vice versa.
If you want to create component for use by both x86 and x64 then you need to either create a pair of dlls one built for x86 and the other for x64 and register both in their appropriate parts of the registry. The regsrv32.exe in the System32 folder will perversely register the x64 component and the regsrv32.exe in the SysWOW64 folder will register the x86 component.
Alternatively build a .NET assembly for Any CPU which can used by either CPU architecture.

They aren't separate registries--one is a subnode of the other, and the OS does virtualization to make sure that 32bit apps get their keys and 64bit apps get their keys.

Here is the Wikipedia article on the WOW64 registry which may give you some of the information you are looking for:
http://en.wikipedia.org/wiki/WOW64

I run an x64 bit machine as my desktop; and I have never run into any issues with the different registry configurations.
Per MSDN, there is apparently a difference:
http://msdn.microsoft.com/en-us/library/ms724072(VS.85).aspx
HTH

How to register .NET assembly to be used as COM in pure 64-bit application?
Problem:
By default, if you enable "Register for COM Interop" in build settings, it DOES NOT register type library for 64-bit.
Solution:
To register your assembly which is not in GAC on a 64-bit machine, open cmd window and do:
cd c:\windows\microsoft.net\framework64\v2.x.xxxxx
regasm /codebase "path to your compiled assembly dll"
This will eliminate "Class Not Registered Error" when using native C++ to instanciate .NET assembly as COM object.

Related

Installation path for .Net based components building using Any CPU

.Net Assemblies built with AnyCPU will JIT to 64-bit code when loaded into a 64-bit or 32-bit process based on the CPU. I am creating a WiX installer.
What should be the default path (Program File x86/Program File) for the components built with AnyCPU option? Shall the installer check the platform and set the appropriate path or are there any other ways to handle it?
At this point in time, I'd recommend installing to ProgramFilesFolder (Program files (x86)) as that is present on both 32-bit and 64-bit computers. 32-bit is the closest thing (at this time) Windows has for "Any CPU".
Note: This does change as WOW is removed from 64-bit Windows. You can already remove the WOW subsystem from Windows Server, in which case you need to provide a package that targets the appropriate architecture. It isn't clear if/when WOW will be removed from Windows client.

Could not load file or assembly System.Data.SQLite - Windows application

I am trying to use the SQLite's .Net DLL to access some data on a local SQLite database. The problem is that i need a way arround this error because i need to develop a software for 32/64 bits platforms (by using VB.Net not C#).
How can i stick to the 32bit version of the DLL to allow 32bit users of my program use it too?
If it's not possible to work with the 32bit version of SQLite's DLL, is it possible to include both versions in my Installer and programaticly choose which version of the DLL should be used?
Or..is there any other way to access SQLite databases without this particular DLL? (Things in C/C++ are much easier when it comes to SQLite usage as i remember)
Thanks!
If you change your Target Platform to x86 instead of AnyCPU your code will be emitted as 32bit code also on 64bit systems and you could use just the 32bit dll of SQLite.
If you think that you are loosing some value working exclusively with x86 then I can give you this reference where the PRO and CONS of AnyCpu are critically examined.
To change the Target Platform use:
Menu BUILD, then Configuration Manager
Choose x86 from the Active Solution Platform combo.
If you don't have an x86 choice,
choose New and Select x86 and copy the default settings from AnyCpu.

COM registration with WIX in 32bit and 64bit Windows

I created an installer for my AnyCPU DLLs. I've marked my assemblies with teh Assembly=.net directive in my project as well. The installer seems to be able to register the COM servers successfully on my XP 32bit machine, but fails to do so in my Windows7 Machine. I did run the installer in admin mode. Also I looked up the Win764 registry and found those CLSIDs in the reigstry. So looks like the MSI did put some entries in the registry but somehow they are not being recognized as valid COM Server entries (OLE Viewer also didnt enumerate my server).
Any idea why this would happen? Any extra config do I need to add to my project?
thanks
Apparently you need to compile your msi as a 64-bit native binary to have the dlls registered in 64 bit mode.

Services 32bit dlls on 64bit machine

I've built and installed my service from vs2010 onto a 64bit machine.
My problem comes in when my service references 32 bit dlls (spssio32.dll to be precise) - I get the error in my event viewer : "System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)"
Any help on the matter would be appreciated.
Regards,
Byron Cobb.
Is your service code written in a .NET language? If so, you need to mark it as targeting x86 rather than Any CPU (via Project properties / Build / Platform target).
(By default, .NET code targets Any CPU, meaning that on 64-bit machines it will compile into x64 machine code. Because such 64-bit code can't load 32-bit DLLs, that can lead to failures like the one you're seeing. Where code has a dependency on a 32-bit DLL, it needs to always compile to 32-bit machine code even on 64-bit machines, hence setting the target platform to x86.)
You can use a COM surrogate
http://www.dnjonline.com/article.aspx?id=jun07_access3264
The other variant is to spawn an external 32 Bit server-process and add a .NET remoting interface to it and your 64 bit application, so you can use .NET remoting for interprocess communication.

Register COM reference to 64-bit Windows 7 machine

I am writing a C# program that interface with COM object through COM interop.
I have a third-party program that register itself as the COM server when I execute the Application. This works fine in 32-bit Windows Vista and I can interface with the interop just fine. (The reference show up in "COM" tab from Visual Studio when you click "Add Reference")
However, the reference does not show up in "COM" tab on my 64-bit Windows 7 machine after I execute the application. Any thoughts, why would this happen? I actually tried using regsvr32.exe to register the application manually but it didn't work either (error message saying "entry-point DllRegisterServer was not found)
You are not going to be able to use it as long as it doesn't show up in the COM tab. The regsvr32.exe utility is for DLLs, this however sounds like an EXE. If it is a DLL then it needs to be registered with the 32-bit version of regsvr32.exe, the one in c:\windows\syswow64. If it is an EXE then the normal way to get it to register itself is by running it with the /regserver command line option.
Mumble.exe /RegServer
Additionally, if this is a DLL or an EXE for which you don't have a 64-bit proxy/stub then you'll have to force your app to run in 32-bit mode. Project + Properties, Build tab, Platform Target = x86.
If all else fails, you really do need support from the vendor of this program. Surely they'll have an update available that is verified to work properly on 64-bit operating systems. If they are no longer around, running this in a virtual machine is always a possibility.
If it is a managed dll then you might try using RegAsm
REGASM AssemblyName.dll /tlb:AssemblyName.tlb
You may find this helpful as I needed to recompiled and build 64 bit proxy stub for the COM server from C++ myself and it kept failing when trying to register the server using /regserver. Here is and thread from miscrosoft that helped me resolved this issue. Basically you need to use this instead /RegServerPerUser, but go through the thread if you get into this situation after the answers from above.
http://social.msdn.microsoft.com/Forums/en/vcprerelease/thread/11f01ceb-52a4-438f-b7ef-727ce7a3e191