Visual Studio中的Prebuild事件将$(SolutionDir)替换为*Undefined*

58
我相信这个问题已经被记录在这里 现在移动到这里,看起来可能是Visual Studio中的一个错误,但我想知道是否有人知道解决方法。
基本上,在预构建事件中,除其他事项外,我有以下两行代码。
"C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" /p:configuration=Release;platform=x86 /t:rebuild "$(SolutionDir)Folder1\Project1.csproj"

"C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" /p:configuration=Release;platform=x86 /t:rebuild "$(SolutionDir)Folder2\Folder3\Project2.csproj" 

第一个成功了,而另一个失败了,显示出The command ""C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" /p:configuration=Release;platform=x86 /t:rebuild "*Undefined*Folder2\Folder3\Project2.csproj"" exited with code 1.

编辑:
找到问题所在,是由于其中一个具有相同预构建行的其他项目失败,因为MSBuild本身不知道宏。


作者FYI:链接已损坏(VS反馈)。 - yzorg
7个回答

101

我将其修复为将所有的$(SolutionDir)替换为$(ProjectDir)..\

这是因为MSBuild独立运行每个项目,而不是整个解决方案。在VS2010中可以正常工作,但在构建服务器上不行。


12
2015 年了,我简直无法相信这仍然是个问题。 - drzaus
14
2017年时这仍然是一个问题,这个答案修正了这个问题。 - James Blake
9
2021年仍存在这个问题。 - Mauro Valvano
7
我来发表一下意见,2022年还存在这个问题! - Issung
5
你知道吗...2023年仍然存在问题。;) - Göran
显示剩余4条评论

35

花费了很多时间寻找解决此问题的完美方案。使用Directory.Build.props

在你的sln文件夹位置创建一个名为Directory.Build.props的文件,并将以下代码放入其中:

<Project>
 <PropertyGroup>
    <SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
 </PropertyGroup>
</Project>

这个文件会被自动地在你所有的 csproj 文件中使用,并定义了 (SolutionDir) 属性。


2
在我的VS 2022中有效。 - Nikhil Agrawal
1
这是.NET Core项目的更清晰的方法。在VS 2022中,这对我起作用了。 - Patrick
1
这是一个不错的方法,特别是当您有一个包含多个单独构建项目的解决方案时 - 我会这样做:RUN dotnet publish --no-restore --configuration Release --output /api src/My.Comany/My.Company.Api.csproj,然后对于同一构建中的其他csproj也会使用类似的命令。 - xandermonkey
使用 .Net 8,并且这在命令行中对我有效。 - Jason Foglia

1
Allan的回答是正确的,但在VS 2019 16.7.2中,将所有的$(SolutionDir)替换为$(ProjectDir)..\对我没有起作用。 $(ProjectDir)..\被解析为实际的ProjectDir加上"..\",而不是向上移动一个目录。
相反,我将所有的$(SolutionDir)替换为$(ProjectDir)\..,这样就可以正确地向上移动一个目录了。

1

Allan的回答非常正确,但是如果你想要移动到ProjectDir的父目录,或者$(ProjectDir)..\的输出将会是一个string,你需要在msbuild中执行'进入父目录'操作
以下是实现方法:

<PropertyGroup>
  <TrimmedDir>$([System.IO.Path]::GetDirectoryName($(ProjectDir)))</TrimmedDir>
</PropertyGroup>

这段代码将ProjectDir的父目录路径设置为TrimmedDir变量。使用[System.IO.Path]::GetDirectoryName()执行此操作。

0
我遇到了同样的问题,在我的情况下,Azure DevOps的构建流水线指向了project.csproj文件,而不是project.sln文件。
这导致$(SolutionDir)未定义。
花了一些时间才弄清楚;想分享一下,以防其他人遇到同样的问题。

0

您没有说明这是发生在许多项目中还是只有一个或两个项目中。

如果只是在一个或两个项目中出现,一个临时的解决方法可能是将 $(SolutionDir) 替换为 Folder2 所在的显式路径。例如,类似于以下内容:

"C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" /p:configuration=Release;platform=x86 /t:rebuild "C:\AllSolutions\ExampleSolutions\Folder2\Folder3\Project2.csproj"

但要使用正确的项目路径。


0

如果您只使用MSBuild,而SolutionDir在某些项目中有效但在其他项目中无效,则有可能是因为SolutionDir已经在工作项目的.csproj文件中定义了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接