我正在Visual Studio中整理一个模板项目,供我的部门使用。项目需要引用存储在 TFS 中其他位置的一些公共库。问题是该模板可能会在各种位置使用,并且我在尝试可靠地设置 HintPath 来处理所有位置时遇到麻烦。
模板化项目需要能够在本地和 TFS 中找到公共库,以便在生成中使用。目前,在我们现有的应用程序中,引用如下所示:
<Reference Include="Company.Common">
<SpecificVersion>False</SpecificVersion>
<HintPath>............Core ComponentsLibrariesCompany.CommonLatestCompany.Common.dll</HintPath>
</Reference>
但是,需要遍历才能到达根部的父母数量可能会有所不同。
而不是为 .. 设置 50 个条件路径。/, ../../, ../../../,等等,我的第一个想法是设置一个绝对引用。工作文件夹在我们的组织中是标准化的,因此在本地,参考始终可以在 C:\Projects\Core Components\...
但这不适用于服务器构建。所以我想我需要某种可以达到 $/的环境变量。我正在想象这样的东西:
<Choose>
<When Condition="Exists('C:Projects')">
<ItemGroup>
<Reference Include="Company.Common">
<HintPath>C:ProjectsCore ComponentsLibrariesCompany.CommonLatestCompany.Common.dll</HintPath>
</Reference>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Company.Common">
<HintPath>$(TFSRoot)Core ComponentsLibrariesCompany.CommonLatestCompany.Common.dll</HintPath>
</Reference>
</ItemGroup>
</Otherwise>
</Choose>
但是我不知道如何做到这一点。
更新:
最终,我们确实建立了一个内部Nuget服务器。我建议任何有同样困境的人解决任何阻碍您设置 Nuget 的繁文缛节。我们花了 3 年时间忍受这种笨拙的做事方式,总有一些新的皱纹需要人工干预。
对于如何解决这个问题,我有两个建议。 好方法和更好的方法。
好的方法(也是最常见的)是,如果你有一些共享库X,并且你需要在应用程序A、B和C中使用它。 在项目 A 下,您将有一个 lib 文件夹,您可以在其中签入 X.dll 的副本。 项目 B 有自己的 lib 文件夹和自己的 X.dll副本(不一定与 A 依赖的 X 版本相同)。等等。 在这个模型中,由 A/B/C 的维护者选择何时拉入新版本的 X 并更新他们的 lib 文件夹。
更好的方法是使用 NuGet(包管理器)。 Project X 会将每个新版本发布到 NuGet 源的某个位置,A/B/C 将订阅该 NuGet 源,Visual Studio/TFS Build 将根据需要自动下载 NuGet 包。 这也提供了一些额外的灵活性,因为项目 A 可以说"我依赖 X ver 3.2",也可以说"我依赖最新版本的 X",NuGet 完成这项工作。
我能想到两种方法来实现您正在寻找的目标。一种是使用内置的 VS 宏,另一种是在生成服务器上创建一个环境变量,然后在项目或 MSBuild 文件中引用它:
<Reference Include="EntityFramework.SqlServer">
<HintPath>....packagesEntityFramework.6.1.2libnet45EntityFramework.SqlServer.dll</HintPath>
<HintPath>$(SolutionDir)packagesEntityFramework.6.1.2libnet45EntityFramework.SqlServer.dll</HintPath>
<HintPath>$(ENVIRONMENT_VARIABLE)packagesEntityFramework.6.1.2libnet45EntityFramework.SqlServer.dll</HintPath>
</Reference>