Nuget包生成时如何排除lib文件夹。

28

我正在尝试使用.nuspec文件生成NuGet包。我们在同一个项目下有多个项目,尝试创建nLog.config(和变换文件),并通过NuGet包进行分发。对于任何版本的.Net Framework,我都需要相同的配置文件集(仅配置,无dll)。所以我真的不需要\ lib \ net45 \ myproject.dll或\ lib \ net40 \ myproject.dll。虽然当我生成NuGet包时,它总是创建lib文件夹并包含dll。这种情况会为与.NET Framework版本相关的任何项目创建依赖关系。

以下是我的nuspec文件,以防有人想参考是否存在错误。我尝试过 "" 和其他一些方法,但没有成功。

<?xml version="1.0"?>
<package >
  <metadata>
    <id>NLogConfig</id>
    <version>1.0.3</version>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <copyright>Copyright 2013</copyright>
    <dependencies>
      <dependency id="NLog" version="2.1.0" />
      <dependency id="NLog.Schema" version="2.1.0" />
    </dependencies>
  </metadata>
  <files>    
    <file src="NLog.config" target="content" />
    <file src="NLog.Debug.config" target="content" />
    <file src="NLog.UAT.config" target="content" />
    <file src="NLog.Release.config" target="content" />
    <file src="tools\*.*" target="tools"/>          
  </files>
</package>
我该如何使用nuspec文件(首选)或其他机制完全排除lib文件夹?谢谢!!
更新1: 我试图偷偷摸摸地做,但并没有成功。我设置了后构建事件并尝试删除DLL文件。但不知何故系统很聪明,它给了我一个错误:“错误79 无法找到'C:\ GITRepo \ NLogConfig \ NLogConfig \ bin \ Release \ NLogConfig.dll'。确保已经构建了项目。”
更新2: 我没有发现用.csproj构建nuget包的方法,但是使用外部命令并指定nuspec文件,我能够达到相同的结果。问题仍然存在,这只是我的解决办法。
10个回答

15

我想分享我的经验。我需要使用 csproj 作为 Nuget.exe 的目标(因为我希望NuGet可以自动解决依赖项),并且在结果包中没有 lib 文件夹。要省略该文件夹,我使用了以下命令:

nuget pack <projectPath> -Exclude bin/**/*.*

这个方法确实有效,应该标记为答案。 - Peter Ivan
"nuget.exe:无法创建既没有依赖项也没有内容的软件包。" 这是错误的,因为<files>用于填充工具文件夹。 - Sam Rueby
请确保为这些文件设置正确的路径,看起来NuGet无法访问它们。如果您使用反斜杠作为路径分隔符,请尝试将其替换为正斜杠。 - AndreyCh
运行良好。我给你点赞。 - JGV

7

这样做确实可以避免将输出内容安装为目标项目(添加了NuGet包的项目)的依赖项,但仍然会导致输出内容被安装到“tools”文件夹中... 但是,我更喜欢“Dav Evans”的方法,因为它将配置包含在“.nuget”包中,而不是修改“nuget.exe” 打包语法。 https://dev59.com/NmIj5IYBdhLWcg3wYUGQ#30883992 - CJBS
这实际上最终创建了一个工具文件夹。这并没有帮助。 - Long Do Thanh

5
我通过首先从项目的输出文件夹中排除所有文件来解决了这个问题。
<file src="bin\**\*.*" target="lib\net451" exclude="bin\**\*.*" />

实际上,当我通过NuGet.exe打包时,我以.nuspec文件为目标,而不是我的csproj文件。生成的软件包不包含我的项目输出dll文件,也没有/lib文件夹。


1
这是个好方法,正如所提到的那样,必须定位于 .nuspec 文件。如果定位于 .csproj 文件会导致 lib 文件夹被包含进去。我喜欢这种方法,因为它不需要修改 NuGet 命令的语法,而是通过 .nuspec 文件来包含它。 - CJBS

3
通常情况下,您不需要或不想要一个 .nuspec 文件。在这种情况下,您可以从项目文件中控制它:
<PropertyGroup>
  <IncludeBuildOutput>false</IncludeBuildOutput>
  <IncludeSymbols>false</IncludeSymbols>
