2011-09-08 4 views
2

Предположим, что у меня есть свойство, содержащееИспользуя MSBuild 4.0, можно ли «упростить» свойство, содержащее путь?

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

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

c:\workdir\project\common 

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

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

c:\workdir\project\wonder 

Я хочу, чтобы он уменьшил до

..\common 
+0

Вы можете сделать это с помощью пользовательских 'UsingTask' сценария: HTTP: // MSDN. microsoft.com/en-us/library/t41tzex2.aspx и немного C#. – skolima

ответ

4

Первая часть (разрешения «..» в пути) относительно просто, вы можете сделать это, используя только property functions:

<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() и обертывания его внутри inline task (или внешней библиотеки задач). Объявить свою задачу:

<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 
Смежные вопросы