我在post-build事件中使用此命令从项目生成nuget包。变量%conf%
设置为正确的配置(调试或发布),%1
是项目名称(例如“MyCompany.MyProject”)。
nuget pack -Prop Configuration=%conf% "%1.csproj" -exclude *.sql -IncludeReferencedProjects
此软件包仅供我们自己使用,永远不会在nuget上发布。它以我们的私人存储库结束。
在项目中,有一个文件设置为generate action : content
和copy local : always
。 (我的视觉工作室是法语,所以我不是百分之百地确定了它的变形)。我们将其命名为importantfile.xml
。
在生成的包中,我最终得到了这个结构:
- content
- importantfile.xml
- lib
-net45 (.NetFramework,Version=v4.5)
-MyCompany.MyProject.dll
哪个好,我希望importantfile.xml
部署在包中,因为这个文件很重要!
当我在另一个项目中安装软件包时,importantfile.xml
部署在项目的根目录下。没关系。但它未设置为copy local : always
。
在我安装软件包的项目中,我需要importantfile.xml
为copy local : always
。
我该如何实现?
注意:
我可以在安装软件包之后在文件上设置copy local : always
,这没什么大不了的。如果以后更新软件包会让这个属性按原样,我会忍受它,但事实并非如此。更新包时,copy local
将重置为never
(如here所述)。
项目文件夹中有一个nuspec文件,这里是:
<?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>
答案 0 :(得分:133)
不使用PowerShell脚本,而是使用与包ID同名的MSBuild targets or props file:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)importantfile.xml">
<Link>importantfile.xml</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
然后,在nuspec文件中,不是将所需文件添加到Content
目录,而是将它们与目标文件一起添加到Build
目录。
如果您需要针对不同体系结构的不同内容,则可以在Build
下添加体系结构文件夹,每个体系结构文件夹都有自己的目标文件。
使用NuGet Content
目录在PowerShell脚本上使用目标文件的好处:
答案 1 :(得分:38)
我知道你们有一个可行的解决方案,但这对我不起作用所以我要分享我从NLog.config NuGet package install.ps1(github source here中取出的内容)。
注意:这不是我的代码,这是install.ps1的内容 NLog.config nuget包只是分享知识。
对我来说似乎更直接一点,只是希望能帮助那些可能偶然发现这一点的人。
您可以找到BuildAction here的已接受int值以及CopyToOutputDirectory here的可接受值。
字段
prjBuildActionCompile 1
该文件已编译。
prjBuildActionContent 2
该文件包含在Content项目输出组中(请参阅部署应用程序,服务和组件)
prjBuildActionEmbeddedResource 3
该文件包含在主生成的程序集中或作为资源包含在附属程序集中。
prjBuildActionNone 0
不采取任何行动。
param($installPath, $toolsPath, $package, $project)
$configItem = $project.ProjectItems.Item("NLog.config")
# set 'Copy To Output Directory' to 'Copy if newer'
$copyToOutput = $configItem.Properties.Item("CopyToOutputDirectory")
# Copy Always Always copyToOutput.Value = 1
# Copy if Newer copyToOutput.Value = 2
$copyToOutput.Value = 2
# set 'Build Action' to 'Content'
$buildAction = $configItem.Properties.Item("BuildAction")
$buildAction.Value = 2
答案 2 :(得分:5)
我做了这个,它将我的构建文件夹中的文件复制到输出文件夹(bin / debug或bin / release)。对我来说就像是一种魅力。
Nuspec文件:
<package>
<files>
<file src="\bin\Release\*.dll" target="lib" />
<file src="\bin\Release\x64\*.dll" target="build\x64" />
<file src="\bin\Release\x86\*.dll" target="build\x86" />
<file src="MyProject.targets" target="build\" />
</files>
</package>
MyProject.targets
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)**\*.dll" />
<None Include="@(NativeLibs)">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
答案 3 :(得分:2)
您可以使用PowerShell和NuGet提供的Install.ps1
挂钩。
请参阅documentation。
通过PowerShell,您必须“搜索”包含属性中importantfile.xml
的内容元素。当脚本找到它时,它必须添加<CopyToOutputDirectory>Always</CopyToOutputDirectory>
作为子元素。
<Content Include="importantfile.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
您可以找到一些PowerShell代码段here。只需查看.ps1
个文件。
您可以尝试以下方法(未经测试)。该文件必须命名为Install.ps1
并复制到tools
文件夹中:
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)
}
}
卸载软件包时,还应检查是否所有内容都已完全删除。
Jonhhy5的注释
通过update-package
更新软件包时,Visual Studio会警告项目已在“环境之外”进行修改。这是由$doc.Save($project.FullName)
引起的。如果在命令完全终止之前单击“重新加载”,则有时会导致错误。诀窍是将对话框留在那里直到进程完成,然后 重新加载项目。
答案 4 :(得分:0)
我编写了一个名为NuGetLib
的小工具,用于在构建后自动将文件添加到nuget包中。
tools
脚本Install.ps1
文件夹
nugetPackage
nugetPackage