我相信这个问题已记录在这里移到这里,看起来它可能是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 本身不知道宏。
我通过将所有
$(SolutionDir)
替换为 $(ProjectDir)..\
来修复此问题。
这是由于 MSBuild 独立运行每个项目,因此不是解决方案。它在 VS2010 中工作正常,但在构建服务器上不行。
浪费了很多时间来找到这个问题的完美解决方案。使用 Directory.Build.props.
在您的
sln
位置文件夹中创建一个名为 Directory.Build.props
的文件并将以下代码放入其中:
<Project>
<PropertyGroup>
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
</PropertyGroup>
</Project>
此文件将被您的所有
csproj
文件自动选取,并定义 (SolutionDir)
属性。
Allan的答案完全正确,但是如果你想移动到
ProjectDir
的父目录,或者$(ProjectDir)..\
输出将是string
,你需要执行'转到父目录msbuild中的目录'操作.<PropertyGroup>
<TrimmedDir>$([System.IO.Path]::GetDirectoryName($(ProjectDir)))</TrimmedDir>
</PropertyGroup>
此代码会将
ProjectDir
的父目录路径设置为 TrimmedDir
变量。 [System.IO.Path]::GetDirectoryName()
执行此操作。
Allan 的答案有正确的想法,但是用
$(SolutionDir)
替换所有 $(ProjectDir)..\
对我来说在 VS 2019 16.7.2 中不起作用。
$(ProjectDir)..\
评估为实际 ProjectDir
,并附加“..\”,而不是向上一级目录。
相反,我将所有
$(SolutionDir)
替换为 $(ProjectDir)\..
,这正确地上升了一个目录。
您没有具体说明这种情况是在许多项目中发生还是仅在一两个项目中发生。
如果仅在一两个项目中,临时解决方法可能是将 $(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"
但要为您的项目提供正确的路径。
如果您仅使用 MSBuild 且 SolutionDir 适用于某些项目,但不适用于其他项目,则 SolutionDir 可能已在工作项目的 .csproj 文件中的某处定义。
我遇到了同样的问题,在我的例子中,Azure DevOps 构建管道指向project.csproj 文件,而不是project.sln 文件。
这导致 $(SolutionDir) 未定义
花点时间找出答案;我想我会分享以防其他人遇到同样的问题。