My DLL should use another DLL dynamically - c#

I have created a COM DLL in C#.
In this DLL I am linking against a third party DLL ("thirdpartydll.dll").
When I set "thirdpartydll.dll" to be output into the Release folder during the compilation, all works fine.
But I do not want to distribute "thirdpartydll.dll" with my DLL.
I would like my DLL to use the "thirdpartydll.dll" that may (or may not) have been registered by the third party.
For example, if the third party installed "thirdpartydll.dll" to C:\Program Files (x86)\Third Party\thirdpartydll.dll, then my COM DLL should use this.
Currently this does not work. I get the automatic error 80070002. I guess it means that my COM DLL can not find "thirdpartydll.dll". I am not sure why. I thought my COM DLL would find it automatically.

If you do not want to care where (non COM) thirdparty.dll is installed on the target system, it has to be install into the Global Assembly Cache (GAC).

Related

Merging multiple managed and unmanaged dlls into single single dll with Fody Costura

I'm embedding multiple 3rd party managed and unmanaged dlls into one dll.
That single dll gets picked up and injected into another host application at runtime ussing Assembly.Load
The entire thing is supposed to work as a host with plugins thing. (just to clarify)
I have it working for all dlls (managed, unmanaged and mixed) except for one: VideoOS.Platform.SDK.Export, for which I get
dll not found exception on runtime, the dll is from Milestone NVR SDK
I've tried:
putting it as IncludeAssemblies, Unmanaged32Assemblies and Unmanaged64Assemblies
toggling: compression, temp files on disk
manually loading it from the resources with: AppDomain.CurrentDomain.AssemblyResolve
decompiling the library itself with (Reflector, DotPeek, ILSpy) they all turn up with issues, so I'm thinking it's probabbly some pinvokes or similar that they can't decompile.
Notes:
The whole process works when the dll is in the same folder as the host app exe but not when it's embededd
I had an issue with a referenced library that started working when put in Unmanaged32Assemblies was resolved OK

How do I add a dependency to a third party dll that causes an error?

I have a Visual Studio (2015) project, written in C#, that is dependent upon an external dll (say a.dll), written in C++. This in turn is dependent upon other libraries (say b.dll, c.dll), also written in C++. These in turn are dependent upon some boost libraries. I have no control over any of the libraries, but they must be used to complete the project.
Adding library a.dll to the visual studio project is fine. I can add it as a reference and that works. However, it does not run, because the other libraries are not present.
When I try to add b.dll and c.dll to my project, then I get an error:
A reference to 'a.dll' could not be added. Please make sure the file is accessible, and that it is a valid assembly or COM component.
Using this answer (https://stackoverflow.com/a/12639732/5503148) I tried running TlbImp, and got this error:
TlbImp : error TI1002 : The input file 'b.dll' is not a valid type library.
If I copy the libraries to the output folder manually, or get them copied automatically by adding them to the project (not as references), then it all runs.
However, in the end result the project needs to have a dependency on the libraries. That way they can be loaded into another third party product.
Is there a way to do this manually - i.e. tell Visual Studio that the library a.dll is dependent upon other libraries?

Register a dll that references multiple dlls

Ok I have 2 questions and I'm in a pickle here and have been for a week.
Important - No application will build this or run it. It will be a single client side dll (that references several other dll's) that will be placed in specific folder and I will need to register this dll using regasm or something.
OverView:
So I have a c# COM ScannerController.dll written. ScannerController references five 3rd party dll's that will already be installed and registered in folders throughout c:\Program Features\etc.... (the locations will change depending on the version of the software that they are on, but the dll will be the same.)
This one dll (integration.ActiveX (it's an assembly)) has a method called InstalledPath. InstalledPath returns the actual location of the executing assembly. When I finished the dll I ran it through IExplorer and it was returning the correct "../program features/....".
Then, in order to set it up on another computer I unregistered it and then ran some regasms and registered the dll at "Scanner/bin/debug/integration.ActiveX" (which oleview says it can't find it's dependencies) So I unregistered it, built it in vs2012 and now when I run it from IExplorer, the InstalledPath is "../bin/debug/". I created a new projecte, built it which auto registered it, and ran it from iexplorer and the InstalledPath is "..Scanner-fake/bin/debug/". I've unregistered it a million times in cmd and no matter what I do, it is now always pointing at the debug folder of the registered ScannerController.
Question 1:
How in the world do i register my COM ScannerController.dll, using something like regasm, and also point it to the five 3rd party dlls that ScannerController references?
Question 2:
I tried fixing it to where Integration.dll wouldn't exists in the local path on my computer (since i'm building it) so I set the copy local to false. When I build it, view it in oleview, it says that its dependencies cannot be loaded or found. How can I set the project up so that, with the copy local = false, the references can find the other 3rd party dlls?
Sorry for the lengthy question but thank you so much for reading and attempting to help me out. I have searched high and low for this and I am just mentally exhausted now.
1) ScannerController.dll
COM registration using regasm ScannerController.dll
2) 3rd Party ActiveX dll
Assuming it's already registered: No action required. (Otherwise register with regsvr32)
3) 3rd Party Managed Libraries (no com types/libsexposed)
Use one of the following 2 option to guarantie that your ScannerController Libraray can access these managed libraries:
Copy them to the folder where your ScannerController.dll or maybe (I am not 100% sure, you have to test it) to the folder where the ScannerController.dll host - the exe / the process calling ScannerController.dll - resides
Register these libs in the global assembly cache (the registry pendant for managed libraries) to make them globally available to other applications

