在给定相对路径时,如何让MSBUILD计算并打印完整路径?
如何让MSBuild在在给定相对路径时,如何让MSBUILD计算并打印完整路径?,msbuild,relative-path,absolute-path,Msbuild,Relative Path,Absolute Path,如何让MSBuild在任务中计算并打印给定相对路径的绝对路径 地产集团 <Source_Dir>..\..\..\Public\Server\</Source_Dir> <Program_Dir>c:\Program Files (x86)\Program\</Program_Dir> 。\..\..\Public\Server\ c:\Program Files(x86)\Program\ 任务 <Message Importance=
任务中计算并打印给定相对路径的绝对路径
地产集团
<Source_Dir>..\..\..\Public\Server\</Source_Dir>
<Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
。\..\..\Public\Server\
c:\Program Files(x86)\Program\
任务
<Message Importance="low" Text="Copying '$(Source_Dir.FullPath)' to '$(Program_Dir)'" />
输出
正在将“”复制到c:\Program Files(x86)\Program\s
Wayne说的没错,众所周知的元数据不适用于属性——只适用于项。使用诸如“MSBuildProjectDirectory”之类的属性可以工作,但我不知道有一种内置的方法来解析完整路径 另一种选择是编写一个简单的自定义任务,该任务将采用相对路径并输出完全解析的路径。它看起来像这样:
public class ResolveRelativePath : Task
{
[Required]
public string RelativePath { get; set; }
[Output]
public string FullPath { get; private set; }
public override bool Execute()
{
try
{
DirectoryInfo dirInfo = new DirectoryInfo(RelativePath);
FullPath = dirInfo.FullName;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
}
return !Log.HasLoggedErrors;
}
}
<PropertyGroup>
<Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
</PropertyGroup>
<ItemGroup>
<Source_Dir Include="..\Desktop"/>
</ItemGroup>
<Target Name="BuildAll">
<Message Text="Copying '%(Source_Dir.FullPath)' to '$(Program_Dir)'" />
</Target>
您的MSBuild行将类似于:
<PropertyGroup>
<TaskAssembly>D:\BuildTasks\Build.Tasks.dll</TaskAssembly>
<Source_Dir>..\..\..\Public\Server\</Source_Dir>
<Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
</PropertyGroup>
<UsingTask AssemblyFile="$(TaskAssembly)" TaskName="ResolveRelativePath" />
<Target Name="Default">
<ResolveRelativePath RelativePath="$(Source_Dir)">
<Output TaskParameter="FullPath" PropertyName="_FullPath" />
</ResolveRelativePath>
<Message Importance="low" Text="Copying '$(_FullPath)' to '$(Program_Dir)'" />
</Target>
D:\BuildTasks\Build.Tasks.dll
..\..\..\Public\Server\
c:\Program Files(x86)\Program\
您试图通过属性访问项元数据属性,这是不可能的。您要做的是这样的:
public class ResolveRelativePath : Task
{
[Required]
public string RelativePath { get; set; }
[Output]
public string FullPath { get; private set; }
public override bool Execute()
{
try
{
DirectoryInfo dirInfo = new DirectoryInfo(RelativePath);
FullPath = dirInfo.FullName;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
}
return !Log.HasLoggedErrors;
}
}
<PropertyGroup>
<Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
</PropertyGroup>
<ItemGroup>
<Source_Dir Include="..\Desktop"/>
</ItemGroup>
<Target Name="BuildAll">
<Message Text="Copying '%(Source_Dir.FullPath)' to '$(Program_Dir)'" />
</Target>
(脚本是从“我的文档”文件夹运行的,因此..\Desktop是访问“我的桌面”的正确相对路径。)
在您的情况下,将“源目录”项目中的“.\Desktop”替换为“…..\Public\Server”,您应该已完成所有设置。如果需要将属性转换为项目,您有两个选项。对于msbuild 2,您可以使用CreateItem任务
<Target Name='Build'>
<CreateItem Include='$(Source_Dir)'>
<Output ItemName='SRCDIR' TaskParameter='Include' />
</CreateItem>
使用MSBuild 3.5,您可以在任务中包含项组
<Target Name='Build'>
<ItemGroup>
<SRCDIR2 Include='$(Source_Dir)' />
</ItemGroup>
<Message Text="%(SRCDIR2.FullPath)" />
<Message Text="%(SRCDIR.FullPath)" />
</Target>
在MSBuild 4.0中,最简单的方法是:
$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\your\path'))
即使将脚本
插入到另一个脚本中,此方法仍然有效;路径是相对于包含上述代码的文件的
(合并自以及最后一部分)
在MSBuild 3.5中,您可以使用以下任务:
如果你问我的话,我会说得有点冗长,但这是有效的。这将是相对于“原始”项目文件的,因此,如果将其放置在一个被
编辑的文件中,则它不会相对于该文件
在MSBuild 2.0中,有一种方法无法解析“.”。但是,它的行为与绝对路径一样:
<PropertyGroup>
<Source_Dir_Abs>$(MSBuildProjectDirectory)\$(Source_Dir)</Source_Dir_Abs>
</PropertyGroup>
$(MSBuildProjectDirectory)\$(源目录)
保留属性始终是包含此引用的脚本的目录
这也将与“原始”项目文件相关,因此,如果将其放置在一个得到
编辑的文件中,则它不会与该文件相关。添加了MSBuild 4.0,它允许您调用某些.net系统DLL中的静态函数。属性函数的一个非常好的方面是,它们将在目标之外进行求值
要在定义这样的属性时计算可以使用的完整路径,请执行以下操作:
<PropertyGroup>
<Source_Dir>$([System.IO.Path]::GetFullPath('..\..\..\Public\Server\'))</Source_Dir>
</PropertyGroup>
$([System.IO.Path]::GetFullPath('..\..\..\Public\Server\'))
语法有点难看,但非常强大。我认为完整路径元数据只适用于项,而不适用于属性。我想你是对的,有人知道从属性到完整/绝对路径的方法吗?你可以通过使用$(ProjectDir)$(Source\u Dir)“有点”达到目的,但你会有多余的',我从上面的那段代码中学到了更多关于如何构建MS任务的知识,这是我在MSBuild文档中所学到的。谢谢!:-)+1哦,伙计。这太棒了!正是我想要的。谢谢。它还会计算相对于(据我所见)定义属性的项目文件的路径,当您希望在其他文件中包含该属性时,这非常好。对我来说,这是一个完美的解决方案。@JeanHominal如果你使用
,它仍然是相对于它导入到的位置的,这是一个遗憾。尽管如此,这是唯一一种在目标之外也有效的方法,我认为这是一个+1。有关解决
问题的方法,请参阅。是的,当我说我所做的事情时,我弄错了-所有相对路径总是相对于“正在执行的项目”路径(MSBuild当前正在执行的项目);但是,您可以使用$(MSBuildThisFileDirectory)
获取当前正在执行的文件目录的完整路径。这正是我所需要的。谢谢+1这很好地工作,我(和其他人一样)在这里找到了一种规范化项目组的方法(基本上假设需要批处理并复制到一个新的项目组)——您显示的语法可以做到这一点。我忘记了FullPath
小心[System.IO.Path]::GetFullPath
。我在Visual Studio中生成时遇到错误,因为msbuild中的当前工作目录是C:\Windows\System32
GetFullPath
相对于工作目录而不是项目目录进行解析。@ChrisChilvers这很不幸。上次我测试它时(承认是很久以前),它是相对于包含代码的文件的。它也适用于回溯。\..\your\path
样式路径。还请注意,$(MSBuildThisFileDirectory)
宏已经包含一个尾随斜杠,因此必须指定your\path
,而不带前导斜杠,即$(MSBuildThisFileDirectory)your\path
。当您将它用于Microsoft单元测试框架的OutDir
测试时,当您尝试运行测试时,它将无法计算连接路径中的“\\”以找到构建的dll。@AdamYaxleyGetFullPath
自动折叠双反斜杠,因此,即使你有额外的反斜杠,它也会起作用。你的问题一定是因为别的原因。
<PropertyGroup>
<Source_Dir>$([System.IO.Path]::GetFullPath('..\..\..\Public\Server\'))</Source_Dir>
</PropertyGroup>