Creating a NuGet package with .exe file as content file - c#

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+. I am using the Net Standard capability of creating NuGet packages on Build.
The Fonts copy perfectly to the NuGet package, but the .exe does not want to copy.
Can someone please help me get the 7za.exe to be placed in the package's content folder? 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.
Here is the .csproj file:
<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:

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.
Also, <CopyToOutputDirectory>Always</CopyToOutputDirectory> is only for local file under the local project rather than the nuget package. And it does not work for nuget package.
Solution
1) add a file called DocumentGeneration.props(<packages_id>.props and your packageID is DocumentGeneration) under build folder
2) modify your DocumentGeneration.csproj file:
.....
<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:
<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. 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.
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. It is quite strange and when you change to use <TargetFramework>, it works well. Since the issue is under TargetFrameworks with GeneratePathProperty=true. I have no other good idea for that and cannot find the good solution to fix them.
And you should report it on DC Forum or raise an issue on 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. See this similar issue.
2) Second, when I use these to distinguish between them, nuget also cannot pack it. 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. And what I know is that content and contentFiles are targets to the whole and cannot target to a targetframework under multi-targetframeworks.
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>

Related

.NET Core project - Exclude files from single file publishment

I would like to exclude nuget dlls from single file deployment but I do not know what am I doing wrong.
My current .csproj is this
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<Content Update="Newtonsoft.Json.dll">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
<Content Update="System.Security.Principal.Windows.dll">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>
</Project>
Method I tried is described here:
https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview#exclude-files-from-being-embedded

Missing assembly reference error in Azure Function

I have created an Azure funtion app but on debug mode it is unable to find below mentioned assembly
System.Private.CoreLib: Could not load file or assembly
'Microsoft.Extensions.Logging.Abstractions, Version=5.0.0.0, Culture=neutral,
PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
although I have it referenced, In output folder when I navigate to the properties for this particular file it shows file version "5.0.20.51904"
Below is my project file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Scheduler.Core\**" />
<EmbeddedResource Remove="Scheduler.Core\**" />
<None Remove="Scheduler.Core\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AzureFunctions.Autofac" Version="4.0.1" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="SyncFeed_Scheduler.Core\SyncFeed_Scheduler.Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
Since you're using .NET 6, but referencing version 5.0.0.0 for Microsoft.Extensions.Logging, there might be a mismatch between the version of your project and the dependencies that were added.
I think this could be solved by either explicitly adding a dependency to version 5.0.0.0 of Microsoft.Extensions.Logging.Abstractions
or
by updating your packages to their latest versions.
For instance: Microsoft.Extensions.Logging has a version 6.0.0.0 available.

Why does my .net sdk style project show so many files in Solution Explorer?

I'm a newb to the SDK style project format
I only have a couple of NuGet PackageReferences. Everything was behaving normally up until some point when I think I had messed with my supported platforms / build configurations.
The build succeeds. But it's a pain to edit this thing in the IDE.
Here's my *.csproj file contents:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net40;net48;</TargetFrameworks>
<Platforms>x64</Platforms>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Authors>myself</Authors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net40|x86'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net40|x64'">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Accusoft.ImageGear.PDF" Version="24.14.0" />
<PackageReference Include="Accusoft.ImageGear.Recognition" Version="24.14.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Consoto.SimpleProj.Core\Consoto.SimpleProj.Core.csproj" />
</ItemGroup>
<ItemGroup>
<NativeLibs Remove="Helpers.cs" />
</ItemGroup>
<ItemGroup>
<NativeLibs Remove="README.md" />
</ItemGroup>
<ItemGroup>
<NativeLibs Remove="Properties\Settings.settings" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>
Here is the actual project directory:

Copy unmanaged DLL from NuGet package to ASP.NET API

My problem is that I have an unmanaged library in a nuget package that I want to copy in the publish folder of the API that embed it.
Here is a StackoverFlow post that I thought it could work as the final goal seems to be the same as me :
Include Unmanaged DLL from Nuget package to web Deploy package
And here is how I tried to adapt it to my project :
<Target Name="AfterBuild" DependsOnTargets="CopyFilesToOutputDirectory">
<ItemGroup>
<MyPackageSourceFile Include="$(SolutionDir)Assemblies\libwkhtmltox\64 bits\libwkhtmltox.dll" />
</ItemGroup>
<Copy SourceFiles="#(MyPackageSourceFile)" DestinationFolder="$(OutputPath)" />
<Copy SourceFiles="#(MyPackageSourceFile)" DestinationFolder="$(ProjectDir)UnmanagedDll" />
</Target>
<Target Name="AddUnmanagedDll" AfterTargets="AfterBuild">
<ItemGroup>
<Content Include="UnmanagedDll\*.dll" />
</ItemGroup>
</Target>
But it doesn't do anything .
In a more common way I also tried something kind of this :
<ItemGroup>
<None Remove="Assemblies\libwkhtmltox\32 bits\libwkhtmltox.dll" />
<None Remove="Assemblies\libwkhtmltox\64 bits\libwkhtmltox.dll" />
</ItemGroup>
<ItemGroup>
<ContentWithTargetPath Include="Assemblies\libwkhtmltox\32 bits\libwkhtmltox.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>Assemblies\libwkhtmltox\32 bits\libwkhtmltox.dll</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Assemblies\libwkhtmltox\64 bits\libwkhtmltox.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<TargetPath>Assemblies\libwkhtmltox\64 bits\libwkhtmltox.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
Maybe it could be important to specify that all the projects are in C# .NET CORE 2.1
Please tell me if you want any further information.

.NET Core 2.0 Project Builds But Not When Referenced By Another .NET Core 2.0 Project

I'm on Ubuntu and I have two .NET Core 2.0 projects (Project Oranges.csproj and Apples.csproj). Oranges only contains references to NuGet packages, while Apples contains a reference to Oranges.
Running dotnet build -f netcoreapp2.0 Oranges.csproj succeeds! Oranges.dll now exists at /Oranges/bin/Debug/netcoreapp2.0/Oranges.dll.
Running dotnet build -f netcoreapp2.0 Apples.csproj fails with: error CS0009: Metadata file '/Oranges/bin/Debug/netcoreapp2.0/Oranges.dll' could not be opened -- PE image doesn't contain managed metadata
How can I go about referencing Oranges, which builds without issue, in Apples without issue?
Oranges.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<TargetFrameworks>netcoreapp2.0;net451;</TargetFrameworks>
<RootNamespace>Oranges</RootNamespace>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\GeneratedKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcore2.0'">
<DefineConstants>NETCORE2_0</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net451'">
<DefineConstants>NET4_5_1</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Remove="packages.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
</ItemGroup>
</Project>
Apples.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<TargetFrameworks>netcoreapp2.0;net451;</TargetFrameworks>
<RootNamespace>Apples</RootNamespace>
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>..\..\GeneratedKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<None Remove="packages.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
<PackageReference Include="System.Composition" Version="1.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Oranges\Oranges.csproj" />
</ItemGroup>
</Project>
After deleting the bin and obj folders from the project directory and rebuilding, a different error was being displayed.
CSC : error CS7027: Error signing output with public key from file 'GeneratedKey.snk' -- Assembly signing not supported. [.../Oranges/Oranges.csproj]
After some research I stumbled across a solution.
Assembly Signing Not Supported
Adding the line below to the .csproj file for each assembly that required signing resolved the issue.
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
For now it seems like if you need to sign netcore assemblies, it should be done on Windows.

Categories

Resources