不覆盖现有事件的情况下添加后构建事件

3
我有一个Powershell脚本(由我的NuGet包运行),可以向用户的Visual Studio项目添加后期构建事件。
$project.Properties | where { $_.Name -eq "PostBuildEvent" } | foreach { $_.Value = "xcopy `"`$(ProjectDir)MyFolder`" `"`$(OutDir)`"" }

很遗憾,目前它会覆盖现有的发布后构建事件。如何修改Powershell脚本,以便在不存在时追加我的构建事件?

我以前从未使用过Powershell,但我尝试在foreach内简单地添加它,但这并没有起作用:

$_.Value = "$_.Value`nxcopy `"`$(ProjectDir)MyFolder`" `"`$(OutDir)`""

只需要执行以下命令:

System.__ComObject.Value xcopy "$(ProjectDir)MyFolder" "$(OutDir)"

该命令将把 $(ProjectDir) 中的 MyFolder 文件夹复制到 $(OutDir) 中。
2个回答

5
我认为编辑PostBuildEvent属性不是向用户项目添加后构建操作的正确方法。我相信推荐的方法是将自定义操作放入一个目标中,然后将其导入到项目文件中。从NuGet 2.5开始,如果您在包中包含一个“build”文件夹(与内容和工具处于同一级别),并且其中包含一个{packageid}.targets文件或{packageid}.props文件,则在安装包时,NuGet将自动向项目文件中添加导入。
例如,您有一个名为MyNuGet的包。您创建一个文件build\MyNuGet.targets,其中包含:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <MySourceFiles Include="$(ProjectDir)MyFolder\**" />
    </ItemGroup>
    <Target Name="MyNuGetCustomTarget" AfterTargets="Build">
        <Copy SourceFiles="@(MySourceFiles)" DestinationFolder="$(OutDir)" />
    </Target>
</Project>

这将创建一个自定义目标,配置为在标准 Build 目标之后运行。它将复制一些文件到输出目录。

在 install.ps1 中,您不需要做任何其他事情。当用户安装您的包时,NuGet 将自动向用户的项目文件中添加导入,然后在运行 Build 目标之后运行您的目标。


Mike Z 没有错。这将是“正确”的做法。 - HAL9256
@mike-z 这太棒了。我没想到你可以用 NuGet 做到这一点,第一次就成功了。谢谢! - openshac
@openshac 是的,直到我做了一些研究才知道这个。更好的是,NuGet会在卸载时自动删除导入。当编辑后生成事件脚本时,这真的很棘手。 - Mike Zboray

1
当在引号内引用带有属性的变量时,您必须将它们括在$()中。
因此,这样写:
$_.Value = "$_.Value`nxcopy `"`$(ProjectDir)MyFolder`" `"`$(OutDir)`""

应该是这样的:

应该是这样的:

$_.Value = "$($_.Value)`nxcopy `"`$(ProjectDir)MyFolder`" `"`$(OutDir)`""

或者更简单的方法是使用+=

i.e:

$_.Value += "`nxcopy `"`$(ProjectDir)MyFolder`" `"`$(OutDir)`""

谢谢 @HAL9256,现在已经实现了追加功能,但是新行 n 似乎不起作用。我做错了什么明显的事情吗? - openshac
1
好的,我明白了,我需要使用rn。现在只需要弄清楚如何检查构建事件是否已经存在了。 - openshac
为了检查它是否已经存在,请放置一个 if($_.Value -notmatch "My Code"){--Code to Add Event--} - HAL9256

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接