为 nuget 创建自定义 powershell 脚本,将自定义目标添加到 csproj BeforeBuild 步骤

发布于 2024-11-15 07:12:23 字数 807 浏览 1 评论 0原文

我想创建一个 nuget 包,使用我创建的自定义 MSBuild 任务将 BeforeBuild 步骤添加到我的 csproj 中。理想情况下,我想要:

  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。

I want to create a nuget package that adds a BeforeBuild step to my csproj using a custom MSBuild task I have created. Ideally, I want to:

  1. Add a new Target into the csproj file (MyCustomBeforeBuildTarget)
  2. Add the BeforeBuild target if it is not already there
  3. Edit the BeforeBuild DependsOnTargets attribute to include my custom target

So after install my csproj should have the following in:

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

</Target>

Also, it would be nice that when my package is removed, the custom target disappears too,
although I have added a condition that should make it ignore the target if my custom task DLL is not present.

What is the simplest Powershell nuget install script I can write that will add my custom target? I have a feeling that the PowerShell scripts here might form part of the solution, but I don't have enough PowerShell experience to know how to actually use them to edit the csproj.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤君无依 2024-11-22 07:12:23

NuGetPowerTools 是一个添加了一些 PowerShell 功能的包,可以更轻松地处理项目的项目设置您正在添加一个包。要使用可用的功能,您只需使您的包依赖于 NuGetPowerTools,使用包 nuspec 文件中的依赖项标记,如下所示:

<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()

应该是这样。

问候

杰斯珀·豪格

The NuGetPowerTools is a package that adds some PowerShell functions that makes it easier to work with the project setup of the project you're adding a package to. To use the functions available you only need to make your package depend on the NuGetPowerTools, using the dependencies tag in your packages nuspec file like this:

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

This will make it possible to grab a reference to a build project representation of your project.

Then you need to put an install.ps1 file in the tools folder of your NuGet package, this PowerShell file will run when you install the package and never again after installation.

The file should look something like this:

#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()

That should be it.

Regards

Jesper Hauge

身边 2024-11-22 07:12:23

以下代码来自名为 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>

The following code comes from a package called CodeAssassin.WixWebProjectReferences. It adds and removes the following import-tag to the project file upon install and uninstall. The package does not require any dependencies.

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

Download the package and open it using NuGetPackageExplorer to se how it's done.

Below is the code from install.ps1 and uninstall.ps1 (they are only executed if the content folder of the NuGet-package is non-empty).

(I couldn't find any powershell-highlighting so I used php instead and it's not perfect.)

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()
}

Sample targets-file that copies some files to the output path

<?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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文