web-dev-qa-db-ja.com

相対パスが指定されている場合、MSBUILDにフルパスを評価および印刷させるにはどうすればよいですか?

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 \'にコピーしています

55
Eric Schoonover

MSBuild 4.0では、最も簡単な方法は次のとおりです。

$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\your\path'))

このメソッドは、スクリプトが別のスクリプトに<Import>edされていても機能します。パスは、上記のコードを含むファイルからの相対パスです。

アーロンの答え 、および Sayedの答え の最後の部分から統合)


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\".

あなたが私に尋ねるなら少し気が遠くなるが、それはうまくいきます。これは「元の」プロジェクトファイルに関連するため、<Import>edを取得するファイル内に配置した場合、これはそのファイルに関連しません。


MSBuild 2.0では、「..」を解決しないアプローチがあります。ただし、絶対パスのように動作します。

<PropertyGroup>
    <Source_Dir_Abs>$(MSBuildProjectDirectory)\$(Source_Dir)</Source_Dir_Abs>
</PropertyGroup>

$(MSBuildProjectDirectory) 予約済みプロパティは、常にこの参照を含むスクリプトのディレクトリです。

これは「元の」プロジェクトファイルに関連するため、<Import>edを取得するファイル内に配置した場合、これはそのファイルに関連しません。

93
Roman Starkov

MSBuild 4.0が追加されました プロパティ関数 これにより、一部の.netシステムdllで静的関数を呼び出すことができます。プロパティ関数の本当に良い点は、ターゲットの外側で評価されることです。

フルパスを評価するには、次のようにプロパティを定義するときに System.IO.Path.GetFullPath を使用できます。

<PropertyGroup>
  <Source_Dir>$([System.IO.Path]::GetFullPath('..\..\..\Public\Server\'))</Source_Dir>
</PropertyGroup>

構文は少し醜いですが、非常に強力です。

31
Aaron Carlson

ウェインは正解です。よく知られたメタデータはプロパティには適用されず、アイテムにのみ適用されます。 「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;
    }
}

そして、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>
6
brock.holum

プロパティを通じてアイテムメタデータプロパティにアクセスしようとしていますが、これは不可能です。あなたがしたいことは次のようなものです:

<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\'

(スクリプトは私のドキュメントフォルダーから実行されたため、..\Desktopがデスクトップへの正しい相対パスです。)

あなたの場合、Source_Dir項目の "..\Desktop"を "......\Public\Server"に置き換えれば、すべての設定は完了です。

5
Scott Dorman

プロパティをアイテムに変換する必要がある場合、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>
4
Scott Weinstein