How prevent copy unnecessary libraries on publish - c#

I have three simple projects:
SampleApp.Cli1
SampleApp.Cli2
SampleApp.Lib
SampleApp.Cli1 use Microsoft.Extensions.Configuration directly
SampleApp.Cli2 uses Microsoft.Extensions.Configuration through SampleApp.Lib
SampleApp.Cli1:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<OutputPath>../_out1</OutputPath>
<TargetFramework>netcoreapp3.1</TargetFramework>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
</PropertyGroup>
</Project>
SampleApp.Cli2:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<OutputPath>../_out2</OutputPath>
<TargetFramework>netcoreapp3.1</TargetFramework>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SampleApp.Lib\SampleApp.Lib.csproj" />
</ItemGroup>
</Project>
SampleApp.Lib:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
</ItemGroup>
</Project>
Script for publishing:
#echo off
if exist "%~dp0_out1" (
rd "%~dp0_out1" /s /q
)
if exist "%~dp0_out2" (
rd "%~dp0_out2" /s /q
)
dotnet publish "%~dp0SampleApp.Cli1/SampleApp.Cli1.csproj"
dotnet publish "%~dp0SampleApp.Cli2/SampleApp.Cli2.csproj"
After build
publish dir for SampleApp.Cli1 contains this files
web.config
SampleApp.Cli1.deps.json
SampleApp.Cli1.dll
SampleApp.Cli1.exe
SampleApp.Cli1.pdb
SampleApp.Cli1.runtimeconfig.json
publish dir for SampleApp.Cli2 contains this files
SampleApp.Lib.pdb
web.config
Microsoft.Extensions.Configuration.Abstractions.dll
Microsoft.Extensions.Configuration.dll
Microsoft.Extensions.Primitives.dll
SampleApp.Cli2.deps.json
SampleApp.Cli2.dll
SampleApp.Cli2.exe
SampleApp.Cli2.pdb
SampleApp.Cli2.runtimeconfig.json
SampleApp.Lib.dll
Question
For some unknown for me reason, the publication understands that for SampleApp.Cli1 Microsoft.Extensions.* must be taken from the shared runtime(Program Files\dotnet\shared\Microsoft.AspNetCore.App), but does not understand the same for SampleApp.Cli2. Of course, I understand that the matter is most likely in SampleApp.Lib(in real application it was Microsoft.Extensions.Hosting.WindowsServices).
In my situation, I have to build all libraries from sources that go into the publish folder. In real application Microsoft.Extensions.* libraries much more, and I would not really like to build all libraries from asp net core runtime.
Is any way to prevent copy(publish) Microsoft.Extensions.* libraries?
Sdk: 3.1.6

Related

dotnet pack generates dll if I add a readme file?

CSProj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>Org.AppName</PackageId>
<PackageVersion>1.0.0</PackageVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
</Project>
If I exclude the PackageReadmeFile, it complains when uploading it needs a README, although if I add PackageReadmeFile then dotnet pack generates a dll not a nuget package file?

NuGet Centrally Manager Packages - NU1604 Error on build with dotnet build

I am trying out the Centrally Managed Packages feature in NuGet and keep getting the following error in all of my projects:
NU1604: Project dependency Ardalis.SmartEnum does not contain an inclusive lower bound. Include a lower bound in the dependency version to ensure consistent restore results.
I have the following defined in the .csproj
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Ardalis.SmartEnum" />
</ItemGroup>
</Project>
and the following Directory.Build.props defined in the root folder beside my .sln file
<Project>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Ardalis.SmartEnum" Version="2.1.0" />
</ItemGroup>
</Project>
An interesting thing is that I am able to get the project to build in Rider, but not with the dotnet build command. Both when running in the root folder and in the project folder. I have tried dotnet clean on both the solution and the project.
For clarity the file structure is:
root/
├─ Directory.Build.props
├─ MySolution.sln
├─ src/
│ ├─ ProjectFolder/
│ │ ├─ ProjectFolder.csproj
What am I missing here?
I was missing a key piece of information.
Centrally managed packages should not be defined in Directory.Build.props.
They should be defined in Directory.Packages.props
Directory.Packages.props
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Ardalis.SmartEnum" Version="2.1.0" />
</ItemGroup>
</Project>

PackageReference to project in the same Solution/git repository

