Событие Prebuild в Visual Studio, заменяющее $(SolutionDir) на * Undefined *

Я считаю, что проблема документирована здесь переехала сюда и похоже, что это может быть ошибка в 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 не знает о макросах.

Ответ 1

Я исправил это, заменив все $(SolutionDir) на $(ProjectDir)..\.

Это было связано с тем, что MSBuild выполнял каждый проект независимо, и, следовательно, не являлось решением. Он хорошо работал в VS2010, но не на сервере сборки.

Ответ 2

Вы не указываете, происходит ли это для многих проектов или только один или два.

Если это только в одном или двух проектах, временным обходным решением может быть замена $(SolutionDir) на явный путь, в котором находится папка 2. Например, что-то вроде:

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

но с правильным путем для вашего проекта.

Ответ 3

Ответ Аллана находится на правильном пути, но если вы хотите перейти в родительский каталог ProjectDir, или ProjectDir $(ProjectDir)..\ будет string, вам нужно выполнить 'перейти в родительский каталог' операция в msbuild.
Вот как вы можете добиться этого:

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

Этот код установит путь родительского каталога ProjectDir в переменную TrimmedDir. [System.IO.Path]::GetDirectoryName() выполняет эту операцию.