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

查看:177
本文介绍了将内容文件设置为“复制本地:始终";在一个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. (我的视觉工作室是法语的,所以我不确定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 traduction). 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.

我该如何实现?

注释:

Notes :

可以在安装软件包后立即在文件上设置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, wich is not the case. When updating the package, copy local is resetted 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)引起的.如果单击之前重新加载命令已完全终止,则有时会导致错误.诀窍是将对话框保留在那里,直到过程完成,然后然后重新加载项目.

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天全站免登陆