61

<Message />相対パスが指定された絶対パスをタスクで評価して出力するように MSBuild を取得するにはどうすればよいですか?

プロパティグループ

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

4

5 に答える 5

103

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

あなたが私に尋ねると、少し長くなりますが、うまくいきます。これは「元の」プロジェクト ファイルに対して相対的であるため、<Import>ed を取得するファイル内に配置されている場合、これはそのファイルに対して相対的ではありません。


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

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

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

これも「元の」プロジェクト ファイルに対して相対的であるため、<Import>ed を取得するファイル内に配置されている場合、これはそのファイルに対して相対的ではありません。

于 2009-08-09T11:22:53.097 に答える
34

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

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

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

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

于 2011-02-04T04:05:21.310 に答える
7

よく知られているメタデータはプロパティには適用されず、アイテムのみに適用されるという 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;
    }
}

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>
于 2008-10-07T03:32:33.030 に答える
5

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

<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 がデスクトップへの正しい相対パスです。)

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

于 2008-10-07T03:38:19.400 に答える
4

プロパティをアイテムに変換する必要がある場合、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>
于 2008-10-07T16:24:50.693 に答える