简体   繁体   English

使用.exe文件作为内容文件创建NuGet package

[英]Creating a NuGet package with .exe file as content file

I have been trying to include the 7za.exe file from the installed 7ZipCLI NuGet package into a project, of which I want a NuGet package to be created. I have been trying to include the 7za.exe file from the installed 7ZipCLI NuGet package into a project, of which I want a NuGet package to be created. The NuGet package targets both.NET Standard2.0 and .NET Framework v4.6.1+. NuGet package 同时针对 .NET Standard2.0 和 .NET Framework v4.6.1+。 I am using the Net Standard capability of creating NuGet packages on Build.我正在使用 Net Standard 功能在 Build 上创建 NuGet 包。

The Fonts copy perfectly to the NuGet package, but the.exe does not want to copy. Fonts完美复制到NuGet package,但是.exe不想复制。

Can someone please help me get the 7za.exe to be placed in the package's content folder?有人可以帮我将 7za.exe 放在包的内容文件夹中吗? It does not need to be the content folder, I just want it copied to the consuming project's output directory on Installing of the NuGet package.它不需要是内容文件夹,我只是希望在安装 NuGet package 时将其复制到使用项目的 output 目录。

Here is the.csproj file:这是 .csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <Version>1.1.13</Version>
    <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeAssemblyReferences</TargetsForTfmSpecificBuildOutput>
    <Platforms>x86</Platforms>
    <PackageId>DocumentGeneration</PackageId>
    <Authors>Me</Authors>
    <Company>Me</Company>
    <Product>DocumentGeneration</Product>
    <Description>A library for creating PDF documents.</Description>
    <PackageTags>Report Certificate Generator iText PDF</PackageTags>
    <AssemblyVersion>1.0.0</AssemblyVersion>
    <FileVersion>1.0.0.0</FileVersion>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
    <OutputPath>$(SolutionDir)Output\</OutputPath>
    <DocumentationFile>$(SolutionDir)Output\DocumentGeneration.xml</DocumentationFile>
    <GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
    <DebugType>full</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
    <OutputPath>$(SolutionDir)Output\</OutputPath>
    <DocumentationFile>$(SolutionDir)Output\DocumentGeneration.xml</DocumentationFile>
    <GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
    <DebugType>embedded</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="Resources\Arial.ttf">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <PackageCopyToOutput>true</PackageCopyToOutput>
      <CopyToPublishDirectory>true</CopyToPublishDirectory>
    </Content>
    <Content Include="Resources\HelveticaNarrow.otf">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <PackageCopyToOutput>true</PackageCopyToOutput>
      <CopyToPublishDirectory>true</CopyToPublishDirectory>
    </Content>
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)' == 'net461'">
    <PackageReference Include="iTextSharp" Version="5.5.13.2" />
  </ItemGroup>
  <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="itextsharp.netstandard" Version="5.5.13.2" GeneratePathProperty="true" />
    <PackageReference Include="System.Drawing.Common" Version="5.0.0" GeneratePathProperty="true" />
    <PackageReference Include="System.Resources.Extensions" Version="5.0.0" />
    <PackageReference Include="System.Resources.ResourceManager" Version="4.3.0" />
  </ItemGroup>
  
  <ItemGroup>
    <PackageReference Include="7ZipCLI" Version="9.20.0" GeneratePathProperty="true" IncludeAssets="all" />
    <PackageReference Include="System.Text.Encoding" Version="4.3.0" />
    <PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
  </ItemGroup>

  <ItemGroup>
    <None Include="readme.txt" pack="true" PackagePath="." />
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <None Include="$(Pkgitextsharp_netstandard)\lib\netstandard2.0\itextsharp.netstandard.dll">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <PackageCopyToOutput>true</PackageCopyToOutput>
      <Visible>false</Visible>
    </None>
    <Content Include="$(Pkg7ZipCLI)\tools\7za.exe">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <PackageCopyToOutput>true</PackageCopyToOutput>
      <PackagePath>content\Resources;contentFiles\any\any\Resources</PackagePath>
      <Visible>false</Visible>
    </Content>
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'net461'">
    <Content Include="$(Pkg7ZipCLI)\tools\7za.exe">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <PackageCopyToOutput>true</PackageCopyToOutput>
      <PackagePath>content\Resources;contentFiles\any\any\Resources</PackagePath>
      <Visible>false</Visible>
    </Content>
  </ItemGroup>
    
  <ItemGroup>
    <Compile Update="Properties\Resources.Designer.cs">
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Update="Properties\Resources.resx">
      <Generator>PublicResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>
    
  <Target Name="IncludeAssemblyReferences">
    <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
      <BuildOutputInPackage Include="$(Pkgitextsharp_netstandard)\lib\netstandard2.0\itextsharp.netstandard.dll">
        <Visible>false</Visible>
      </BuildOutputInPackage>
    </ItemGroup>
  </Target>

</Project>

Also here is what the NuGet package looks like currently:这也是 NuGet package 目前的样子:

当前的 NuGet 包

If you just want the file be output into the bin folder under packages.config , you should have to use <packages_id>.props file and <PackageCopyToOutput>true</PackageCopyToOutput> is only for PackageReference .如果您只想将文件 output 放入packages.config下的 bin 文件夹中,则必须使用<packages_id>.props文件,并且<PackageCopyToOutput>true</PackageCopyToOutput>仅适用于PackageReference