How to deploy a COM

I just finished building my new COM project (C#, .NET 3.5). This project will be called by a VFP application. It's working great on my development machine, but now I need to know how to deploy it on the user's machine. Click Once isn't available for this kind of project, so I guess I'm stuck with manually distributing the DLL.
So, where should I put the DLL and how do I register it?
BTW, the 3.5 framework is already installed on the user's machine.
TIA
I've really never used RegSvr32 with .Net assemblies, rather I use the regasm with the /codebase option:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe /codebase mydll.dll
You can also use the /tlb option to export the type library and register it.
Of course the easiest way, just create an installer with vstudio and it will do this for you.
Creating a Description of the COM class and Interfaces
.Net assemblies don't include information in Type Library compatible format. So it is necessary for the programmer to run one of two .Net-supplied utilities to extract the assembly description of a class into a Type Library file.
One utility is TLBEXP.EXE, the .Net Type Library Exporter. This command line utility takes as input the name of an assembly DLL file to be converted to a Type Library. The programmer can also specify the name of a Type Library file to be created.
tlbexp ComServer.dll /out:ComServer.tlb
Assembly exported to C:\Magellan\Source\Output\Debug\ComServer.tlb
Once a Type Library has been created, it can be referenced by a COM client to obtain the information necessary for the COM client to bind to the interfaces of the COM class, and activate the COM class at runtime.
Registration of the COM Class and Interfaces
For a COM class to be accessible by the client at runtime, the COM infrastructure must know how to locate the code that implements the COM class. The following command accomplishes this:
regasm ComServer.dll
Your DLL can be put anywhere you wish, but a good choice is C:\Program Files\MyApplication.
http://www.csharphelp.com/archives/archive190.html

C++ calling managed COM object can't find dependent assemblies

I've created and registered a managed COM library in C# on my development machine. I've successfully registered it and created a .tlb file with regasm, and successfully imported the tlb into a c++ console app used for testing.
My COM assembly is called "efcAPI.dll" and it references another assembly that has not been set up for COM or registered in anyway called "efcServerDiscovery.dll". This second dll contains some code used by my COM dll and exists in the same folder as efcAPI.dll.
Everything concerning loading the COM assembly works fine. I can create instances of my classes defined in the COM and call methods from them. However when I call certain methods that use the code defined in efcServerDiscovery.dll I get a _com_error which reports that it could not load file or assembly 'efcServerDiscovery'.
I've verified that everywhere on my hard drive where efcAPI.dll exists there's a copy of efcServerDiscovery.dll (which is just the location I built and registered efcAPI.dll from). I've also attempted to place efcAPI.dll and efcServerDiscovery.dll in the same directory as the c++ app with no success.
Any suggestions as to where the c++ app is looking for the assembly or how to discover where it's looking would be great!
Yes, this is a problem with COM components having non-COM dependencies. Windows doesn't consider the location of the COM DLL when it searches for dependent DLLs. The normal search rules are in effect, the folder that contains the EXE first, Windows directories, current working directory, PATH environment. The location of the COM server does not play a role.
Assuming you don't want to deploy to the EXE folder, none of these are good places to store your DLL, although plenty of installers made the desperation move of storing it in c:\windows\system32 or modify the system PATH environment variable.
One thing you could do is P/Invoke SetDllDirectory() in your C# code before running any code in the DLL. Using Assembly.GetExecutingAssembly().Location will do it. That is however not a safe thing to do though, it might alter the search rules for the app that uses your component.
The only real fix is to install the DLL in the Windows side-by-side cache (WinSxS) and to include a manifest in your C# executable. Given the state of the documentation, I can only wish you the best of luck.
In these situations i always start with Dependency Walker verifying that what & where its trying to load is what i think it is.
fuslogvw will tell you where the CLR is looking for assemblies
Or use GAC.
(here are your characters, stackoverflow)

Categories

Resources