42

I am using EmguCV for a project and when our program runs it needs some dlls like "cxcore.dll" etc. (or it throws runtime exceptions). At the moment, I put the files in the root of the output folder (selected "Copy Always" in the file's properties in Visual Studio).

However it looks a bit messy, to have about 10 different dlls just there. Is there someway where I can move it to a subfolder in the output folder and it'll still find it.

Aishwar
  • 9,284
  • 10
  • 59
  • 80
  • Are you wanting to reference them from another location (i.e. be included with all other dependent libraries), or have them in say a subfolder under your bin directory? Also are these **included** in the project, or are the **loaded** (Assembly.Load, or P/Invoked) by your app? – GrayWizardx Mar 15 '10 at 07:13
  • @Gray: I want to put them in a subfolder under my bin directory. I do not use these dlls directly, but they are used by the EmguCV project (I believe they are P/Invoked). Also, I think the dlls themselves were written in C. If the dlls are absent I can still build, but I would get a runtime exception. – Aishwar Mar 15 '10 at 07:19

4 Answers4

74

Amazing answers so far. None right ;) Well,

yes, you can put the assemblies in separate locations.

In the corresponding application config (app.config which gets copied to your.exe.config) add:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="lib" />
    </assemblyBinding>
</runtime>

According to:

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

This will make the program look into the private path (folders under it's own folder) for assemblies - much like a web application looks for /bin.

You can also put them into the GAC, but that should be avoided unless there are other reasons for this.

That being said, you really dont need to. Users wont get confused if you install the application properly in the start menu ;) I never had that problem, including projects with 50+ assemblies. Users simlpy never see them.

Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
TomTom
  • 61,059
  • 10
  • 88
  • 148
  • @TomTom Svish answer is right – Sergey Mirvoda Mar 15 '10 at 07:27
  • 3
    As for your answer. Are you sure it will work with unmanaged libs? – Sergey Mirvoda Mar 15 '10 at 07:29
  • @TomTom: Would the above be in my `.csproj` file? My project is a C# winforms application - I cannot find a `.config` file. – Aishwar Mar 15 '10 at 07:40
  • Swish answer also was done after mine. The entry would go into the aplpications config file. Read up on .config files - really. This is .NET basics. Add itme, it will say application configuration. the result is a XML file named "app.config" that gets copied on built into "your.exe.config". This is where you can do runtime configuration - similar to (same file actually) the web.config in web applications. Read up on them. – TomTom Mar 15 '10 at 08:01
  • I am not sure this applies to libraries which are P/Invoked. It might work, and probably works by association, but I am not sure if it directly answers the question since we are talking about libraries not assemblies (i.e. c++ dlls) – GrayWizardx Mar 15 '10 at 08:20
  • He talks about assemblies. First line of the question. Unmanaged libs - no idea. I seriously wont even try moving the assmeblies, as I indicated - so I never tried that out. – TomTom Mar 15 '10 at 08:33
  • I had dll hell with this. I was doing everything right but it still wasn't working. The catch is when you add references to your project, keep the **COPY LOCAL** to false. After that, add the reference to your `yourexe.config` file. – lukik Sep 27 '12 at 03:57
  • 3
    I tried, but I could not make it work properly... So I found a solution and posted here: https://stackoverflow.com/a/51211161/5734097 – D.Kastier Aug 03 '18 at 11:57
  • This doesn't seem to be an option if the assemblies are located in parent directories. It only works if they are in the application's directory or a sub-directories. – Guett31 Jan 05 '23 at 23:50
26

To get the assemblies in a sub-directory you can copy them there manually, use a pre- or post-build event or something completely different.

To load them, you can use the AppDomain.AssemblyResolve Event, or (as noted by TomTom) the <probing> Element. From MSDN:

The following example shows how to specify application base subdirectories the runtime should search for assemblies.

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="bin;bin2\subbin;bin3"/>
        </assemblyBinding>
    </runtime>
</configuration>

The GAC is of course another place to dump your assemblies, but that wouldn't really count as a sub-directory... unless you install your application somewhere it really shouldn't be installed :P

Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Svish
  • 152,914
  • 173
  • 462
  • 620
  • @Svish: Would the above be in my .csproj file? My project is a C# winforms application - I cannot find a .config file. – Aishwar Mar 15 '10 at 07:44
  • @aip.cd.aish: There is a more complete example at http://msdn.microsoft.com/en-us/library/4191fzwb(v=VS.90).aspx. If there is no config file, you can just create one. According to http://msdn.microsoft.com/en-us/library/ms229689(v=VS.90).aspx it is supposed to be named the same as your application with a .config extension. – Svish Mar 15 '10 at 08:25
  • The file might also be named just app.config... but I'm not sure. Read about configuration files on MSDN and you should figure it out :) – Svish Mar 15 '10 at 08:26
-2

You can copy the dll's to the place you want using the pre/post build events, and the macros that telling you where your output folder is.

But, if the dll's are not in the same directory as the executable is, they won't be loaded. If they are managed, you can load them manualy using the Assembly.Load methods. If they are unmanaged, I don't know how you can do it.

sagie
  • 2,998
  • 3
  • 22
  • 31
  • 1
    beware pre/post build events especially in environments where you are working with multiple devs and/or automated build. They can be big gotchas. – GrayWizardx Mar 15 '10 at 07:12
-3

You can keep it elsewhere and still link it. In the reference properties, set the "Copy local" to false and set the path accordingly. This will work. If the external DLLS are suppose to change version, you can set "Specific version" to false to be able to link to any version.

Kangkan
  • 15,267
  • 10
  • 70
  • 113