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

How to programmatically update project references in a Visual Studio project

我的文件结构如下:

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

需要在 a.csproj 上工作的开发人员将在 dev 中创建一个 b运行ch,他们将从那里开始工作。我们的项目需要在二进制文件目录中引用 binary1.dll。

如果引用是相对路径(Visual Studio 默认值),则该路径将不适用于主干中的项目和开发人员的 b运行ch 中的项目。

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

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

这很完美,但我想帮助开发人员更轻松地添加引用,所以我编写了一个程序,将指向 binary1.dll 的相对路径(例如,从 dev b运行ch a.csproj 它会将路径 ../../binaries/binary1.dll 更改为 $(MY_ENV_VAR)\binary1.dll) 但我还没有弄清楚如何让它工作。

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

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

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

我一直在尝试的其他一些想法是创建一个新项目来更新第二个项目,并且它们之间有一个 link,但这会重复项目的数量。

我也可以只改变树干的深度,但这只会隐藏问题并不能真正解决问题。当开发人员在他们的开发 b运行ch 中创建一个 b运行ch 来处理不同的功能或错误时,我又遇到了同样的问题。

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

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

我找到了一种方法来做到这一点。问题是 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>