Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
В 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 , есть подход, который не разрешает "..".
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>
Если необходимо преобразовать Свойства в Объекты, у Вас есть две опции. С 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>
Вы пытаетесь получить доступ к свойству метаданных объекта через свойство, которое не возможно. То, что Вы хотите сделать, является чем-то вроде этого:
<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, и Вы должны быть все установлены.