假设我有一个包含
c:\workdir\project\wonder\subproj\..\..\common
我想减少/简化它
c:\workdir\project\common
此外,我还希望能够从当前目录获取相对路径或指定。
使用相同的起始属性并将当前工作目录设置为
c:\workdir\project\wonder
我希望它减少到
..\common
假设我有一个包含
c:\workdir\project\wonder\subproj\..\..\common
我想减少/简化它
c:\workdir\project\common
此外,我还希望能够从当前目录获取相对路径或指定。
使用相同的起始属性并将当前工作目录设置为
c:\workdir\project\wonder
我希望它减少到
..\common
第一部分(解析路径中的“ .. ”)相对简单,您可以仅使用属性函数来完成此操作:
<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