At the moment I'm trying to setup a solution with a implementations class library and an abstractions project. I want to have both packages on nuget.org.
Normally when you're just using ProjectReferences, you'd only have to point to the csproj:
Random.Abstractions:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>Abstractions for the Randomizer</Description>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<Company>MyCompany</Company>
<Authors>Pieterjan De Clippel</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
</ItemGroup>
</Project>
Random
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Random.Abstractions\Random.Abstractions.csproj" />
</ItemGroup>
</Project>
But off course when you build a nuget package, you don't want the Random.Abstractions.dll to be inside the Random nuget package, but the Random package to depend on the Random.Abstractions package. But since this package doesn't exist yet, you can't build it yet.
Microsoft is able to solve this problem like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
</PropertyGroup>
<ItemGroup>
...
</ItemGroup>
<ItemGroup>
...
<Reference Include="Microsoft.AspNetCore.DataProtection.Abstractions" />
</ItemGroup>
</Project>
So this is neither a ProjectReference nor a PackageReference, which is why they are able to:
build and test the solution locally (so there they'd be acting as ProjectReferences)
push the code to GitHub and let the GitHub Actions create and publish the new version of the packages, while they depend on each other (so there they'd be acting as PackageReferences)
I've tried doing the same in my solution, but the project containing the concrete implementations is unable to find the abstractions project:
MyCompany.Random.Abstractions.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>Abstractions for the Randomizer</Description>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<Company>MyCompany</Company>
<Authors>John Wick</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
</ItemGroup>
</Project>
MyCompany.Random.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="MyCompany.Random.Abstractions" />
</ItemGroup>
</Project>
So no ProjectReference (we don't want the dll to be in this nuget package), no PackageReference (the package is not yet published), but just Reference.
But somehow I'm still getting an error that the Abstractions assembly cannot be found:
I've checked the NuGet.config but there's nothing really special in there.
How can I use the Reference tag in a dotnet-based project, in order to reference to code while building/testing locally and reference the new package while building/pushing in a CI pipeline?
Reference to Microsoft.NET.Sdk documentation
Update:
#pinkfloydx33, you're right. I can see only one assembly/dll inside the nupkg:
Update 2:
I added the Microsoft.SourceLink.GitHub package to my project, and after downloading/unzipping the new version of my package I can see the following nuspec:
Where 77b181a24a83e46b4c80376f65bb305bedba1a64 is the commit ID.
Thanks for the tip.

Create a self contained exe with a COMReference

I am trying to publish a self contained exe file.
Sadly all my google work was not helpful. I have a COM reference in my code to the WindowsInstaller.
So far this is my csproj file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>MSI_Info</RootNamespace>
<RuntimeIdentifiers>win10-x64;win10-x86</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<COMReference Include="WindowsInstaller">
<Guid>{000C1092-0000-0000-C000-000000000046}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>1033</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
</Project>
Code is hosted here https://github.com/SmuSmu/MSI-Info
Not so easy to get a simple exe file :)

Multiple binaries from a single DotNet Core project configuration file

I have code for a bunch of CLI utilities made to test/showcase a network library. The library is compiled into an assembly - DotNet Core DLL.
I have several CLI examples showing how to use the library, for example, one search is using paging functionality and another returns everything etc. Basically, each is a short standalone CLI program.
I have CS source files and csproj file targeting dotnet core. Below is the configuration:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="mylib>
<HintPath>../../bin/Debug/netstandard2.0/publish/mylib.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
I want to have one executable for each source file e.g. PGSample.cs will get compiled into PGSample.exe etc. How would I about achieving this?
I'm afraid you can have only one output per csproj, but there are some tricks to manage multiple projects easier.
You can put common build settings into a file named Directory.build.props in the root project folder, e.g.:
<Project>
<PropertyGroup>
<Authors>Your name here</Authors>
<Company>Your company</Company>
<Product>The project name</Product>
<Version>1.6.18</Version>
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
<!-- e.g. bin/Release_net48/foo_cli/ -->
<OutputPath>$(SolutionDir)bin\$(Configuration)_$(TargetFramework)\$(MSBuildProjectName)</OutputPath>
<TargetFrameworks>net48</TargetFrameworks>
</PropertyGroup>
</Project>
Then, add one subdirectory and minimal csproj file per output, e.g.
libfoo/libfoo.csproj: <Project Sdk="Microsoft.NET.Sdk" /> (really, that's it!)
foo_cli/foo_cli.csproj:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup><OutputType>Exe</OutputType></PropertyGroup>
<ItemGroup><ProjectReference Include="..\libfoo\libfoo.csproj" /></ItemGroup>
</Project>
Iff you have only one library and a lot of executables, you might even add your executable settings to the Directory.build.props:
[..]
<PropertyGroup Condition=" $(MSBuildProjectName) != 'libfoo'">
<OutputType>exe</OutputType>
</PropertyGroup>
<ItemGroup Condition=" $(MSBuildProjectName) != 'libfoo'">
<ProjectReference Include="..\libfoo\libfoo.csproj" />
</ItemGroup>

Categories