How do I install both 32-bit and 64-bit versions of a COM DLL and "auto-select"? - com

We've got a DLL (a COM server) that will compile fine in 32-bit and 64-bit, but the DLL uses the same CLSID and AppID for the 32-bit version and the 64-bit version. Is this OK or does this have to change?
I'm asking this because apparently on a 64-bit machine, we can't register the 32-bit version and the 64-bit version together. It would be nice if 32-bit client applications could automatically use the 32-bit DLL, and 64-bit client applications could automatically use the 64-bit DLL.
On a related note, we have the source code and Visual Studio 2005 project file for a client application ... how do we compile a 32-bit and 64-bit version of the same application? It's a C# application, and it includes a reference to our COM server DLL like this:
<ItemGroup> <COMReference Include="ComServer">
<Guid>{C1FADEA6-68FD-4F43-9FC2-0BC451FA5D53}</Guid>
<VersionMajor>830</VersionMajor> <VersionMinor>0</VersionMinor>
<Lcid>0</Lcid> <WrapperTool>tlbimp</WrapperTool> <Isolated>False</Isolated>
</COMReference> </ItemGroup>
If it turns out that we need a separate CLSID for 64-bit, how do we make this reference "only for the 32-bit configuration" in Visual Studio? Or do we have to have separate projects with the same source code: one that refers to 32-bit DLL, and the other that refers to 64-bit DLL?

