将内容文件设置为“复制本地:始终"在一个 nuget 包中 [英] Set content files to "copy local : always" in a nuget package

查看:14
本文介绍了将内容文件设置为“复制本地:始终"在一个 nuget 包中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在构建后事件中使用此命令从项目生成 nuget 包.变量 %conf% 设置为正确的配置(调试或发布),%1 是项目名称(例如MyCompany.MyProject").

I generate a nuget package from a project with this command in the post-build event. the variable %conf% is set to the right configuration (debug or release) and %1 is the project name (e.g. "MyCompany.MyProject").

nuget pack -Prop Configuration=%conf% "%1.csproj" -exclude *.sql -IncludeReferencedProjects

这个包仅供我们自己使用,它永远不会在 nuget 上发布.它在我们的私有存储库中结束.

This package is for our own usage only, it will never be published on nuget. It ends in our private repository.

在项目中,有一个文件设置为 generate action : contentcopy local : always.(我的 Visual Studio 是法语的,所以我不能 100% 确定翻译).我们将其命名为 importantfile.xml.

In the project, there is a file that is set to generate action : content and copy local : always. (My Visual Studio is in French, so I'm not 100% sure of the translation). Let's name it importantfile.xml.

在生成的包中,我最终得到了这个结构:

In the generated package, I end up with this structure :

- content
    - importantfile.xml
- lib
    -net45 (.NetFramework,Version=v4.5)
        -MyCompany.MyProject.dll

这很好,我希望 importantfile.xml 部署在包中,因为,这个文件很重要!

Which is fine, I want importantfile.xml to be deployed in the package, because, well, this file is important!

当我在另一个项目中安装包时,importantfile.xml 部署在项目的根目录.没关系.但它没有设置为 copy local : always.

When I install the package in another project, importantfile.xml is deployed at the root of the project. That's OK. But it is not set to copy local : always.

我需要 importantfile.xml 在我安装包的项目中 copy local : always.

I need importantfile.xml to be copy local : always in this project where I install my package.

我怎样才能做到这一点?

注意事项:

可以在安装软件包后在文件上设置 copy local : always,这没什么大不了的.如果以后对包的更新会让这个属性保持原样,我会接受它,但事实并非如此.更新包时,copy local 被重置为 never(如 这里).

I can set copy local : always on the file just after installing the package, that's no big deal. I would live with it if later updates of the package would let this property as-is, which is not the case. When updating the package, copy local is reset to never (as stated here).

项目文件夹中有一个nuspec文件,在这里:

There's a nuspec file in the project's folder, here it is :

<?xml version="1.0"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>$description$</description>
    <copyright>Copyright 2014</copyright>
    <tags>some random tags</tags>
  </metadata>
</package>

推荐答案

您可以使用 PowerShell 和 NuGet 提供的 Install.ps1 钩子.

You can use PowerShell and the Install.ps1 hook provided by NuGet.

请参阅文档.

通过 PowerShell,您必须搜索"在属性中包含 importantfile.xml 的内容元素.当脚本找到它时,它必须添加 <CopyToOutputDirectory>Always</CopyToOutputDirectory> 作为子元素.

Via PowerShell you have to 'search' for the content element which includes your importantfile.xml in an attribute. When the script found it, it has to add <CopyToOutputDirectory>Always</CopyToOutputDirectory> as a child element.

    <Content Include="importantfile.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>

您可以在此处找到一些 PowerShell 片段.看看 .ps1 文件.

You can find some PowerShell snippets here. Just take a look at the .ps1 files.

您可以尝试以下方法(未经测试).该文件必须命名为 Install.ps1 并复制到 tools 文件夹中:

You could try the following (not tested). The file has to be named Install.ps1 and copied into the tools folder:

param($installPath, $toolsPath, $package, $project)

# Load project XML.
$doc = New-Object System.Xml.XmlDocument
$doc.Load($project.FullName)
$namespace = 'http://schemas.microsoft.com/developer/msbuild/2003'

# Find the node containing the file. The tag "Content" may be replace by "None" depending of the case, check your .csproj file.
$xmlNode = Select-Xml "//msb:Project/msb:ItemGroup/msb:Content[@Include='importantfile.xml']" $doc -Namespace @{msb = $namespace}


#check if the node exists.
if($xmlNode -ne $null)
{
    $nodeName = "CopyToOutputDirectory"

    #Check if the property already exists, just in case.
    $property = $xmlNode.Node.SelectSingleNode($nodeName)
    if($property -eq $null)
    {
        $property = $doc.CreateElement($nodeName, $namespace)
        $property.AppendChild($doc.CreateTextNode("Always"))
        $xmlNode.Node.AppendChild($property)

        # Save changes.
        $doc.Save($project.FullName)
    }
}

您还应该在卸载软件包时检查是否所有内容都已完全删除.

You should also check if everything is removed completely when uninstalling the package.

Jonhhy5 的笔记

当通过 update-package 更新包时,Visual Studio 会警告项目在环境之外"被修改.这是由 $doc.Save($project.FullName) 引起的.如果我单击 reload before 命令完全终止,它有时会导致错误.诀窍是让对话框留在那里直到进程完成,然后然后重新加载项目.

When updating the package via update-package, Visual Studio warns that the project is modified "outside the environnment". That's caused by $doc.Save($project.FullName). If I click reload before the command is fully terminated, it sometimes causes errors. The trick is to leave the dialog there until the process finishes, and then reload the projects.

这篇关于将内容文件设置为“复制本地:始终"在一个 nuget 包中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