Ответ 1
Способ, которым MSBuild работает при обработке файлов, состоит в том, чтобы читать все файлы и создавать в памяти все эти файлы. Все это происходит до выполнения любой цели. Из-за этого, когда цель выполняется, у нее нет понятия, в каком файле она содержалась. В основном вы не сможете использовать относительные пути внутри файлов .targets. Способ справиться с этой ситуацией - обеспечить, чтобы ваши отдаленные файлы .proj(или любое другое расширение, которое вы используете) объявили известное свойство, которое использует ваш файл .targets, чтобы разрешить полный путь к общим файлам.
Например
Sample.targets
<Project ...>
<Target Name="ExecTool">
<Exec Command="$(YourToolPath)tool.exe" />
</Target>
</Project>
Build.proj
<Project ...>
<PropertyGroup>
<YourToolPath>$(MSBuildProjectDirectory)\..\</YourToolPath>
</PropertyGroup>
<Import Project="..\..\..\Sample.targets"/>
</Project>
В соответствующей заметке я обсуждал вопрос о проверке таких "общих" свойств в моем блоге некоторое время назад на Элементы многоразовых скриптов MSBuild: проверка.
Только MSBuild 4.0
Если вы используете MSBuild 4.0, то есть Visual Studio 2010/.NET 4.0 (который может также ориентироваться на .NET 2.0/3.0/3.5). Затем у вас есть эти свойства, которые могут быть использованы для этой конкретной цели:
-
MSBuildThisFile
-
MSBuildThisFileDirectory
-
MSBuildThisFileDirectoryNoRoot