VB6 to COM-callable wrapped .NET - problems finding .NET libraries - c#

Premise:
Wrote a COM-callable wrapper (CCW) written in C# to be called by VB6 code.
The C# code has .NET libraries (third party) that it must utilize.
The wrapped C# class instantiates fine, raises events properly, takes method calls properly.
Problem:
The VB6 code, when running the C# code, gets an error when the C# code attempts to access the additional .NET libraries mentioned above.
Process tested:
C# wrapped code completed.
VB6 code written, references the COM dll created.
"File not found..." error received when the C# code tries to access the .NET libraries from inside itself.
Copied the third party .NET libraries into the main folder of the VB6 code (also into system32 folder).
Still "File not found..." error.
Wrote a C# Windows Form test project. Referenced the C# wrapped code.
Received the same error as the VB6 code.
In C# Windows Form test project, referenced the .NET libraries used by the C# wrapped code.
The program ran just fine.
Conclusion/Question:
Can VB6 call/use a com-callable wrapped C# program that references other third party .NET libraries?

I've done this with tons of third party libraries and as long as the third party library DLL's are in the same directory as your C# DLL's there shouldn't be a problem.
Copying them into the same directory as your VB6 code will do nothing, the effective directory of VB6 code when running the in VB6 debugger is %ProgramFiles%\Microsoft Visual Studio\VB98, so the code running will have no visibility of that.
The system32 directory has nothing to do with DotNet dll's (the only DLL's they would affect is PInvoke'd dll's and you say you add a reference so that isn't the case).
Adding the third party library to the GAC should fix things, however that is not necessarily possible/easy due to the need to sign the DLL. So just make sure the Libraries you are referencing are in the directory of YOUR library and that VB6 is actually referencing that version of your library (Debug/Release whatever what last compiled). You may want to hand RegAsm the library to make sure the correct library is Com Registered.
So to sumerize, suppose your source code looks like this:
c:\projects\vb6project
c:\projects\c#project
And your project is set to Debug, the third party libraries should be in:
c:\projects\c#project\bin\Debug
When you actually want to distribute the application, make sure that ALL the libraries are in the same directory as your VB6 exe.

This will mirror somewhat the answer by Kris Erickson.
First, for my usage which solves these problems, I did not use the GAC. Assuming that my VB6 application is in c:\program files\mycompany\vb6app.exe, I placed the COM-friendly .NET dll (lets call it net4vb.dll) in the folder with the executable. I then regsiter that dll there with RegAsm using the /codebase option. Finally, I place the .NET assembly that I'm wrapping or using (lets call it purenet.dll) in that folder as well.
At this point, vb6app.exe should run with no errors.
It is important to note that if you select the "Register for COM Interop" in Visual Studio then it will overwrite the registration you did above. So do not use this option. Stick with the command-line tools only for this.

Related

install a c# com dll for use by vbscript classic asp website

I have a Classic ASP website with vb6 dll's and all is ok with the world, but now I have some extra functionality that has been completed using c# into a COM DLL. In the dev environment this is working, but now I wish to move this DLL onto another machine.
My question is what is the best way to do this?
I have seen answers such as "add it to the GAC" or, "in needs a strong name", etc.
What happened to the good old regsvr32?
Regsvr32 is still relevant today but you can't use it with .NET, only native DLLs. .NET has a special way to register COM-types as we shall soon see.
Regsvr32 works by invoking the DllRegisterServer export. DllRegisterServer gives the library a chance to register COM classes; type libraries; interfaces etc. This export is not present in .dlls created by .NET which makes sense because they are not COM by default. You can easily see these differences if you open up a .NET or non-.NET .dll in Dependency Walker/Viewer.
Here's a native c++ ActiveX dll I made earlier (Note the DllRegisterServer export on the right):
And here is a managed .dll. (Note there are no exports let alone DllRegisterServer):
If you have marked your c# class as COM-visible then you can complete the COM-registration by invoking:
regasm assemblyFile[options]
Tell me more
This will place the necessary entries into the Windows Registry.
There is no need for the GAC because native COM clients (VB6) do not use the GAC

Native C++ dll in one solution with C# project

I have a source file written in C++, performing some simulation. I would like to create a user interface for this in C#. How can I have both C++ and C# in a single Visual Studio solution?
What I did so far was I created a .NET C# project and solution, and then a native project as a DLL library. I have marked the C# project as "Depends on" the C++ dll. I have provided the necessary dllexport directives and imported using DllImport. Everything compiles fine, but when I execute the application, the dll is not found:
Unable to load DLL 'xxxx.dll': The specified module could not be found.
It is no surprise the DLL is not found, as the application is run from its output directory and the output directories are different for the C# and C++ projects. I do not want to write an explicit path as my import like `"..\..\Debug\xxxxx.dll".
Is there some common way how to structure a solution containing native a Dll and C# app so that the C# app can call the native Dll?
If you know that after deployment your C++ DLL will be in the same folder as your C# DLL (or executable), then on simple way to solve the problem is to use the PostBuild event (Project properties, Build events).
You can add a copy command that will put your C++ DLL into the C# output folder.
I found a very comfortable way, which might have some unexpected drawbacks, but I do not see any so far: I can enable CLR for the C++ DLL project, making it "mixed", even if it in fact does not contain any managed code, and then the project building it can be made a Reference in the C# .NET project.
To make the project mixed mode set Configuration Properties / General / Common Language Runtime Support to Common Language Runtime Support (/clr).
After this the build system copies the DLL into the application output folder automatically.

