E_NOINTERFACE for MFC GUI not for Win32 console application - com

Running under Win7 SP1 with VS2010 and Microsoft SDK v7.0a. If I create a VS2010 project for a Win32 console application, a CreateInstance on a regsvr32.exe registered COM DLL succeeds. If I create a VS2010 project for an MFC GUI, the identical CreateInstance fails with E_NOINTERFACE. Have tried both Unicode and multi-byte, works both ways for Win32 console application, fails both ways for MFC GUI. How is this possible?
If I F11 through the Win32 console application, I eventually see the CreateInstance get to a QueryInterface on IUnknown [which succeeds]. If I F11 through the MFC GUI, it never gets to the QueryInterface.
I've seen some talk about ADO versions/upgrades being relevant, but here is one system that succeeds for Win32 console application and fails for MFC GUI. How?
Update: I was mistakenly allowing the WinDDK comip.h to be used instead of the VS2010 comip.h. But even after correcting that, the problem remains.
Also discovered that the same MFC GUI project and source compiled on a 64 bit machine does NOT fail. Only my 32 bit machine does. Both get to QueryInterface in the CreateInstance call stack, but the 32 bit machine returns failure, whereas the 64 bit machine returns success.

Courtesy of MSDN tech support, I was enlightened that MFC GUIs do not support the "free threading" that COM requires.

Related

32 Bit dll in 64 bBit application

I need to run the vb6 32 Bit dll in .net application. When I run the application in X86 it works fine. But when I run the application in "Any Cpu" Configuration it gives Following Error:
Retrieving the COM class factory for component with CLSID {AAA4DA7D-FC03-4BF7-B240-FA6F323D41EE} failed due to the following error: 800700c1 is not a valid Win32 application. (Exception from HRESULT: 0x800700C1).
For the Code line
CommonUniqueObj = New Uniquekey.Class1
How to solve this error. I want to run the .net application in "Any cpu" configuration?
AX (COM) DLLs run in-process, and as the comments say, you can't mix x86 and x64 code directly.
One possible workaround is to compile the VB6 DLL as an AX EXE instead. 64-bit programs can instance AX EXEs and data can be marshalled between them, since they run in separate processes.
You can mix 32 bit and 64 bit. By calling into an exe bitness doesn't matter. Data is marshalled as with any out of process call.
DLLs can be run in an exe by setting registry values.
See https://learn.microsoft.com/en-us/windows/win32/com/dllsurrogate
PS when using an exe it is a good idea to always set everytime just before you use it in case the user has terminated the dllhost.exe that hosts the DLLs.

Calling an x86 dll from a VS 2010/DotNet 4.0 x86 targeted app

I'm getting an 'AccessViolationException' 'Attempted to read or write protected memory' when calling a method in an x86 dll when running on an x64 platform (Windows 7). Everything works great on x86 platforms.
I've read many, many posts about similar problems but haven't been able to get my code to work.
I'm in the process of trying to make our old x86 app work happily on Windows 7 (x64) and Server 2008 R2 (x64). The app is an assortment of VB6 , VB.Net, C#, MicroFocus COBOL and C++. (We couldn't think of any other languages to throw in at the time). The DotNet code was originally written in Visual Studio 2003 for DotNet 1.1. I've ported the code up to Visual Studio 2010 and DotNet 4.0. I've set the target for all the projects to x86. When I call into un-managed 32 bit dll's I get the above error.
Our InstallShield setup routine is installing the x86 dll's into C:\Windows\sysWOW64 instead of C:\Windows\System32. This behavior seems correct. The dll's are some COBOL object code and runtime components linked together into a 'C Style' dll. I don't think the problem has to do with COBOL or the linking process as I also ported up a sample app from Code Project with a VB.Net WinForms app that calls a simple C++ dll, all targeted to x86. I get the same error there. I've also tried building a C++ command line app to call the dll. The Load Library succeeds. GetProcAddress succeeds. Calling the function pointer for the particular method fails. Our VB6 apps can call the dll's just fine when running on Windows 7 x64. I've also tried turning off UAC and setting the requestedExecutionLevel in the manifest to the highestAvailable. I've tried running as administrator.
Seems like this should work, but not sure what to try next. Any ideas?
On x64 .net programs will be run as 64-bit programs and cannot call 32bit-dlls.
Try compiling the application with target x86 instead of "Any Target". You can also force the
target of the built .exe with the .Net CorFlags.exe utility to run in 32bit-mode.
Of course your program will then run in the 32bit environment, especially it will only have a maximum of 2gb of RAM.
Good news,
We investigated DEP as a possible cause of the problem as we saw that even our VB6 code will fail when DEP is turned on. We noticed that the VB.Net code was failing in the same way as VB6 when DEP was on. Apparently our COBOL dll's do something that DEP isn't happy with. Unfortunately the DotNet assemblies don't seem to respect the operating system DEP setting, so you have to turn off DEP with using editbin.exe:
editbin.exe /nxnocompat:no
I still have to test it on our full application, but it looks like we have a solution!

Microsoft C++ exception: _com_error at memory location

I have created a COM dll in .Net and build it under Any CPU. I am using that COM dll in Vcpp code but getting Microsoft C++ exception: _com_error at memory location error when creating the pointer reference to COM class. The VCPP code works perfectly fine if the Build configuration is Win32 but if i change the configuration to X64 mode then teh application crashes.
Please Help
Since you're using a so-called in process DLL, you have to use the 64 bits version of that DLL in your program.
This question discusses it. It seems that you have to use the 64 bit regasm tool to register your .NET DLL.

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