Search code examples
c#visual-studio-2013relative-pathbuildconfigurationdll-reference

Build a project with relative path to dll


I have created a c# project in it I reference system.windows.interactivity.dll.
What I'm wondering is how to set the project up so that when I build the *.exe I get this sort of structure:

Program Folder
    program.exe
Libraries Folder
    system.windows.interactivity.dll

I have tried a little bit of experimentation by placing a "Libraries" folder under the solution folder, so that it is at the same level as the project folder. This gives a relative path in the csproj file of "..\Libraries\system.windows.interactivity.dll", however this cannot be the solution as when I compile it copies the dll into the debug folder with the exe and it keeps this 'same level' path structure.

How can I alter things so that it places and references the dll in another directory?

[Update]
So I have modified the following in my project:
1: Changed the 'Copy Local' property on reference system.windows.interactivity.dll to False.
2: Added the following code to the csproj file to check if the Libraries folder exists above the Output directory, if not create and then copy over the dll.

  <Target Name="BeforeBuild">
    <MakeDir Directories="$(OutDir)..\Libraries" 
             Condition="!Exists('$(OutDir)..\Libraries')" />
    <Copy SourceFiles="..\Libraries\System.Windows.Interactivity.dll" 
          DestinationFolder="$(OutDir)..\Libraries" 
          ContinueOnError="True" />
  </Target>

3. Add the following code to App.config to add another location for the app to search for the dll.

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

My Findings:
Upon building the app, all files are exactly where I want them, as in the structure in my original post. When I try to run the exe from the output directory it cannot find the dll.

[/Update]


Solution

  • Using app.config you can tell .NET to probe subdirectories to search for assemblies (.NET needs to know how to find the DLLs when the application runs when they're in a non-standard location):

    https://msdn.microsoft.com/en-us/library/823z9h8w(v=vs.110).aspx

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

    You could modify the .csproj file to do a BeforeBuild/AfterBuild task and copy the dll to a subdirectory. However if you really only want this structure for deployment, it would probably be easier to include that as part of the package/installer logic instead of the direct build logic. Typically it's much easier to just let the compiler pick the output destination for your DLLs.

    Here's an example of how you'd create the BeforeBuild copy task:

    Copy all files and folders using msbuild

    You can tell Visual Studio not to copy the DLL to the output folder by setting "Copy Local" to false on the reference.