1

I have a Visual Studio 2010 C# project which creates an .exe and this project is using some 3rd party class library. My project is located in: /MyFramWork/tests/test1 3rd party library is located at: /MyFrameWork/bin/utils/

I am adding the reference to the library by using References->Add Reference->Browse. I can see that in the project file all is fine: ....\bin\utils\log4net.dll False

I would like to reference the 3rd party library without using the option "Copy Local". However if I don't use the option, the library is not found and I get an exception.

My question is: Is there a way to specify that the 3rd party library should be found at ....\bin\utils. It seems that when the .exe gets build the information from the .csproj gets lost.

yoozer8
  • 7,361
  • 7
  • 58
  • 93
Potzon
  • 33
  • 1
  • 5
  • 6
    Why do you not want to use copy local? – thecoop Apr 07 '12 at 15:23
  • 1
    You can invoke DLL Hell by writing an event handler for the AppDomain.CurrentDomain.AssemblyResolve event. Assign it in the Main() method. – Hans Passant Apr 07 '12 at 15:25
  • I have the same issue - 3rd party .NET assemblies are not registered in GAC. We want to extend the 3rd party application with a web service installed in a different directory. I have no option but to copy the files to the web service BIN directory. If I upgrade the 3rd party software I have to also update the web service. Bummer.... If I could only refer to the 3rd party .NET dll's where they reside naturally. This is where WIN32 dll's have an advantage. – barrypicker Feb 21 '13 at 21:26

4 Answers4

2

By default, .NET apps look for their dependencies in only two places: the EXE directory, and the GAC (Global Assembly Cache).

You have three choices:

  • You can make sure the dependency gets copied into the same directory as your EXE (this is what Copy Local does). This is the best choice most of the time, which is why it's the default when you reference an assembly that's not already in the GAC.
  • You can install your dependency into the GAC using gacutil. This might be a good choice if your dependency isn't going to change, is going to be in a different location on every development machine (i.e. if relative paths won't work well), and if you want to use it from many different projects. But it's a major pain if the dependency is still under active development and changing frequently. You'll also need to make sure to put the DLL into the GAC on every computer you deploy your app to.
  • You can customize the dependency-loading behavior so it looks in other places, as Hans noted in his comment. This is an advanced option and comes with a whole new set of headaches.

Normally, you would just use Copy Local; it's a very sensible default. You should need a fairly compelling reason to do anything different.

Joe White
  • 94,807
  • 60
  • 220
  • 330
  • I don't want to use copy local because I want all the .exes and .dlls which I create to be also located inside the /MyFrameWork/bin/ directory. For example this .exe when build is then copied inside /MyFrameWork/bin/tests. But i can feel that this is not supposed to happen? I just want to tell my .exe that it should look for the .dll at ../../bin/utils. Maybe there is not way? Also I don't want to use GAC because I want when users get the files from source control to be able immediately start using them. – Potzon Apr 07 '12 at 16:07
  • I saw an article: http://support.microsoft.com/kb/837908 It seems that I can use an application configuration (.config) file with the tags. I will write if this is what I am looking for. – Potzon Apr 07 '12 at 16:24
  • Dude, if you want to build all your EXEs and DLLs into one directory, then do it that way in the first place -- go to project properties > Build tab and specify the output directory. Then you don't need to worry about whether it's "Copy Local" or not, because everything's already in one directory. – Joe White Apr 07 '12 at 17:25
  • Yes, but I was hoping to keep some kind of directory structure in this /bin. For example /bin/devices; /bin/tests; /bin/utils and so on... However if I add sub-directories in /bin I need some way of referencing the assemblies. – Potzon Apr 10 '12 at 22:37
  • I am marking this as answer. My solution is a bit different but still decided to put all the libraries at one place. What I did is: Binaries are hold in: /framework/bin/lib/ Tests are hold in: /framework/bin/tests/ I am using DEVPATH environmental variable to point to /framework/bin/lib/. This way when the tests are run they can find the libraries in the /lib directory. – Potzon Apr 16 '12 at 18:54
1

Use the <probing> element to specify where the CLR should search for your assemblies. The only restriction is that the assemblies must be located in subdirectories of your application's base directory.

For example, if your application base directory is C:\MyFramework, then you could have your assemblies in C:\MyFramework\bin.

Have a look at this article to learn how the CLR searches for assemblies.

Bernard
  • 7,908
  • 2
  • 36
  • 33
  • The problem is that my application base directory is not C:\MyFramework. It is more like C:\MyFramework\tests\test1 or C:\MyFramework\bin\tests\. But I understand what you mean. It seems that what I want to do is not so straightforward. I was reading that I can use an application configuration (.config) file with the tags, but this is too much overhead as it requires strong-named assemblies. – Potzon Apr 07 '12 at 17:36
  • I wouldn't use strongly-named assemblies just for this purpose either. – Bernard Apr 08 '12 at 00:42
  • Great answer. i saw it in several software – Siarhei Kuchuk Apr 08 '12 at 16:36
0

If you need to load assemblies from custom locations, you could try the Assembly.LoadFile Method.

The following links may be useful:

C# - Correct Way to Load Assembly, Find Class and Call Run() Method

http://www.csharp-examples.net/reflection-examples/

Community
  • 1
  • 1
Anil Mathew
  • 2,590
  • 1
  • 15
  • 15
0

It's me Potzon. I am still investigating this incredibly silly problem.

I have been hoping for some elegant solution. I am about to build fairly large framework with lots of assemblies which would be placed inside /Framework/bin/. However I wanted to have some directory structure inside the the directory, for example /bin/utils, /bin/test, /bin/devices/ and so on.

One possible solution that I have found is to define environmental variable DEVPATH (see here http://msdn.microsoft.com/en-us/library/cskzh7h6.aspx) but it turns out that .net4 is not using this variable when an assembly is run independently (outside the visual studio), or at least this is the case for me - I can't make it work.

It seems that the solution to put all the assemblies inside the /bin directory without using sub-directories is the best. I think I will give up and just do it this way.