Можно ли с помощью MSBuild 4.0 «упростить» свойство, содержащее путь? - PullRequest
2 голосов
/ 09 сентября 2011

Предположим, у меня есть свойство, содержащее

c:\workdir\project\wonder\subproj\..\..\common

и я хочу уменьшить / упростить его до

c:\workdir\project\common

Кроме того, я также хотел бы иметь возможность получить относительный путь из текущего каталога или указанного.

Использование того же начального свойства и текущий рабочий каталог, установленный на

c:\workdir\project\wonder

Я хочу уменьшить его до

..\common

1 Ответ

4 голосов
/ 26 октября 2011

Первая часть (разрешение ' .. ' в пути) относительно проста, вы можете сделать это, используя только функции свойств :

<PropertyGroup>
  <Folder>c:\workdir\project\wonder\subproj\..\..\common</Folder>
</PropertyGroup>
<Message Text="Folder $(Folder)" />     
<Message Text="Shortened path $([System.IO.Path]::GetFullPath($(Folder)))" />

Выход:

Folder c:\workdir\project\wonder\subproj\..\..\common
Shortened path c:\workdir\project\common

Вторая часть - сокращение одного пути относительно другого - требует использования магической функции Uri.MakeRelativeUri() и ее обертывания внутри встроенного задания (или внешней библиотеки заданий) , Объявите свою задачу:

<UsingTask TaskName="RelativePath" TaskFactory="CodeTaskFactory"
  AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
 <ParameterGroup>
    <Target Required="true" />
    <BaseDirectory Required="true" />
    <Result Output="true" />
  </ParameterGroup>
  <Task>
    <Code Type="Fragment" Language="cs"><![CDATA[
Uri fromUri = new Uri(new DirectoryInfo(BaseDirectory).FullName
  + Path.DirectorySeparatorChar);
Uri toUri = new Uri(new DirectoryInfo(Target).FullName);
Uri relativeUri = fromUri.MakeRelativeUri(toUri);
Result = relativeUri.ToString().Replace('/', Path.DirectorySeparatorChar);
]]></Code>
    </Task>
</UsingTask>

Затем используйте его следующим образом:

<PropertyGroup>
  <Folder>c:\workdir\project\wonder\subproj\..\..\common</Folder>
  <WorkingDir>c:\workdir\project\wonder</WorkingDir>
</PropertyGroup>
<Message Text="Folder $(Folder)" />
<Message Text="Base directory $(WorkingDir)" />
<RelativePath Target="$(Folder)" BaseDirectory="$(WorkingDir)">
  <Output PropertyName="Relative" TaskParameter="Result"/>
</RelativePath>
<Message Text="Relative path $(Relative)" />

Выход:

Folder c:\workdir\project\wonder\subproj\..\..\common
Base directory c:\workdir\project\wonder
Relative path ..\common
...