Как я могу заставить MSBUILD оценивать и печатать полный путь при предоставлении относительного пути?

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

55
задан Ruben Bartelink 12 August 2010 в 05:26
поделиться

4 ответа

В MSBuild 4.0 самый простой способ заключается в следующем:

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

Этот метод работает, даже если сценарий вставлен в другой сценарий; путь указан относительно файла, содержащего указанный выше код.

(объединено из ответа Аарона , а также последней части ответа Сайеда )


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

Немного многословно, если вы спросите меня, но оно работает. Это будет относиться к "исходному" файлу проекта, поэтому, если поместить его внутрь файла, который получает ed, он не будет относиться к этому файлу.


В MSBuild 2.0 , есть подход, который не разрешает "..".

94
ответ дан 26 November 2019 в 17:45
поделиться

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>
6
ответ дан brock.holum 26 November 2019 в 17:45
поделиться

Если необходимо преобразовать Свойства в Объекты, у Вас есть две опции. С msbuild 2 можно использовать задача

  <Target Name='Build'>
    <CreateItem Include='$(Source_Dir)'>
      <Output ItemName='SRCDIR' TaskParameter='Include' />
    </CreateItem>

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 26 November 2019 в 17:45
поделиться

Вы пытаетесь получить доступ к свойству метаданных объекта через свойство, которое не возможно. То, что Вы хотите сделать, является чем-то вроде этого:

<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, корректный относительный путь для получения до моего рабочего стола.)

В Вашем случае, замените "..\Desktop" "......\Public\Server" в объекте Source_Dir, и Вы должны быть все установлены.

5
ответ дан Scott Dorman 26 November 2019 в 17:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: