Missing static file from nuget package on install - .net-core

I am trying to include a global configuration file in my nuget package. This is what I have so far:
In my csproj I have the following:
<ItemGroup>
<Content Include="appsettings.infrastructure.json">
<Pack>true</Pack>
<PackagePath>contentFiles;content</PackagePath>
<IncludeInPackage>true</IncludeInPackage>
<CopyToOutput>true</CopyToOutput>
<BuildAction>Content</BuildAction>
<copyToOutput>true</copyToOutput>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</Content>
</ItemGroup>
If I publish the package locally and unzip it I can see the file exists under contentFile folder.
The problem appears after I install my nuget package in a project. If I check bin/debug/netcoreapp3.1 I expected to see appsettings.infrastructure.json there but it is not there.
I have also tryed to do a file system search in the project folder but there does not seem to be any appsettings.infrastructure.json file saved anywhere.
Does anyone know what I can do to get this file in the bin/Debug/netcoreapp3.1 from a nuget package?

In the end I was able to achieve what I needed using the following configuration:
<ItemGroup>
<None Update="appsettings.infrastructure.json"
Pack="true"
PackagePath="contentFiles\any\any;content">
<PackageCopyToOutput>true</PackageCopyToOutput>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</None>
</ItemGroup>

Related

.target file is not applied to the .csproj file when nuget package is released

I'm making a nuget package which only includes references to a bunch of analyzers and a ruleset file.
I am struggling with getting it to add the <CodeAnalyzersRuleSet> tag to the .csproj file during package install.
After searching for a few hours I stumbled upon this 5 year old question which attempts to solve the same thing but I can't get it to work.
I've configured my NuGet project as follows:
Foo.csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Author, Description, ect removed for brevity -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AsyncFixer" Version="1.6.0">
<IncludeAssets>analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.2.0">
<IncludeAssets>analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<IncludeAssets>analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
build\Foo.targets file:
<Project>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)Foo.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
</Project>
And then the build\Foo.ruleset itself.
I run dotnet pack (dotnet version 7.0.102) in order to create the nuget package.
During package install the only thing that happens is that the package is added like a normal <PackageReference>, and I get all the analyser warnings but it doesn't add the ruleset file, and it doesn't add the <CodeAnalyzerRuleSet> tag to the .csproj file.
I've inspected the nuget package and it doesn't include the .targets and .ruleset files unless I add the following to my .csproj file as well:
<ItemGroup>
<None Include="build\**" Pack="True" PackagePath="build\" />
</ItemGroup>
This adds the files to the .nupkg but they are still not added or applied to my project during package install.
Any help or pointers are greatly appreciated.

How to require license acceptance for NuGet package through .csproj file

I'm moving away from .nuspec files for .NET Core/5/6 NuGet packages, but I cannot figure out how to set equivalent of the <requireLicenseAcceptance> element in the .csproj file.
I'm including a license file called license.txt in the package like:
<ItemGroup>
<None Include="license.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
I then set the following:
<PropertyGroup>
<PackageLicenseExpression></PackageLicenseExpression>
<PackageLicenseFile>license.txt</PackageLicenseFile>
</PropertyGroup>
This results in the following in the generated .nuspec file:
<license type="file">license.txt</license>
<licenseUrl>https://aka.ms/deprecateLicenseUrl</licenseUrl>
I'd like <requireLicenseAcceptance>true</requireLicenseAcceptance> to also be included in the generated .nuspec file, to make the contents of license.txt to pop up when installing the package.
Doh. I didn't realize it could be set through the project properties, and doing so revealed what I should have guessed: the element name is nearly the same, just prefixed with "Package".
.nuspec:
<RequireLicenseAcceptance>True</RequireLicenseAcceptance>
.csproj:
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>

DotNet Core Create Proto message common library

The use case is pretty simple:
I have two projects (ProtoProvider & ProtoConsumer).
ProtoProvider has the proto file (to_import.proto) and the message I want to use on the ProtoConsumer.
ProtoConsumer has a referrence on ProtoProvider and attempts to use the ProvidedMessage in the imported.proto.
I cannot use the the message because I get "File not found." on the impoort and "ProvidedMessage is not defined" on the compiler for the imported.proto.
EDIT2>>>
To clarify I want to create a message like google's google.protobuf.Timestamp and distribute it to another project or projects without the other projects while having the project/projects (consumer) getting the message from the dll. The whole premise of the question is how to use the message defined in to_import.proto in another project through the dll (think of it as a common.grpc lib).
EDIT1>>>
The error messages I'm getting
Is there a solution that allows the importing of the proto files from a project reference?
I'm looking for something like google's solution for the well-known-types
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
source: https://developers.google.com/protocol-buffers/docs/csharptutorial#where-to-find-the-example-code.
(Copying the proto files or moving the files is not an elegant solution).
Below I'll provide the .csproj files
ProtoProvider:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Remove="to_import.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="to_import.proto" GrpcServices="None" />
</ItemGroup>
</Project>
ProtoConsumer:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Protobuf Include="Protos\imported.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ProtoProvider\ProtoProvider.csproj" />
</ItemGroup>
</Project>
Edit>>3
Some context : The purpose of this question is to help me understand a clearer way to implement decimal once (as specified here) and reuse them in each project.
AFAIK, compiling proto files requires all files (including imports) to exist on disk.
The way this works for the well known types is that they are included in Grpc.Tools nuget package.
So its not possible to ship a class library that accomplishes what you want.
Discussion on a related grpc-dotnet issue suggests using a combination of:
Building a nuget package containing your common proto and associated class library
In the consuming code's package reference, use GeneratePathProperty to generate a variable holding the path to the nuget package content
In the consuming code's Protobuf Include, use AdditionalImportDirs to include the common proto from the nuget package.

