问题
I'm packaging example code for an SDK distribution. In the distribution, the relative path from code to the SDK assemblies is different from the build machine. For example:
Distribution
csharp/bin/assembly.dll
example/ex1/ex1.csproj
Build Machine
foo/sdk/csharp/bin/assembly.dll
bar/baz/quux/ex1/ex1.csproj
Assume that I can't move anything. Is there a way I can instruct ex1.csproj
to look in both
../../csharp/bin/
and ../../../../foo/sdk/csharp/bin/
for assembly.dll
?
In C++ I'd put the dependency path in a standalone property sheet and distribute a different version with the SDK. But C# doesn't have property sheets, and I don't want to maintain two versions of the full project.
I've seen this question which states that I can't use multiple <HintPath>
tags, so I'm looking for another way to approximate the same behavior.
回答1:
The simplest way since only ONE HintPath can be used is to use the all-so-nice Condition attribute like this:
<Reference Include="TheAssembly">
<HintPath Condition="Exists('..\My\Assembly\Path')">..\My\Assembly\Path\TheAssembly.dll</HintPath>
<HintPath Condition="Exists('..\..\My\Assembly\Path')">..\..\My\Assembly\Path\TheAssembly.dll</HintPath>
<HintPath Condition="Exists('..\..\..\My\Assembly\Path')">..\..\..\My\Assembly\Path\TheAssembly.dll</HintPath>
<HintPath Condition="Exists('..\..\..\..\My\Assembly\Path')">..\..\..\..\My\Assembly\Path\TheAssembly.dll</HintPath>
<HintPath Condition="Exists('..\..\..\..\..\My\Assembly\Path')">..\..\..\..\..\My\Assembly\Path\TheAssembly.dll</HintPath>
<HintPath Condition="Exists('..\..\..\..\..\..\My\Assembly\Path')">..\..\..\..\..\..\My\Assembly\Path\TheAssembly.dll</HintPath>
<HintPath Condition="Exists('..\..\..\..\..\..\..\My\Assembly\Path')">..\..\..\..\..\..\..\My\Assembly\Path\TheAssembly.dll</HintPath>
etc...
</Reference>
So the answer to the question would be this:
<Reference Include="assembly">
<HintPath Condition="Exists('..\..\csharp\bin')">..\..\csharp\bin\assembly.dll</HintPath>
<HintPath Condition="Exists('..\..\..\..\foo\sdk\csharp\bin')">..\..\..\..\foo\sdk\csharp\bin\assembly.dll</HintPath>
</Reference>
If multiple conditions matches, the last one will be used.
回答2:
I found a hacky solution that works for my case, where the parent directory is guaranteed to be different somewhere up the tree:
<Choose>
<When Condition="Exists('$(MSBuildProjectDirectory)\..\..\example')">
<ItemGroup>
<Reference Include="Assembly ...">
<HintPath>..\..\csharp\bin\assembly.dll</HintPath>
</Reference>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Assembly ...">
<HintPath>..\..\..\..\..\foo\sdk\csharp\bin\assembly.dll</HintPath>
</Reference>
</ItemGroup>
</Otherwise>
</Choose>
回答3:
Add the secondary path as follows to the general property group. in the csproj file
<PropertyGroup>
<ReferencePath>..\..\..\..\..\foo\sdk\csharp\bin\</ReferencePath>
...
</PropertyGroup>
The ReferencePath
property is intended to be specified when executing MsBuild, but it will work fine like this.
回答4:
I am using this solution without any problem:
<Reference Include="log4net">
<HintPath>
$(SolutionDir)packages\log4net.2.0.8\lib\net45-full\log4net.dll
</HintPath>
</Reference>
Got it from here: use hint paths relative answer from LeonidVasilyev
回答5:
You could subst the /csharp/bin
folder into a drive (differently on each machine), for example X:
and then reference X:\
or X:\bin
on both machines, as the path will now be the same.
回答6:
Simply add the build server location of the DLLs as a Reference path on the project. Seems to do the trick nicely and is very simple. Works only if you know the build server's folder of the DLLs.
来源:https://stackoverflow.com/questions/15666618/csproj-multiple-hint-paths-for-an-assembly