I'm developing an application that depends on some 3rd party dll's (it's actually a plugin to the 3rd party application, and I receive COM objects implementing certain interfaces declared in those dll's). My project contains references to those dll's locally exist on the dev machine, but I want to avoid wraping them inside my installer (for size and legal considerations).
Instead, my installer requires that the dll's are already existing on the target machine, and their path is saved to a text file next to my executable assembly.
How can I use this file to link to the dll's on run time?
Or is it better to add an environment variable during installation and use it instead (how can it be done)?
Using project references, I do not know of a way to have dlls in an arbitrary location. Typically I've handled this issue using an installer, like InstallAware, prompted the user for the 3rd party location, and copied the dlls into my projects folder at the same relative location I chose in my solution file.
If this is improbable for you, you can always load the dlls and create instances of the classes yourself by hand using Assembly.LoadFrom and Activator.CreateInstance.
I hope this helps.
Related
Say I have a Visual Studio Project that references a libary XYZ.dll. I am not able to distribute that dll but I know that many people have a license for it.
What can I do to connect my project to XYZ.dll on the target computer? To be more precise, I want to do the following things:
Reference XYZ.dll in a project in Visual Studio.
Distribute a compiled version of the solution/project without XYZ.dll
Let the customer, who installs my program, link the program to his copy of XYZ.dll so that the program can use it.
(This may be an easy question, but I was not able to find the answer, maybe due to wrong search terms).
If the XYZ.dll is installed with a third-party product, you may check whether it is registered in GAC.
If so, then you - in your VS project - reference the XYZ.dll pointing to it in GAC and then setting the copy local to false, so that it will not be copied to your program's bin directory and used from there.
It becomes more problematic in case the dll is not in GAC - in such case you would need to ask user for the assebly's location (or read it from registry if you know what product to search for) and then resolve this assembly dynamiccaly using that path with the use of AssemblyResolve event (https://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve%28v=vs.110%29.aspx)
There is also a way in which you create a "proxy" class in your project that loads the third-party assembly dynamiccaly from the path on the customer's computer, and then create a set of proxy methods that would call loaded third -party assembly using reflection.
This is a simple question. I just can't run my program if the Newtonsoft.Json.dll is not in the program folder. Why this? I've tried adding the reference, added the file to the project root, added to the resources folder, but nothing worked. How to run the program without the Newtonsoft.Json.dll in the program folder? I'm developing in a Windows Form Application.
UPDATE
Problem solved, thanks to spender for introducing me the ILMerge, a really really nice NuGet package that can combine third party dlls to a single executable binary file. For who wants to make a standalone application, just use ILMerge. Rapid, easy and extremely useful. See ya!
Usually, if your program uses a DLL, then you'll need that DLL in the app folder (or in the user path, or the GAC).
The conventional method of distributing multiple files is with an installer. You can write one using either WiX or the VS Installer Projects extension. Now all your output files get installed in one go along with all the other goodness that comes with an installed program. I have a strong preference for this method.
However, there are alternatives:
Download the source and copy the source into your main project, then it will be compiled into your main assembly (make sure you check that this is permitted by the license).
Use ILMerge to combine all your assemblies into a single binary.
If you don't want to reference dll in your program, you can install it to GAC on client machine but I don't understand which the context you want
If you just need some JSON serialization. Can you switch out your functionality with the JavascriptSerializer class which is installed with .Net?
http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.90).aspx
I wrote a dll c++/cli library which uses my other c# dll library. C++/cli library works fine when I've got c# dll in the same folder as application which calls it. This library will be finally loaded to many applications and a C# dll must not be copied into directory with application. It has to be in the same folder as c++/cli library, but in that cases I've got System.IO.FileNotFoundException.
My suggestion is to load c# library manually or to change path where f.ex. firefox is looking for dependencies, but I tried with LoadLibrary() and Assembly::LoadFrom() methods to force loading from right directory. Of course I added directory path with dll to system PATH.
I work on VS2010.
You don't change the default directory where an application will look for dlls.
At design time put your dll in some well know location, the one you are going to deploy to. Add a reference to it, make sure it's set to Don't copy ever, otherwise it will end up in the bin folder. You have to do this otherwise it won't compile.
When you deploy, you'll need one package to deploy common dlls, and one for each application. Careful you don't create your own version of dll hell, if appA needs an older or new version of the common dll, compared to AppB
Add an AppDomain.AssemblyResolve event to main (for windows app). At run time the event handler will get fired when you reference a type in your dll, and the assembly has not yet been loaded.
In there you load it from the well known location. That usually in config, or in a relative path.
E.g.
AllMyApps
CommonDLLS
MyFirstApp
So the path you load the required common dll from would be "..\CommonDlls\MyCommondll.dll".
NB you will want to secure the dlls in some way, otherwise a bad guy might be able to inject their version of one in to your app, which would be bad...
You can use this mechanism to get the dll from a remote server or a database blob as well.
The simplest case is only a few lines of code, just look the event up. Took me about 15 minutes to get this going in a similar scenario.
Not on this machine though, otherwise I'd have pasted in the code.
We are trying to program a couple of plugins for another application. We have two directories each with the code it needs to run independently whcih contain all the dll's (but not the exe as its 3rd party and we have no control over it). There is some shared code in a dll, placed in each plugin directory. When introducing a new version of the plugin we need to change this shared dll in one of the plugin directories but leave the other. When we do this the old version breaks as it relies on the older version of the shared dll but it only loads one. Is there a way to force it to use a certain version of the dll?
you should use the latebinding approach System.Reflection
I have created a dll that will be used by multiple applications, and have created an installer package that installs it to the program files, as well as adds it to the Global Assembly Cache.
The dll itself uses log4net, and requires a xml file for the logging definitions.
Therefore when the installer is run, the following files get copied to the install directory within program files:
The main dll that I developed
- The Log4Net.dll
- the Log4Net.xml file
I am now experiencing a problem. I have created a test console application for experimentation. I have added my dll as a reference, and set the 'local copy' flag to false.
When I compile the test console exe however, I noticed that it has copied the log4net.dll and log4net.xml files to the bin directory. And when running the test console, it appears that it will only work if the log4net.dll is in the same directory as the exe. This is dispite the fact that the test console application does not use log4net, only the dll that was added as a reference does.
Is there some way to have it so that the log4net.dll & xml files used will be the ones that were installed to the program files, rather than any application needed to copy over local copies? The applications that will be using my dll will not be using log4net, only the dll that they are referencing uses it.
Many thanks
Don't install into the Global Assembly Cache! Even if your library dll is used by multiple applications each should have it's own local copy. Otherwise you get into a whole world of pain for saving a few KB of disk space.
Always copy the required dlls locally. If you are really sure that the application won't need it you can simply delete the unnessesary dlls later or don't include them in the installer. But if your application will call ANY reference there it will crash at runtime. So best option is to leave them there (after all they WERE referenced for a reason).
No, it's not possible (at least not without much efford) to have .Net load dlls from arbitrary locations on the disk. And it should be this way (look up DLL-hell if you want to know why).
I suspect your problem is the configuration. You must use fully qualified names if you want it to work from the GAC. As per the documentation at http://logging.apache.org/log4net/release/faq.html:
"When loading an assembly from the GAC the fully qualified assembly name, including the version, culture and public key must be specified. This is in the standard syntax supported by System.Type.GetType. See the next FAQ on how to get the version and public key for an assembly."
I managed to resolve this by adding Log4net.dll to the GAC as well. It will now run without needing a local copy the dll.
It does however require a local copy of the XML file, to correctly log.