كيف يمكنني الحصول على MSBUILD تقييم و طباعة المسار الكامل عندما تعطى مسار نسبي ؟

StackOverflow https://stackoverflow.com/questions/176931

سؤال

كيف يمكنني الحصول على 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\".

قليلا مهزار إذا كنت تسألني, لكنه يعمل.هذا بالنسبة إلى "الأصل" ملف المشروع ، حتى إذا وضعت داخل الملف الذي يحصل <Import>اد ، وهذا لن يكون بالنسبة إلى هذا الملف.


في MSBuild 2.0, هناك هو النهج الذي لا يحل "..".ومع ذلك فإنه لا تتصرف تماما مثل مسار مطلق:

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

على $(MSBuildProjectDirectory) محفوظة الملكية دائما الدليل النصي الذي يحتوي على هذه الإشارة.

هذا سوف أيضا تكون نسبة إلى "الأصلي" ملف المشروع ، حتى إذا وضعت داخل الملف الذي يحصل <Import>اد ، وهذا لن يكون بالنسبة إلى هذا الملف.

نصائح أخرى

MSBuild 4.0 إضافة وظائف المنشأة والتي تسمح لك دعوة في وظائف ثابتة في بعض .صافي النظام dlls.شيء جميل حقا حول الملكية وظائف أنها سوف تقيم خارج الهدف.

لتقييم مسار كامل يمكنك استخدام النظام.IO.مسار.GetFullPath عند تعريف المنشأة مثل ذلك:

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

الجملة القبيحة قليلا ولكنها قوية جدا.

واين هو الصحيح الذي المعروفة بيانات التعريف لا ينطبق على خصائص فقط على البنود.باستخدام خصائص مثل "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>

أنت تحاول الوصول إلى عنصر الوصفية الملكية من خلال المنشأة التي لم يكن ممكنا.ما تريد القيام به هو شيء من هذا القبيل:

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

(السيناريو كان تشغيل من مجلد "المستندات" ، لذلك ..\سطح المكتب هو تصحيح المسار النسبي إلى سطح المكتب.)

في حالة استبدال "..\سطح المكتب" مع "......\العامة\Server" في Source_Dir البند يجب أن تكون كل مجموعة.

إذا كنت بحاجة إلى تحويل خصائص العناصر لديك خياران.مع 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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top