C++ unmanaged wrapper not working in web project/iis

i have received a wrapper class for a C++ unmanaged code, which i need to add to my web project and call through c#.
1) in a c# desktop application project
When i'm adding references i can only add the wrapper dll. cannot add the unmanaged dll. i think this is not a issue. Then when i'm buliding and running it gives an error saying
Could not load file or assembly 'AskCmnWrapper.DLL' or one of its dependencies. The specified module could not be found.
So then i manually copied my unmanaged dll to the bin folder . It worked fine
2) in a c# web application
i got the same above issue. manually copied my unmanaged dll to the bin folder when i'm trying to run it with iis express (through vs2012) . but it's not working. Is there any special configurations to be made when running unmanaged dll/wrappers in web applications?
please guide me.
thank you.
Chances are you are missing some of the required C++ redistributables or other dependencies. Run Dependendy Walker on your native DLL to see which ones are are missing.
Ideally, you want to make a C++/CLI project which contains the source code of the native library you are wrapping, and write a managed C++/CLI wrapper on top of it, in the same project. This way only the "wrapper" (containing the native code) will be required in your folder.
If you don't have the source, and you can not statically link the library into your C++/CLI project, you will need to have both the wrapper DLL and the native DLL in the directory at run time, as that's when they will be linked.

Trying to link C++ library with C# using swig - will not let me add reference to resulging dll to C# project

I'm trying to make c# bindings for a library. I used cmake to create a visual studio 2010 solution from the library source, and that compiled fine. I used the included .i file to create the wrappers as per the instructions here (https://code.google.com/p/labstreaminglayer/source/browse/LSL/liblsl-Generic/AUTOGENERATE%20HOWTO.txt ) using cygwin. I then added the resulting liblsl_warp.cxx file to the same project. It still compiled fine, so I would assume that the resulting .dll includes the required bindings.
I've added that project to my c# application and am trying to add a reference from the c# project to the resulting dll (also tried adding a reference to the project). The only error I get is A reference to 'lsl' could not be added..
What steps am I missing? I looked at a couple examples, and I am basically setup the same way, but their examples are significantly easier.
SWIG produces both C# and C++ source code. The C# code uses DllImport to import the functions from the C++ side - it doesn't use .net-like bindings. Therefore the C++ DLL does not need to be (and cannot be) registered, and hence can't be 'referenced'. Referencing is for registered DLLs.
So you have a C++ DLL and a C# exe. Just ensure the C++ DLL can be found by the exe, by putting it in the same folder for example. Don't worry about referencing it.

Debug C#.Net DLL Project from VB6 DLL project

I have three projects,
One is a VB6 project which compiles to an EXE.
Another is also a VB6 project, which compile to a DLL.
And the last one is a .Net (2010) project which compiles to DLL.
The DLL from .Net is referenced in my VB6 DLL project.
And the resulting VB6 DLL project is reference in my VB6 EXE project.
In this scenario, how can I debug my .Net DLL project?
It is failing (or not able to debug) in both cases, even if I attach the (VB6 DLL) process to my .Net DLL Project, or I setup the ‘start external program’ to my VB6 DLL project on .Net DLL Project.
Do I have to change the reference (.Net DLL) on my VB6 DLL Project to get it in debug?
All your valid inputs are welcome.
(Please explain the procedures step by step which I need to do)
Thanks in advance.
You should be able to debug the C#.NET dll by setting the start action under Debug to
Start external program
and specify the VB6 executable as the program.
I know this works as I use this to debug a .NET/C# plugin for an old VB6 application.
It shouldn't matter how many other dlls (.NET or otherwise) you have to go through to get to the code you are trying to debug.
ah vb6 :) it's been a long time....
basically, you can't debug .NET code within VB6 IDE.
However, nothing stops you from creating a .NET test project to unit test the .NET dll. And that's what you should have done prior to reference it in VB6.
If you need to track down a specific issue, another way you can use is to write debugging infos to a file/database/event view/... when the dll is in debug mode, like which functions were called, parameters, stack trace...
This might not be correct, but I believe VB 2010 uses what? .NET 4.0, right? VB6 was created in like...1994 I believe, so it would be <= .NET 1.0. The binaries would more than likely be incompatible.

Categories

Resources