</PropertyGroup>

1
当您按项目打包时,这是预期的行为,因为整个重点是nuget将读取项目并相应地生成包。任何找到的.nuspec只能添加内容,而不能删除任何先前添加的内容。
所以你在第二次更新中提到的是你应该做的 - 通过.nuspec打包。

0

我也遇到了这个问题,你提出的解决方法是将包创建与项目分离,但我的问题在于我无法在nuspec文件中使用通配符。我的解决方法是使用install.ps1 PowerShell脚本,在将包添加到项目后运行该脚本。但是,您需要先在包管理器控制台中设置ExecutionPolicy,以便PowerShell脚本可以运行。

param($installPath, $toolsPath, $package, $project)
$project.Object.References | Where-Object { $_.Name -eq 'NLogConfig' } | ForEach-Object { $_.Remove() }

我真的不喜欢这个解决方法,因为它在执行策略受限的机器上会运行失败,而这是默认设置。


0

你需要移除dependencies元素,在你使用项目构建NuGet包之前,NuGet会添加对这些dll的引用

<?xml version="1.0"?>
<package >
  <metadata>
    <id>NLogConfig</id>
    <version>1.0.3</version>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <copyright>Copyright 2013</copyright>
  </metadata>
  <files>    
    <file src="NLog.config" target="content" />
    <file src="NLog.Debug.config" target="content" />
    <file src="NLog.UAT.config" target="content" />
    <file src="NLog.Release.config" target="content" />
    <file src="tools\*.*" target="tools"/>          
  </files>
</package>

谢谢您的回复,Giammin!不幸的是,那对我没用。 - TorontoKid
@TorontoKid 这真的很奇怪...你是如何生成那个包的?你是如何调用 nuget.exe 的? - giammin
如果您在.csproj文件中修改了"<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />",并且对于给定的配置(在我的情况下是Release),如果您设置<BuildPackage>true</BuildPackage>,每次构建发布时,您将在输出文件夹中生成nuget包。您需要在根文件夹中拥有.nuget\nuget.config、.nuget\nuget.exe和.nuget\nuget.targets才能使其正常工作。如果这让您感到困惑,我可以向您发送详细的电子邮件,并提供设置屏幕截图。 - TorontoKid
@TorontoKid 我认为你需要将软件包创建与项目分离,以使其正常工作。 - giammin
谢谢查看!!这正是我为解决问题所做的。我更新了我的问题,并进行了编辑,“我没有找到使用 .csproj 构建 nuget 包的方法,但使用外部命令并指定 nuspec 文件,我能够达到相同的结果。问题仍然存在,这只是我的解决方法。”再次感谢您的建议。 - TorontoKid

0

我遇到了同样的问题,我并不在意.dll是否被包含,但是我的内容中有.cs文件,这样类就会同时存在于添加到目标项目的内容和安装包中添加的dll中(猜测你也是在做类似的事情)。

最终我将内容文件夹中的.cs文件的构建操作更改为“无”,以便它们不会出现在DLL中。

注意:当您这样做时,.cs文件中的所有代码都不会得到验证,因此您应该在确保一切正确之后才进行此操作。

虽然希望能完全排除DLL,但这是我使用项目作为构建的解决方法。

希望这能帮助到某些人。


0

1
谢谢您的回复,但是不幸的是它没有起作用。我认为我的问题可能不够清楚,但我正在尝试使用<BuildPackage> true </ BuildPackage>作为Visual Studio构建过程的一部分来创建包,并使用<Import Project =“ $(SolutionDir)\ .nuget \ NuGet.targets”Condition =“ Exists(' $(SolutionDir)\ .nuget \ NuGet.targets')”/>进行发布。像这样排除dll仍然会包括lib文件夹和生成的相同dll。到目前为止,我发现唯一的选择是使用nuspec在外部创建包或将相同的命令放入后构建事件中。 - TorontoKid
可能是因为没有包含“target”参数,所以这可能不起作用。 - CJBS

0

尝试将此行代码添加至您的项目文件中,对我有效:

<None Remove="bin\**\*.*"/>

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接