11

I am trying to make a simple c# program using Growl C# API.

I tried to compile my program in two different ways:

1) I kept my .dll file in the same directory as my .cs file. Than I ran

csc /r:Growl.Connector.dll,Growl.CoreLibrary.dll /out:test.exe *.cs

It compiled fine and also ran fine.

2) Now I have created a directory inside my current working directory named growl and kept all my .dll references there.

Now when I try to compile it using the below command

csc /r:"D:\Modified\Growl_NET_Connector_SDK\libraries\growl\Growl.Connector.dll","D:
\Modified\Growl_NET_Connector_SDK\libraries\growl\Growl.CoreLibrary.dll" /out:test.exe *.cs

It compiled fine but when I tried to run it the below mentioned exception occurred.

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Growl.Connector, Version=2.0.0.0, Culture=n
eutral, PublicKeyToken=980c2339411be384' or one of its dependencies. The system cannot find the file specified.
 at GrowlNotification.Program.Main(String[] args)

So, my question is what is the correct way to reference .dll file in csc when files are in an external folder.

Here is the directory structure for 2nd case.

RanRag
  • 48,359
  • 38
  • 114
  • 167

3 Answers3

11

So, my question is what is the correct way to reference .dll file in csc when files are in an external folder.

You're already referencing them at build time. You just need to make them available at execution time too, but copying them into the same directory as the executable, when you want to run it.

You could also investigate using the Global Assembly Cache if these are signed assemblies, but personally I'd stick with just keeping the executable with the libraries on which it depends.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • So there is no way I can keep the `.dll` file in an external folder and run my `.exe` just by `double-clicking` it. As I understand from your answer that `.dll` file should be present in the same folder as .exe at run time. – RanRag May 23 '12 at 15:17
  • @Noob: I believe it could be in a *subdirectory* if you add an app.config file to specify private bin path probing, but that's just adding even more complexity. It's all *much* simpler if everything's in the same directory. – Jon Skeet May 23 '12 at 15:22
  • @JonSkeet What if the assembly is signed, and already copied in the GAC? – Ramy Al Zuhouri Aug 22 '14 at 22:06
  • @RamyAlZuhouri: Then it should just be fine. – Jon Skeet Aug 22 '14 at 23:10
3

You can add these using the /lib and /reference command-line switches while compiling.

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

But (Quote from the article)

An alternative to using /lib is to copy into the working directory any required assemblies; this will allow you to simply pass the assembly name to /reference. You can then delete the assemblies from the working directory. Since the path to the dependent assembly is not specified in the assembly manifest, the application can be started on the target computer and will find and use the assembly in the global assembly cache.

Because the compiler can reference the assembly does not imply the common language runtime will be able to find and load the assembly at runtime. See How the Runtime Locates Assemblies for details on how the runtime searches for referenced assemblies.

so Jon Skeet's answer is better. (I'm just adding this to provide more info than I could in a comment, not as an answer. Jon's answer is the best IMO)

David
  • 72,686
  • 18
  • 132
  • 173
1

You can create symlinks to the assemblies in your libraries folder so you would only need to keep them updated in one location.

Tuan
  • 5,382
  • 1
  • 22
  • 17