相対パスが指定されている場合、MSBUILDにフルパスを評価および印刷させるにはどうすればよいですか?
-
05-07-2019 - |
質問
MSBuildで<Message />
タスクで相対パスを指定して絶対パスを評価および印刷するにはどうすればよいですか?
プロパティグループ
<Source_Dir>..\..\..\Public\Server\</Source_Dir>
<Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
タスク
<Message Importance="low" Text="Copying '$(Source_Dir.FullPath)' to '$(Program_Dir)'" />
出力
「」を「c:\ Program Files(x86)\ Program \」にコピー
解決
MSBuild 4.0の場合、最も簡単な方法は次のとおりです。
$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\your\path'))
このメソッドは、スクリプトが別のスクリプトに<Import>
挿入された場合でも機能します。パスは上記のコードを含むファイルからの相対パスです。
MSBuild 3.5 では、 ConvertToAbsolutePath タスク:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="Test"
ToolsVersion="3.5">
<PropertyGroup>
<Source_Dir>..\..\..\Public\Server\</Source_Dir>
<Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
</PropertyGroup>
<Target Name="Test">
<ConvertToAbsolutePath Paths="$(Source_Dir)">
<Output TaskParameter="AbsolutePaths" PropertyName="Source_Dir_Abs"/>
</ConvertToAbsolutePath>
<Message Text='Copying "$(Source_Dir_Abs)" to "$(Program_Dir)".' />
</Target>
</Project>
関連する出力:
Project "P:\software\perforce1\main\XxxxxxXxxx\Xxxxx.proj" on node 0 (default targets).
Copying "P:\software\Public\Server\" to "c:\Program Files (x86)\Program\".
あなたが私に尋ねると少し時間がかかりますが、うまくいきます。これは、<!> quot; original <!> quot;に関連します。プロジェクトファイルです。したがって、<=> edされるファイル内に配置された場合、これはそのファイルに関連しません。
MSBuild 2.0 には、<!> quot; .. <!> quot;を解決しないアプローチがあります。ただし、絶対パスのように動作します。
<PropertyGroup>
<Source_Dir_Abs>$(MSBuildProjectDirectory)\$(Source_Dir)</Source_Dir_Abs>
</PropertyGroup>
$(MSBuildProjectDirectory)予約済みpropertyは常に、この参照を含むスクリプトのディレクトリです。
これは、<!> quot; original <!> quot;にも関連します。プロジェクトファイルです。したがって、<=> edされるファイル内に配置された場合、これはそのファイルに関連しません。
他のヒント
MSBuild 4.0は、静的な呼び出しを可能にするプロパティ関数を追加しました。 .netシステムdllの一部で機能します。プロパティ関数の素晴らしいところは、ターゲットの外側で評価することです。
フルパスを評価するには、システムを使用できます。 IO.Path.GetFullPath のようにプロパティを定義する場合:
<PropertyGroup>
<Source_Dir>$([System.IO.Path]::GetFullPath('..\..\..\Public\Server\'))</Source_Dir>
</PropertyGroup>
構文は少しいですが、非常に強力です。
Wayneは、よく知られているメタデータがプロパティには適用されず、アイテムにのみ適用されることを認識しています。 <!> quot; MSBuildProjectDirectory <!> quotなどのプロパティを使用します。動作しますが、フルパスを解決するための組み込みの方法を知りません。
別のオプションは、相対パスを取得して完全に解決されたパスを吐き出す単純なカスタムタスクを作成することです。次のようになります:
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;
}
}
そして、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>
プロパティを介してアイテムメタデータプロパティにアクセスしようとしていますが、これは不可能です。あなたがしたいことは次のようなものです:
<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>
次のように出力を生成します:
Copying 'C:\Users\sdorman\Desktop' to 'c:\Program Files (x86)\Program\'
(スクリプトはDocumentsフォルダーから実行されたため、.. \ Desktopはデスクトップに到達するための正しい相対パスです。)
あなたの場合、<!> quot; .. \ Desktop <!> quot;を置き換えます。 with <!> quot; ...... \ Public \ Server <!> quot; Source_Dirアイテムで、すべて設定できます。
プロパティをアイテムに変換する必要がある場合、2つのオプションがあります。 msbuild 2では、 CreateItem タスク
を使用できます <Target Name='Build'>
<CreateItem Include='$(Source_Dir)'>
<Output ItemName='SRCDIR' TaskParameter='Include' />
</CreateItem>
MSBuild 3.5では、タスク内にItemGroupsを含めることができます
<Target Name='Build'>
<ItemGroup>
<SRCDIR2 Include='$(Source_Dir)' />
</ItemGroup>
<Message Text="%(SRCDIR2.FullPath)" />
<Message Text="%(SRCDIR.FullPath)" />
</Target>