将内容文件设置为“复制本地:始终"在一个 nuget 包中 [英] Set content files to "copy local : always" in a nuget package
问题描述
我在构建后事件中使用此命令从项目生成 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 : content
和 copy 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屋!