How to use ATl COM from a windows service - windows

Using the VS2008 wizard, I have created a Service (That does nothing currently other than Start and Stop)
I wish to use an (out of process) COM object
If I add a #import "object.tlb", then recompilation gives
error C2812: #import is not supported with /clr:pure and /clr:safë
Changing properties to use /clr (not pure or safe), allows compilation, but install of the service fails with "Ättempt to load an unverifiable executable with fixups"
Any advice appreciated
Peter

It is explicitly mentioned in the MSDN article for InstallUtil.exe:
Note that you cannot deploy a Windows service created using C++ with
Installutil.exe. Installutil.exe cannot recognize the embedded native
code that is produced by the C++ compiler. If you attempt to deploy a
C++ Windows service with Installutil.exe, an exception such as
BadImageFormatException will be thrown. To work with this scenario,
move the service code to a C++ module. Then, write the installer
object in C# or Visual Basic.

Related

Stepping into the break point when using Win32 thru a CLI Wrapper in a C# .NET Application

I have the following solution structure:
Project Files
1. Win32 C++ DLL
2. CLI/C++ Wrapper DLL
3. WinForm C# Exe
4. MFC Tester Exe
When I access the Win32 using the following stucture:
WinForm => CLI Wrapper => Win32 DLL
I can debug the WinForm and the CLI Wrapper but not the Win32 DLL.
I can only unit test the Win32 DLL thru an MFC Tester.
Is there a way to seamlessly debug until the Win32 DLL if it is run from the WinForm GUI not the MFC GUI?
I tried the following:
1. Attach WinForm Running and break thru the Win32 DLL
2. Checked the setup of the visual studio project
Using the following answer on the following previous stackoverflow question's accepted answer. (e.g. setting to Mixed debug, setting /Ci option, etc)
No Symbols loaded in mixed C# C(win32) project using VS2010
Do you have other ideas? Is it even possible?
You need to make sure you select 'Native debugging' in the debug options of the project. It will work then if you native code has symbols/PDB's.

Error registering a COM component and using in WPF application

I have a COM DLL (MyWrapper), with a COM ATL Object (class) defined inside. This COM dll is basically to be an interface between my WPF .exe and native MFC DLLs.
Everything works perfectly fine until I put the COM DLL in my source control to check in the code. I put the Pre and post build events to copy the DLL to our desired location. when I compiled I got the error.
Unable to register the dll. Try enabling per user redirection
I enabled the option in linker. The DLL compiled and copied to the directory successfully. Then I tried to add the reference to the WPF project, it gave me the following error
A reference to MyWrapper.dll" could not be added. Please make sure that the file is accessible and that it is a valid assembly or COM component
When I remove the pre/post build events and then add the reference, everything works great. I loaded the DLL in Dependency walker it shows IESHIMS.dll is missing.
I have tried to register the DLL using regsvr32 but that returns an error:
The module 'MyWrapper.dll' was loaded but the call to DllRegisterserver failed with error code 0x80070715.
I have admin rights on my machine and am running Visual Studio as administrator.
In the postBuild events, I created a Proxy dll of the COM and added that dll in my WPF application. This solved my problem.

ActiveX component cannot be created for COM component in release mode (VS2010 specific)

I have an ATL COM component(.exe) (VC++ ) in VS2008. Through VB6 client, i use CreateObject and get the object.
But once the component is updated to VS2010 SP1, the VB6 client no longer is able to create the COM object.
If I compile the VS2010 COM component in debug mode and get the .exe, VB6 client is working fine.
In release mode, .exe is generated without any errors, and VB6 client fails saying ActiveX component cannot be created.
Please help me in resloving this.
Finding out why COM refuses to create an instance of some CoClass is really a PITA. All you get is some generic error code that won't help you very much. If you use the run-time library via Dlls, you should check whether those can be found outside of the debugger. I use the COM/OLE viewer to check whether I can create objects of a CoClass, so that I can rule out that the problem has anything to do with VB. Good luck.
Stuart

What does tlbimp do which Visual Studio IDE doesn't?

I have a COM DLL written in unmanged C++, and compiled with VS 2010. I can register the DLL using regsvr32 and I can invoke it via VBscript.
When I try to add a reference to it, while creating a C# client, I don't see the COM object listed in Add Reference -> COM tab. If I manually browse to the DLL and try to select it, it says that the DLL is not a valid assemlby or COM component.
Now, I can use tlbimp tool to generate an interop DLL and use that to add as a reference to my C# client. And everything works fine.
My questions are:
Why the original COM is not listed in COM tab in Add Reference dialog when it's registered via regsvr32?
Why does VS IDE think that it's not a valid COM when I can invoke it from VBScript and C++ native code?
What exactly does tlbimp do which the IDE can't do?
What do I need to read further to improve my understanding of the
type libraries and interoperability at play here?
Looks like a typelib issue -- your COM classes may be have been registered correctly, but your typelib probably is not. Maybe you forgot to invoke RegisterTypeLib from within your DllRegisterServer function?
Referring to your questions:
The dialog looks for registered typelibs, not for COM classes
VBscript invokes IDispatch and does not care about typelibs. tlbimp does not care about IDispatch and requires a typelib
You passed the DLL name to tlbimp -- so tlbimp knew how to get hold of the typelib. VS, in contrast, refers to the registry which lacks the approriate registration data

How to fully publish a Visual C# project?

I have a Visual C# Project that is fairly basic (no more than 100 lines) but it includes some 3rd party DLL references. Running the project on the computer it was developed on has it run just fine.
In Microsoft Visual C# 2010 Express, I go to Project->Publish <project name> and it builds some files including a setup.exe installer.
When I move those files to another computer and run the setup.exe, it correctly installs the program.
But when I run the program, it simply closes out saying:
ProjectName.exe has encountered a problem and needs to close. We are sorry for the inconvenience.
The command window also appears for a brief second with some errors, but it's hard to make out what it is saying. It looks something like:
Unhandled Exception: System.Runtime.InteropServices.COMException: Retrieving the COM class factory for the component with CLSID { ....... } failed due to the following error: .....
I'm unable to get the command window to stay, so I cannot get the full message. But I assume this is due to the other computer not having those 3rd party DLLS.
How can I have Visual C# 2010 package everything including DLLs so this error does not appear? Or if that may not be the actual issue, how can I stop the command window from instantly vanishing? (I do not know the full list of DLLs required)
Or if the DLL is a registered DLL under C:\Windows\system32, is the project never going to build that into the package? Is there a way to see what it depends on?
Visual Studio 2010 Express doesn't create fully functional installers, but only ClickOnce installers, and those also with limited functions. This kind of installer can't register COM DLLs.
What seems to be wrong in your case is that you are using a COM DLL which isn't registered on the target system. You could try to check that in your own program (like trying to create the class and catch any exceptions that are thrown by the CreateObject function), and call RegSvr32.exe /s in order to register it. Or you just do this when the program starts the first time, before you create any object from the DLL... haven't tried that, though.
You could also make sure that you register the DLL manually on the target system before you run your program.
Moreover, when .Net uses a COM DLL, it usually creates a compatibility assembly which wraps the COM DLL and makes it accessibly to .Net. In case the DLL you use is only this compatibility assembly, you might have to locate the COM DLL it depends on manually on your system and to include it explicitly in your project's files.
In order to debug, it should be enough to put try / catch blocks around CreateObject. If that doesn't help, try adding an eventhandler for the event that is raised when an exception isn't handled by the application (this might be different according to the kind of application you create).

Resources