Both versions can (and indeed should) use the same GUIDs for everything.
On a 32-bit machine you can't register or use the 64-bit DLL, so there's no problem there. The 64-bit DLL simply doesn't enter the picture.
On a 64-bit machine the 64-bit DLL gets registered in HKLM/Software/Classes/CLSID (etc.) and the 32-bit DLL gets registered in HKLM/Software/Wow6432Node/Classes/CLSID. (I wonder where you got the advice that you can't register the 32-bit DLL on a 64-bit machine...) A 32-bit client running on the 64-bit machine will look in the normal place in the registry, but the OS will silently redirect it to the Wow6432Node key instead.

This is dealt with inside Windows with a feature called 'Registry redirection' On the 64-bit version of Windows, a 32-bit program gets a different view of the registry. Any access to the HKCR alias or the HKLM\Software root is redirected for the kind of keys that a COM server uses. A 32-bit program actually sees the key values stored in HKLM\Software\Wow6432Node. You can see it with Regedit.exe
This is normally taken care of by an installer, a VS Setup project has the TargetPlatform property for example. If you want to make the COM server available in both 32-bit and 64-bit mode then you should use two installers. Or a 64-bit installer that writes both sets of keys. Having a COM server that can handle both is very unusual in the olden days. But not unheard of when you implemented in .NET for example.

Related

Can a 64-bit Windows app use an out-of-process (AX EXE) component?

A client is writing a 64-bit Windows app in some language (yet TBD) that can use COM. I have a 32-bit ActiveX EXE that includes functionality they'd like to include. All data to be marshalled between these would be simple 32-bit integers.
I have no experience in this area, but it seems like this should be possible. I've searched other answers here and many talk of using 32-bit DLLs in 64-bit apps but I didn't find anything on the point of out-of-process 32-bit COM servers in the same scenario.
We just migrated an MS-Office-based application from 32-bit Office to 64-bit Office. The application uses a 32-bit out-of-process ActiveX EXE which was written in VB6 ages ago. Everything worked smoothly, no modification to the ActiveX EXE was required.
So, in my personal experience, the answer to your question
Can a 64-bit Windows app use a [32-bit] out-of-process (AX EXE) component?
is yes.

Is it possible to load a 64-bit dll into a 32-bit process?

Is it possible to load a 64-bit dll into a 32-bit process ?
Generally speaking, I know it can not happen.
Yet, maybe there are some exceptions ?
No, and neither a 64-bit process can load a 32-bit DLL.
If you're on a 64 bit OS, you can load the DLL in a 64-bit process and have it communicate with your 32-bit process through IPC.
If you're on a 32 bit OS, you're out of luck.
In .NET, it is possible to load a 64-bit DLL into a 32-bit process for reflection only. For details please check "Analyze 64-bit DLL from within T4 template in Visual Studio (32-bit) using Reflection".
I know that this is a special case, but I thought I'd add it anyway because it might help others looking for a similar solution as me.
Yes, you can load 64 code in 32 bit module. example:
vmprotect
metatrader4
above software mixed x86 and x64 in one process.
I found metatrade4 for win7 has a function it exeucte a instruction like :
jmp 0x33:0x175328
segment selector 33 is a 64bit segment. after execution this instruction, cpu will switch to 64bit mode from 32bit mode.
if you use windbg to trace some windows api on windows x64 OS, you will find similar code.
for example:
NtQueryInformationProcess
But new computer bought today at least have 4G ram. We cannot prevent using 64-bit OS to avoid problem. We must face 64-bit positively! Server 2008 R2 only have 64-bit.
Issues around EXE AnyCPU / x86, 32-bit COM / C++ dll must be handled.
Ideally compile both 32 and 64 bit COM / C++ dll.

64 bit COM(ActiveX) server

I have activex server exe that was building and registering fine on 32bit OS. I wanted to make 64 bit version of that exe by upgrading project to Visual Studio 2010 and changing platform to X64 which apparently doesn't work.
Application itself works but I don't see it registered after running
That.exe /RegServer
I would appreciate any usable advice on migrating activex from 32 to x64.
Code that is processing /RegServer param is below:
if(lstrcmpi(lpszToken, _T("RegServer")) == 0)
{
_Module.UpdateRegistryFromResource(IDR_OUTDISKSARG, TRUE);
nRet = _Module.RegisterServer(TRUE);
bRun = false;
break;
}
32 bit activex is unuable for me since I have to load it in x64 .NET process.
Assuming that the process has enough rights to write to the registry, you'll have to take care of that by running it from an elevated command prompt, this is likely to only add the COM registry keys to the registry view that 64-bit processes can see.
32-bit COM clients get a different view of the registry, HKLM\Software\Wow6432Node. It is not going to find the registry keys there. Review RegCreateKeyEx() in the SDK docs. Note the link at the bottom and the talk about the KEY_WOW64_32KEY option. The online article is here.
32-bit clients accessing a 64-bit out-of-process COM server is otherwise a pretty well supported scenario, with some caveats. Like building and registering both the 32-bit and 64-bit proxy/stub DLLs.
When you run That.exe /RegServer, did you do that from an Administrator command prompt? If not that's probably why it didn't work.
If you did and it still didn't work, try debugging it to see what it's doing to the registry. e.g. Use Process Monitor, or even the Visual Studio debugger (remembering to ensure the debugger runs your app as admin).

How can I use the function CoGetClassObject in x64

I have a COM DLL that is compiled in 32-bit mode (the server side). I registered it and tried to call CoGetClassObject() from a 32-bit client for getting the IClassFactory.
Hr = CoGetClassObject(CLSID_IOrbCom, CLSCTX_INPROC_SERVER,
0 , IDD_IClassFactory, (LPVOID*)&ClassFactory)
and it works just fine for 32-bit client. Yet when I tried to call CoGetClassObject() from a 64-bit client I got "Class not registered" error.
I can only have my COM server compiled in 32-bit mode. My OS is 64 bit Windows XP.
How do I make it work?
This is the expected behavior - you can't load a 32-bit dll into a 64-bit client process, this is just not supported by the OS. You'll have to either recompile the server (and register the 64-bit version of it) or use DCOM, COM+ or other interop solution that would run the 32-bit code in a separate process and marshal calls from the client into that process using RPC.

Can a VB6 component be compiled to 64 bit?

Is there a way to compile a VB6 component into 64 bits?
My feeling is that the answer is "no", but I would like to confirm this.
Please, if you can, paste a link to an authorative source that would confirm.
No. I hope this counts as authoritative.
64-Bit Windows
Visual Basic 6.0
runtime files are 32-bit. These files
ship in 64-bit Windows Operating
Systems referenced in the table below.
32-bit VB6 applications and components
are supported in the WOW emulation
environment only. 32-bit components
must also be hosted in 32-bit
application processes.
The Visual Basic 6.0 IDE has never
been offered in a native 64-bit
version, nor has the 32-bit IDE been
supported on 64-bit Windows. VB6
development on 64-bit Windows is not
and will not be supported.
No it cannot (well Microsoft has not released a compiler to compile it for a 64-bit environment), but this does not mean that it won't run on a 64-bit system. To run it in conjunction with IIS, you'll need to install the 32-bit version of IIS.