Referencing assemblies under dotnet installation directory

Wondering if there is any legitimate reason for a .csproj to contain an assembly reference to an assembly w/ a hint path under the dotnet installation directory (default: c:\Program Files\dotnet on Windows).
In particular, the directories
packs
sdk
shared
An example of such a reference:
<ItemGroup>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions">
<HintPath>..\..\..\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\3.1.0\ref\netcoreapp3.1\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
</ItemGroup>
Surely not. This application would not work on other machines.
It looks like someone inserted code that uses Microsoft.Extensions.Configuration.Abstractions package which was not referenced and then probably applied "Quick fix" action from Resharper/Rider. Sometimes it leads not to referencing Nuget package
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.1" />
</ItemGroup>
but to referencing locally placed assembly.

Repackage 3rd party libraries as NuGet package

I am using a 3rd party library which supports .NET Core, but not .NET Standard. They provide separate binary SDKs for each platform they support; win-x86, linux-x64, etc. For each platform there is a CoolSdkDotNetCore.dll, and a coolsdk.dll/so/dylib. The CoolSdkDotNetCore.dll files are indeed different for each platform - they're all exactly the same size, but have different SHA hashes.
For my own sanity I'd like to repackage all this as a single .nupkg using runtime identifiers to pull in the right stuff for a given platform, so that I can build for Windows, docker, etc without having to swap binaries around. I have a project file like so:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>CoolSdk.NetStandard</PackageId>
<Version>1.2.3</Version>
<RootNamespace>coolsdk</RootNamespace>
<AssemblyName>coolsdk</AssemblyName>
</PropertyGroup>
<ItemGroup>
<None Pack="true" PackagePath="runtimes/win-x64/native/coolsdk.dll" Update="windows/x64/coolsdk.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="windows/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/native/libcoolsdk.so" Update="linux/x64/libcoolsdk.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="linux/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
This produces a .nupkg that appears to have everything I need, but consuming projects don't actually get a reference to the CoolSdkDotNetCore assembly. In the bin folder, I see a runtimes folder with the native components, but no lib folders (the lib folders are definitely present in the actual nupkg).
What am I missing here? Do I need to go back and write a nuspec myself instead of trying to use a csproj to generate it all for me, or is there some other trick I can use?
edit:
Changing the library paths above from runtimes/<rid>/lib/netcore to runtimes/<rid>/netcoreapp allows the lib folders to be copied to the bin folder in a consuming project, but I'm still not able to actually reference the assembly. Manually adding a reference to CoolSdkDotNetCore like:
<Reference Include="CoolSdkDotNetCore">
<HintPath>CoolSdkDotNetCore.dll</HintPath>
</Reference>
Generates MSB3245 - Could not resolve this reference....
The answer is to include a single copy of the .NET Core assembly as a "ref". Which one doesn't really matter - this assembly will never be run, only loaded by the IDE and at compile time. At runtime, the correct assembly will be loaded from the runtimes folder. As a final gotcha, nuget will not pack the same file twice; if you have two or more items in the item group with the same value for the Update key, only the last one will actually get added to the final .nupkg. So, picking at random I made a copy of the windows/x64 dll in the root of my project, and updated my csproj thusly:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>CoolSdk.NetStandard</PackageId>
<Version>1.2.3</Version>
<RootNamespace>coolsdk</RootNamespace>
<AssemblyName>coolsdk</AssemblyName>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<None Pack="true" PackagePath="ref/netcoreapp2.1/CoolSdkDotNetCore.dll" Update="CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/native/coolsdk.dll" Update="windows/x64/coolsdk.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/win-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="windows/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/native/libcoolsdk.so" Update="linux/x64/libcoolsdk.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Pack="true" PackagePath="runtimes/linux-x64/lib/netcore/CoolSdkDotNetCore.dll" Update="linux/x64/CoolSdkDotNetCore.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Resources