如何以编程方式更新Visual Studio项目中的项目引用

时间:2015-01-22 18:01:00

标签: c# visual-studio-2013 msbuild

我有如下文件结构:

- binaries
   - binary1.dll
- dev
   - <developer-name>
      - a.csproj
-trunk
    - a.csproj

需要使用a.csproj的开发人员将在dev中创建一个分支,他们将从那里开始工作。我们的项目需要在二进制目录中引用binary1.dll。

如果引用是相对路径(Visual Studio默认值),则该路径对于trunk中的项目和开发人员分支中的项目都不起作用。

要解决这个问题,我想到了创建一个环境变量并在项目文件中使用它:

<Reference Include="binary1">
   <HintPath>$(MY_ENV_VAR)\binary1.dll</HintPath>
</Reference>

这很好用,但我想帮助开发人员更容易地添加引用,所以我编写了一个程序,它将转换指向binary1.dll的相对路径(例如,从dev分支a.csproj它将改变路径../../binaries/binary1.dll$(MY_ENV_VAR)\binary1.dll)但我还没弄清楚如何让它发挥作用。

如果我使用预构建事件,项目已经加载到内存中,并且事件返回错误,因为它无法写入项目文件。

然后我意识到我可以覆盖MSBuild目标,并尝试使用目标:BeforeCompilerAfterCompilerBeforeBuildAfterBuild并且在所有目标中项目都是已经锁定了。

然后我遇到this answer我修改了我的代码以调用GenerateApplicationManifest目标中的可执行文件,但是那个似乎根本没有调用可执行文件。

我一直在玩的其他一些想法是创建一个新项目来更新第二个项目并在它们之间建立链接,但这会重复项目数量。

我也可以只改变行李箱的深度,但这只能隐藏问题,并没有真正解决它。当开发人员在他们的dev分支中创建一个分支来处理不同的功能或错误时,我会再次遇到同样的问题。

可能还有另一个功能以更优雅的方式解决了这个问题,但我还没有找到任何东西。

所以我的问题是:如何获得MS Build或预构建事件来修改CS项目?

1 个答案:

答案 0 :(得分:0)

我找到了一种方法来做到这一点。问题是Visual Studio进程本身正在锁定项目,但Visual Studio可能会覆盖该文件。我最终修改了a.csproj以包含:

<Target Name="BeforeBuild">
    <Exec Command="UpdateReferences.exe" /> <!-- This creates the $(ProjectPath).new file -->
    <Move SourceFiles="$(ProjectPath).new" DestinationFiles="$(ProjectPath)" />
  </Target>