How to 'flatten' a C++ COM DLL to standard exported methods? (Consumed by c#) - c#

We have an in-house code C++ COM library. We are currently consuming the library from a C# application. Works fine.
However, the registration and unregistration of COM objects is tedious and is starting to be a problem for users upgrading to win7 due to the need for running the registration with admin priviledges (not possible directly from our Click-once application).
So... Since we really have no reason for using the library through COM (it's coded as COM for historic reasons), we'd like to switch to just exposing methods as 'plain exports'.
First attempt was just exposing the methods next to the COM Classes. Looks fine through appropriate tools for inspecting dlls.
Now, when I remove the COM reference in VS and include the dll by just 'browsing' in the add-reference dialog, it is still treated as a COM object and the dll is not included in output as I would expect.
Is it 'illegal' to use a COM library as simple dll? What is the best way through this problem?
Thanks for any input!
Anders, Denmark

You cannot use the add references dialogs to add a DLL, even if it wasn't a COM one. Now as it is COM it recognizes it and loads it at a COM object.
The simplest solution is probably to use registration free COM, which means you can deploy the DLL with your application rather than actually having to register it, but you still talk to it as a COM object. It is just a case of manipulating your manifest file.
Try the tool at here to help you generate the manifest, or a search on here for registration free COM.

To have the DLL in the output you should have the Embed Interop types set to true
more on this from MS

Do you know what, specifically, causes you to need admin privileges? If it's the COM registration, you could try registering the DLLs in HKCU\Software\Classes instead of HKCR.

Related

Calling C# compiled DLL classes and functions from VBA (excel)

I have a large codebase built in C# (classes and functions), compiled to .NET 4.7.2 in VS2019 and need to call to the compiled C# assembly (compiles to .dll) from VBA in excel. What is the path of least resistance to achieve this, considering I need to deploy the final VBA + C# dll (and whatever wrapper layers I may need) to client machines that won't have admin rights.
I can recompile the C#, if necessary.
If I cannot call directly to C#, could I go via a C++ native wrapper, and then on to C#? (or do I need a C++/CLI layer too?).
I have tried the recommendation here but access denied (admin rights required)
I also tried this Side-By-Side COM Interop with C# and VBA. But the .NET framework that excel targets is of an older version than that which I build my C# on. Not sure how I can fix this... Would it require registry edits? because if so, I can't use that method as I don't have admin rights.
Lastly I looked at this option https://pragmateek.com/using-c-from-native-c-with-the-help-of-ccli-v2/. But it appears to be going via C++ -> C++/CLR -> C# source. considering I start in VBA, that's two intermediate steps... surely there is a better way?

Creating class library in VS2013 and registering the .tlb so it can be referenced from a VB6 app

I created a COM class library using my VS2013. I went into the library properties and Compile -> Register for COM interop is checked. I then built the library and see the .tlb file that it generated. At this point I am wondering if there is anything additional that I have to do with the library properties.
I then used RegAsm sample.dll tbl:/sample.tbl
Would the next step be to simply reference the tbl from my VB6 app? I keep getting an error when trying to use the CreateObject function: 429 ActiveX Component can't create object
If my COM library is created properly with GUIDS/Settings based on tutorials and I registered it with RegAsm is there anything that I could be missing?
I had the same problems registering a COM-Interop-DLL. I finally used the InstallShield limited edition setup project to get it running. It's free and replaces the old MS setup project. You need to register to download the software and get a licence.
In the tab Application Files add the needed files. In the properties of the files / tab COM & .NET Settings set the check box COM Interop (this is what I'done) and then create the output.
This is what worked for me.
Christian

COM troubles between two versions of a C# Application

I haven't worked much with COM, so please forgive my ignorance.
Background: I am working on a project in VS 2010. There is a C# COM DLL integrated into the C# solution, and a Setup/Deployment project as well - the Setup project is set to register the COM .tlb file upon installation.
The problem: A previous version of the C# application, along with it's COM DLL, was present on a PC when someone decided to install the newest version of the C# application, and therefore the newest COM DLL. When this happened, it broke the COM functionality for both versions of the C# application..or that is what I am assuming has happened.
Is this typical COM/DLL-Hell behavior? When both C# applications are uninstalled, and then only ONE is re-installed, everything is back to normal - both apparently can't be installed at the same time.
I have tried changed the GUID for the COM DLL project, changing the AssemblyVersion and AssemblyFileVersion for the COM DLL project - all with mixed results. When I change those items, the new install of the application works (great), but now the old C# application doesn't have working functionality.
Note: there are no errors or exceptions thrown when the COM functionality is failing - the COM calls just seem to do nothing. So it is "silently" failing.
I have been researching this and trying various modifications to no real success...maybe I'm thinking about this the wrong way. Is there anyone else with more experience on this that could give me some insight?
You could use a merge module to install the com object and its successive versions. This would allow you to have multiple versions on the same machine. From Microsoft:
A merge module is like a snapshot of a particular version of a component. A new merge module should be created for each successive version of a component in order to avoid version conflicts.
Check out this link: Installer vs. Merge Module Recommendations

Making a c# winforms application useable as a dll from an unmanaged mfc application

I'm wondering how I would go about converting an existing c# winforms application to a class library and then call it from an mfc application. Are there any references on how to do this? I've tried googling, but, besides the fact that it will need the ComVisible attribute set to true I haven't found much information.
Thanks.
In visual studio project properties change the output type to class library. This will make your project compile into a dll. Also set the comvisible attribute to true. Thus will generate a com callable wrapper and a tlb file which you can use from your mfc project.
Also I think the following link is a very good and detailed explanation of how COM Interop works in .Net
http://www.codeproject.com/KB/COM/cominterop.aspx
Have a look at the regasm.exe tool shipped with .NET. It will generate the necessary registry entries (and optionally a .tlb file) that will allow COM components to access your assembly.
There is an MSDN sample that covers putting a Winforms user control on an MFC app - dialog or view. In addiition to code this should show you the project settings you will need.
Once you get this build properly, then you will need to get it to run properly. The main problem might be correctly parenting the windows forms from unmanaged windows, basically getting your managed forms to live inside what started as an unmanaged application. If you don't use WPF as the UI bridge between your unmanaged code and managed forms, then you will need to do this work yourself. You can google this topic for more info, don't have a link for this handy at the moment.

Adding dlls in VS 2008

I would like to add some external .dll libraries e.g. glut32.dll (but it's only example) in Visual Studio 2008, using C#.
Can you please tell me what should I do step by step?
I am a little bit confused cause I found a lot of solutions to add dll files, but they significantly differ.
Some of them add dll's only using code, some using properties in vs, add references and in other tutorials there is about registering dlls in system.
But how to put it all together?
There are different kinds of DLLs, you'll need to treat them differently when you use them in a C# project. The 3 main kinds are:
DLLs that contain unmanaged code and were designed to be used by a program written in unmanaged code. You cannot use such a DLL directly, there is no way to add a reference to them in a C# project. You must use P/Invoke, the [DllImport] attribute is required to declare the exported functions in the DLL. Glut32.dll is such a DLL. A very basic test you can use to see if you've got such a DLL is to run Dumpbin.exe /exports on that DLL. It lists the names of the functions that are exported.
DLLs that implement an in-process COM server. They are written in unmanaged code as well. .NET has very good support for using such servers, as long as you have a type library for them. The type library is usually embedded in the DLL, Visual Studio expects to find it when you add a project reference, either through the COM tab or the Browse tab. A very basic test is Dumpbin.exe /exports again, an in-process COM server has 4 exported functions. The DllGetClassObject function is the important one. You can view the type library embedded in the DLL with OleView.exe, File + View Typelibrary. A good example is c:\windows\system32\shell32.dll
DLLs that were created by a managed compiler. They don't contain machine code like the other types, they contain IL code and metadata. It is the native kind of DLL for managed code, you simply use Project + Add Reference to add a reference, the compiler automatically knows the types that are available in the DLL.
The first kind is the one you'll encounter a lot for DLLs in the wild. There's a lot of code written for Windows in an unmanaged language. It isn't a kind of DLL that's particularly easy to use from managed code. Glut32.dll for example has a lot of exported functions, writing a P/Invoke declaration for every single one of them is painful.
Tools you can use to help with this are SWIG and PInvoke Interop Assistant. The former is required when the DLL was written in the C++ language. C++ classes are not directly usable from a C# program, they need a wrapper written in the C++/CLI language. The latter tool is useful for DLLs written in C, including the Windows API.
Beware that those tools don't usually give you a clean and guaranteed-to-work interop solution. Declarations in unmanaged code are ambiguous, you'll need to know the exact semantics of the arguments of an unmanaged function to pick the right one. Getting the wrong one can be hard to diagnose, the best place to get help is a forum or Q+A site. Like stackoverflow.com
You can use the add reference dialog under the project menu to do that. Just go to the COM tab and add your library. Now you can verify that the classes appear in teh object browser
Right click on project in solution explorer and select add reference and then browse and select the dll.
If you wish to reference the dlls you
Right Click on References, and select add reference.
Or have a look at
How to: Add and Remove References in Visual Studio (C#)
Adding a Reference to a C# or Visual Basic .NET Project
In Solution Explorer, right-click the project node and click Add Reference.
In the Add Reference dialog box, select the tab indicating the type of component you want to reference.
Select the components you want to reference, and then click OK. Tip.

Categories

Resources