Visual studio 将内容文件设置为";复制本地:始终“复制”;在一个nuget包中

Visual studio 将内容文件设置为";复制本地:始终“复制”;在一个nuget包中,visual-studio,visual-studio-2012,nuget,nuget-package,copy-local,Visual Studio,Visual Studio 2012,Nuget,Nuget Package,Copy Local,我在后期生成事件中使用此命令从项目生成一个nuget包。变量%conf%被设置为正确的配置(调试或发布),并且%1是项目名称(例如“MyCompany.MyProject”) 此软件包仅供我们自己使用,永远不会在nuget上发布。它在我们的私有存储库中结束 在项目中,有一个文件被设置为generate action:content和copy local:always。(我的VisualStudio是法语的,所以我对翻译不是100%肯定)。让我们把它命名为importantfile.xml 在生成

我在后期生成事件中使用此命令从项目生成一个nuget包。变量
%conf%
被设置为正确的配置(调试或发布),并且
%1
是项目名称(例如“MyCompany.MyProject”)

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

在项目中,有一个文件被设置为
generate action:content
copy local:always
。(我的VisualStudio是法语的,所以我对翻译不是100%肯定)。让我们把它命名为
importantfile.xml

在生成的包中,我以以下结构结束:

- content
    - importantfile.xml
- lib
    -net45 (.NetFramework,Version=v4.5)
        -MyCompany.MyProject.dll
这很好,我希望在包中部署
importantfile.xml
,因为这个文件很重要

当我在另一个项目中安装包时,
importantfile.xml
部署在项目的根目录下。没关系。但它没有设置为
复制本地:始终

我需要
importantfile.xml
成为
本地副本:始终
在我安装软件包的项目中。

我如何才能做到这一点?

注意事项:

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

项目文件夹中有一个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>

$id$
$version$
$title$
$author$
$author$
假的
$description$
版权所有2014
一些随机标签

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

通过PowerShell,您必须“搜索”包含属性中的
importantfile.xml
的内容元素。当脚本找到它时,它必须添加
始终
作为子元素

    <Content Include="importantfile.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
卸载软件包时,还应检查是否已完全删除所有内容

Jonhhy5的注释


当通过
update package
更新包时,VisualStudio警告说项目已在“环境之外”修改。这是由
$doc.Save($project.FullName)
引起的。如果在命令完全终止之前单击“重新加载”,有时会导致错误。诀窍是将对话框保留在那里,直到过程完成,然后重新加载项目。

我知道你们对此有一个可行的解决方案,但它对我不起作用,所以我将分享我从install.ps1(github源代码)中提取的内容

注意:这不是我的代码,这是来自的install.ps1的内容 NLog.config nuget包只是分享知识

对我来说,这似乎有点直截了当,只是希望帮助那些可能会偶然发现这一点的人

您可以找到的接受int值和CopyToOutputDirectory的接受值

如果链接再次断开

田地 prjBuildActionCompile 1
该文件已编译

prjBuildActionContent 2
该文件包含在内容项目输出组中(请参见部署应用程序、服务和组件)

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

另一种方法不是使用PowerShell脚本,而是使用与包id同名的:

<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>

importantfile.xml
总是
然后在nuspec文件中,将所需文件与目标文件一起添加到
Build
目录,而不是将其添加到
Content
目录

  • 建造
    • importantfile.xml
    • MyPackage.targets
  • 解放党
    • 网络45
      • MyAssembly.dll
如果您需要不同体系结构的不同内容,则可以在
Build
下添加体系结构文件夹,每个文件夹都有自己的目标文件

通过PowerShell脚本和NuGet
Content
目录使用目标文件的好处:

  • Visual Studio中的项目中未显示所需的内容文件
  • 内容文件链接到引用NuGet包的每个项目的目录,而不是复制到该项目的目录中(防止存在多个副本,并保持与NuGet包中程序集/库的行为相同)
  • PowerShell脚本只在VisualStudio和(构建服务器、其他IDE和其他操作系统)中工作,这种方法在任何地方都适用
  • PowerShell安装脚本为

我制作了这个程序,它将文件从构建文件夹复制到输出文件夹(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>

%(RecursiveDir)%(文件名)%(扩展名)
保存最新

我编写了一个名为
NuGetLib
的小工具,用于在生成后自动将文件添加到nuget包中

  • 使用
    Install.ps1
    脚本创建一个
    tools
    文件夹
  • 构建您的
    nugetPackage
  • 将工具文件夹添加到内置的
    nugetPackage

  • 我看过此文档,发现它非常不完整。这就是我想做的,尽管你的代码比我的干净多了。真的吗?你漏了什么?你是说医生漏了什么?那么,至少应该记录由
    param($installPath,$toolsPath,$package,$project)
    启动的变量。问题中的情况是
    <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>
    
    <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>