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

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?

Related

Using C# dll in C++ codes without using Regasm

I have created a C++ application which uses a C# dll following the link as shown below.
http://support.microsoft.com/kb/828736
The application works fine on my development PC , but when I tried to run it on another PC , it fails.
The only way to make it work is to recompile the C# dll on that PC and run the Regasm command again on that PC to work .
Is there a way to build my C# dll in such a way so that I do not have to do this every single time on every PC my application is deployed to ?
What regasm does is generate a COM wrapper for your C# dll and then registers it as a COM object.
You do not need to recompile though, once you have a dll you can register it on the target PC using regasm.
The main other way to call a C# dll is to write a C++ .net program using the C++/CLI system from Microsoft. This is basically a way of creating .NET programs using a superset of C++ (hint: its not C++, which is a shame as the old managed extensions it replaces was much more transparent for this task). As its not 'true' C++ you'll end up with a .NET binary instead of a C++ one, so be aware of this. One aspect is that you could write a C++/CLI wrapper to the C# dll and call that from your C++ program, this is probably the preferred way of creating a bridge between the systems.
I did this, and it worked, copy and paste the code on cmd
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\regasm.exe MyAssembly.dll
Kindly vote if it works for you. :D

Adding MinGW compiled DLL to Visual Studio fails

I have written a library in C that I want to be able to be used in C#, C++, and Python (other languages would be nice, but not necessary for now). The library was developed in Linux and I have been able to compile it on Windows via MinGW. The problem I am having is when trying to add the .dll as a reference in a Visual Studio 2010 solution. The error I get is:
A reference to 'C:\path\to\libmylibrary.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.
I have spent some time trying to see if I am compiling the DLL incorrectly, but don't see anything glaring out at me. Some references I've used are this, this, and this.
If more information is needed I can provide some compilable example source code.
There are 2 ways to add a "DLL" to a C# project.
If the DLL is a CLR Assembly, meaning it is managed code that adheres to the CLR, then you can add it as a "reference".
If the DLL is NOT a CLR Assembly, you can load the code manually using the P/Invoke structure. There's a lot of online documentation on P/Invoke. It is messy, but it works. You need to declare each DLL entry function using the [DllImport] attribute, and load the DLL manually. Search SO for p/invoke.
Based on your error message, you are trying to load a plain DLL as an CLR DLL. That means you'll have to figure out how to use P/Invoke.

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

How to 'flatten' a C++ COM DLL to standard exported methods? (Consumed by 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.

Generation of .tlb Files in Windows 7 Pro 32-bit

I have a C++ DLL that imports a .tlb file generated in a C# project. The C++ DLL is a wrapper DLL containing functions that call the corresponding C# functions.
When I call the C++ functions on the computer that I built the projects, all works well. But when I copy the DLL's and generated tlb's to another computer with the same exact version of Windows and installed programs andI call the C++ functions, it breaks with a COM error. However, after recompiling the projects on the new computer, everything works again.
I already checked the "Work on All Computers" for both projects but this keeps happening. What else do I need to do for the DLL's to work on all computers?
The HRESULT you get would be crucial to diagnose this. Forced to guess: did you run Regasm.exe on that machine? Required to make the necessary registry entries so COM can find the server. It is automatic when you build in the IDE.

Categories

Resources