Also , <CopyToOutputDirectory>Always</CopyToOutputDirectory> is only for local file under the local project rather than the nuget package.此外<CopyToOutputDirectory>Always</CopyToOutputDirectory>仅适用于本地项目下的本地文件,而不适用于 nuget package。 And it does not work for nuget package.它不适用于 nuget package。

Solution解决方案

1) add a file called DocumentGeneration.props (<packages_id>.props and your packageID is DocumentGeneration ) under build folder 1)build文件夹下添加一个名为DocumentGeneration.props的文件(<packages_id>.props 并且您的 packageID 是DocumentGeneration

在此处输入图像描述

2) modify your DocumentGeneration.csproj file: 2)修改您的DocumentGeneration.csproj文件:

.....

      <Content Include="$(Pkg7ZipCLI)\tools\7za.exe">
           <CopyToOutputDirectory>Always</CopyToOutputDirectory>
           <PackageCopyToOutput>true</PackageCopyToOutput> 
           <PackagePath>content\Resources;contentFiles\any\any\Resources</PackagePath>
           <Visible>false</Visible>
       </Content>

        <None Include="build\*.*">
           <Pack>true</Pack>
           <PackagePath>build</PackagePath>
        </None>
    
    
.....

3) add these on the DocumentGeneration.props file: 3)DocumentGeneration.props文件中添加这些:

<Project>
    <ItemGroup>

        <None Include="$(ProjectDir)Resources\*.*">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>           
        </None> 
    </ItemGroup>

</Project>

Or或者

<Project>
        <None Include="$(MSBuildThisFileDirectory)..\content\**\*.*">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <Link>Resources\%(FileName)%(Extension)</Link>
        </None>
 </Project>

4) repack your lib project. 4)重新打包你的lib项目。 When you install this new release version, you should first clean nuget caches or delete all cache files under C:\Users\xxx(current user)\.nuget\packages .安装此新版本时,应首先清理 nuget 缓存或删除C:\Users\xxx(current user)\.nuget\packages下的所有缓存文件。

Besides , there is a similar issue .此外,还有一个类似的问题

Update更新

I think it is an issue for multi-targetframeworks feature.我认为这是多目标框架功能的问题。 And if you use GeneratePathProperty for the pkg, the property will lost on the other targetframework.如果您对 pkg 使用GeneratePathProperty ,则该属性将在其他目标框架上丢失。 It is quite strange and when you change to use <TargetFramework> , it works well.这很奇怪,当您更改为使用<TargetFramework>时,它运行良好。 Since the issue is under TargetFrameworks with GeneratePathProperty=true .由于问题是在TargetFrameworks下使用GeneratePathProperty=true I have no other good idea for that and cannot find the good solution to fix them.我对此没有其他好主意,也找不到解决它们的好方法。

在此处输入图像描述

And you should report it onDC Forum or raise an issue on github .您应该在DC 论坛上报告或在 github 上提出问题 And when you finish it, you could share it here.当你完成它时,你可以在这里分享它。

1) Also , since you use multi-targetframeoworks, you should also use buildCrossTargeting folder on the nupkg to enable the props file. 1)另外,由于您使用多目标框架,您还应该使用 nupkg 上的buildCrossTargeting文件夹来启用道具文件。 See this similar issue . 看到这个类似的问题

2) Second, when I use these to distinguish between them, nuget also cannot pack it. 2)其次,当我用这些来区分它们时, nuget 也无法打包。 And it is so strange, and I have to remove that condition.这太奇怪了,我必须删除那个条件。

<ItemGroup  Condition="'$(TargetFramework)'=='net461'">
...
<None Include="7za.exe" Pack="true" PackagePath="content\Resources;contentFiles\any\any\Resources">
...
</ItemGroup>


<ItemGroup  Condition="'$(TargetFramework)'=='netstandard2.0'">
...
<None Include="7za.exe" Pack="true" PackagePath="content\Resources;contentFiles\any\any\Resources">
...
</ItemGroup>

My thought is that content and contentFiles node target to the whole project and you cannot specify a condition with targetframeworks during packing them as content.我的想法是contentcontentFiles节点针对整个项目,并且在将它们打包为内容期间,您不能使用targetframeworks指定条件。 And what I know is that content and contentFiles are targets to the whole and cannot target to a targetframework under multi-targetframeworks .我所知道的是contentcontentFiles是整体的目标,不能针对multi-targetframeworks 下的 targetframework targetframework

You should use these:你应该使用这些:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
    </PropertyGroup>

...
    <ItemGroup>
        <PackageReference Include="7ZipCLI" Version="9.20.0" GeneratePathProperty="true">
        </PackageReference>
    </ItemGroup>

...

    <Target Name="FunCopy" BeforeTargets="PrePareForBuild">
        <Copy SourceFiles="$(Pkg7ZipCLI)\tools\7za.exe" DestinationFolder="$(ProjectDir)"></Copy>
    </Target>

    
    <ItemGroup>
        <None Include="$(ProjectDir)7za.exe" Pack="true" PackagePath="content\Resources;contentFiles\any\any\Resources">
            <PackageCopyToOutput>true</PackageCopyToOutput>
            <Visible>false</Visible>
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </None>
    </ItemGroup>
    
    <ItemGroup>

        <None Include="build\*.*" Pack="true" PackagePath="build;buildCrossTargeting"></None>
        
    </ItemGroup>
        
...
</Project>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM