我想创建一个nuget包,它使用我创建的自定义MSBuild任务向我的csproj添加BeforeBuild步骤。理想情况下,我想:
安装完成后,我的csproj应该包含以下内容:
<Target Name="MyCustomBeforeBuildTarget" Condition="SomeCondition">
<MyCustomTask />
</Target>
<Target Name="BeforeBuild" DependsOnTargets="MyCustomBeforeBuildTarget">
</Target>
此外,当我的包被删除时,自定义目标也会消失,这将是很好的, 虽然我添加了一个条件,如果我的自定义任务DLL不存在,它应该忽略目标。
我能写的最简单的Powershell nuget安装脚本会添加我的自定义目标吗?我觉得PowerShell脚本here可能是解决方案的一部分,但我没有足够的PowerShell经验知道如何实际使用它们来编辑csproj。
答案 0 :(得分:13)
NuGetPowerTools是一个包,它添加了一些PowerShell函数,使您可以更轻松地使用要添加包的项目的项目设置。要使用可用的功能,您只需要使用包nuspec文件中的dependencies标记使您的包依赖于NuGetPowerTools,如下所示:
<dependencies>
<dependency id="NuGetPowerTools" version="0.26" />
</dependencies>
这样就可以获取对项目的构建项目表示的引用。
然后,您需要将install.ps1
文件放在NuGet包的tools
文件夹中,此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
答案 1 :(得分:8)
以下代码来自名为CodeAssassin.WixWebProjectReferences的包。它在安装和卸载时将并删除以下import-tag添加到项目文件中。该包不需要任何依赖。
<Import Project="..\packages\CodeAssassin.WixWebProjectReferences.1.0\tools\CodeAssassin.WixWebProjectReferences.targets" />
下载该软件包并使用NuGetPackageExplorer打开它以了解它是如何完成的。
以下是install.ps1和uninstall.ps1中的代码(只有在NuGet-package的内容文件夹非空时才会执行它们。)
(我找不到任何powershell-highlighting,所以我使用了php而不是完美的。)
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()
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>