Создайте собственный сценарий powershell для nuget, который добавляет настраиваемую цель к шагу csproj BeforeBuild - PullRequest
11 голосов
/ 13 июня 2011

Я хочу создать пакет nuget, который добавляет шаг BeforeBuild к моему csproj, используя пользовательскую задачу MSBuild, которую я создал.В идеале я хочу:

  1. Добавить новую цель в файл csproj (MyCustomBeforeBuildTarget)
  2. Добавить цель BeforeBuild, если ее еще нет
  3. РедактироватьАтрибут beforeBuild DependsOnTargets для включения моей пользовательской цели

Так что после установки мой csproj должен иметь следующее в:

<Target Name="MyCustomBeforeBuildTarget" Condition="SomeCondition">
     <MyCustomTask />
</Target>
<Target Name="BeforeBuild" DependsOnTargets="MyCustomBeforeBuildTarget">

</Target>

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

Какой самый простой скрипт установки Powershell nuget, который я могунапиши что добавит мою кастомную мишень?У меня есть ощущение, что сценарии PowerShell здесь могут составлять часть решения, но у меня недостаточно опыта PowerShell, чтобы знать, как на самом деле использовать их для редактирования csproj.

Ответы [ 2 ]

13 голосов
/ 08 сентября 2011

NuGetPowerTools - это пакет, который добавляет некоторые функции PowerShell, облегчающие работу с настройкой проекта, к которому вы добавляете пакет.Чтобы использовать доступные функции, вам нужно только сделать так, чтобы ваш пакет зависел от NuGetPowerTools, используя тег зависимостей в файле nuspec для пакетов, например:

<dependencies>
  <dependency id="NuGetPowerTools" version="0.26" />
</dependencies>

Это позволит получить ссылку на сборку.представление проекта вашего проекта.

Затем вам нужно поместить файл install.ps1 в папку tools вашего пакета NuGet, этот файл PowerShell будет запускаться при установке пакета и никогда после его установки.

Файл должен выглядеть примерно так:

#First some common params, delivered by the nuget package installer
param($installPath, $toolsPath, $package, $project)

# Grab a reference to the buildproject using a function from NuGetPowerTools
$buildProject = Get-MSBuildProject

# Add a target to your build project
$target = $buildProject.Xml.AddTarget("PublishWebsite")

# Make this target run before build
# You don't need to call your target from the beforebuild target,
# just state it using the BeforeTargets attribute
$target.BeforeTargets = "BeforeBuild"

# Add your task to the newly created target
$target.AddTask("MyCustomTask")

# Save the buildproject
$buildProject.Save()

# Save the project from the params
$project.Save()

Так и должно быть.

С уважением

Jesper Hauge

8 голосов
/ 28 августа 2012

Следующий код взят из пакета с именем CodeAssassin.WixWebProjectReferences.Он добавляет и удаляет следующий тег импорта в файл проекта при установке и удалении.Пакет не требует никаких зависимостей.

<Import Project="..\packages\CodeAssassin.WixWebProjectReferences.1.0\tools\CodeAssassin.WixWebProjectReferences.targets" />

Загрузите пакет и откройте его, используя NuGetPackageExplorer , чтобы увидеть, как это делается.

Ниже приведен код из install.ps1 и uninstall.ps1 (они выполняются только в том случае, если папка содержимого пакета NuGet не пуста).

(я не смог найтилюбое подсвечивание powershell, поэтому я использовал php, а он не идеален.)

install.ps1

param (
    $InstallPath,
    $ToolsPath,
    $Package,
    $Project
)

$TargetsFile = 'CodeAssassin.WixWebProjectReferences.targets'
$TargetsPath = $ToolsPath | Join-Path -ChildPath $TargetsFile

Add-Type -AssemblyName 'Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

$MSBProject = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.GetLoadedProjects($Project.FullName) |
    Select-Object -First 1

$ProjectUri = New-Object -TypeName Uri -ArgumentList "file://$($Project.FullName)"
$TargetUri = New-Object -TypeName Uri -ArgumentList "file://$TargetsPath"

$RelativePath = $ProjectUri.MakeRelativeUri($TargetUri) -replace '/','\'

$ExistingImports = $MSBProject.Xml.Imports |
    Where-Object { $_.Project -like "*\$TargetsFile" }
if ($ExistingImports) {
    $ExistingImports | 
        ForEach-Object {
            $MSBProject.Xml.RemoveChild($_) | Out-Null
        }
}
$MSBProject.Xml.AddImport($RelativePath) | Out-Null
$Project.Save()

uninstall.ps1

param (
    $InstallPath,
    $ToolsPath,
    $Package,
    $Project
)

$TargetsFile = 'CodeAssassin.WixWebProjectReferences.targets'

Add-Type -AssemblyName 'Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

$MSBProject = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.GetLoadedProjects($Project.FullName) |
    Select-Object -First 1

$ExistingImports = $MSBProject.Xml.Imports |
    Where-Object { $_.Project -like "*\$TargetsFile" }
if ($ExistingImports) {
    $ExistingImports | 
        ForEach-Object {
            $MSBProject.Xml.RemoveChild($_) | Out-Null
        }
    $Project.Save()
}

Образец файла назначениякопирует некоторые файлы в путь вывода

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
    <ItemGroup>
        <Files Include="..\packages\Insert_Path_To_Your_Package_Folder_Here\bin\*" />
    </ItemGroup>
    <Target Name="Insert_Name_of_Your_Target_Here" AfterTargets="AfterBuild">
        <Copy SourceFiles="@(Files)" DestinationFolder="$(TargetDir)\bin\" SkipUnchangedFiles="true" />
    </Target>
</Project>
...