I'm trying to create a custom nuget package out of one of my projects. When I try to install it into the test project that references it, I receive this error:
Package "package" 1.0.5 is not compatible with uap10.0.15063 (UAP,Version=v10.0.15063). Package "package" 1.0.5 supports: net (.NETFramework,Version=v0.0)
This obviously isn't the case because the test project can run fine referencing the Project itself.
I'm building the nuget package based on my nuspec file:
<?xml version="1.0"?>
<package >
<metadata>
<id>Project</id>
<version>1.0.0</version>
<title>Project</title>
<authors>company</authors>
<owners>company</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>desc</description>
<copyright>cp</copyright>
<dependencies>
<group targetFramework="uap ">
<dependency id="Logging" version="1.0.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.NETCore" version="5.0.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.NETCore.Portable.Compatibility" version="1.0.0" exclude="Build,Analyzers" />
<dependency id="NuGet.Build" version="2.12.0" exclude="Build,Analyzers" />
<dependency id="NuGet.CommandLine" version="4.1.0" exclude="Build,Analyzers" />
</group>
</dependencies>
</metadata>
<files>
<file src="bin\Release\*.dll" target="lib" />
</files>
"Logging" is also a custom nuget package I created from the .csproj file of another project.
I've tried removing the tag, and also tried renaming the targetFramework="uap", none of that works.
What could be wrong and what can I try to get this working?
The target doesn't just rely on the NuSpec file, it would depend on the C# project and the dll itself. Go to:
Project> Rightclick> Properties> TargetFramework>
Set it to .Net or whatever. Also, change your output type to a console application rather than a windows application, if that is doable.
Also, you should create the nuspec file using:
Nuget spec < ProjectPath >
This gives us the advantage to just change the metadata for .csproj files, and copies that into the package metadata automatically.
I'm not a 100% sure if this will fix it, but this should be what needs to be done. Best of luck!
Related
I have a nuget package that consumed by internal teams.
This is the dependency section in the nuspec file
<dependencies>
<dependency id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="5.2.9" />
<dependency id="Newtonsoft.Json" version="12.0.2" />
<dependency id="System.Runtime.Caching" version="4.5.0" />
<dependency id="Polly" version="7.1.0" />
</dependencies>
When some teams installed my nuget package, they complained that some dlls were downgraded. For example:
and
Yes, the code does use newton. However, in my dependency section, I didn't hard code the exact version and from visual studio, it shows this and I think newton json version 13 should be bigger than 12.0.2?
Then for System.Memory, I didn't include that as a dependency, so how come its version got degraded?
Bear with me - this is an unusual scenario.
I have 4 projects in my solution. The top most project references the 3 other projects. None of the 3 other projects reference each other. So the architecture is like this:
Now, when I build project A I want it to produce a nuget package containing projects B, C and D but not project A. As this is in .NET standard I can configure the packages tab of project A to produce a nuget package automatically when it builds by checking the 'Generate NuGet package on build option.' Then, I can get it to include B, C and D by making the following changes to A's csproj file:
<ItemGroup>
<ProjectReference Include="..\B.csproj">
<PrivateAssets>all</PrivateAssets>
</ProjectReference>
<ProjectReference Include="..\C.csproj">
<PrivateAssets>all</PrivateAssets>
</ProjectReference>
<ProjectReference Include="..\D.csproj">
<PrivateAssets>all</PrivateAssets>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
<Version>1.0.0-beta</Version>
<PackageId>A</PackageId>
<Company></Company>
<Product>A</Product>
<Description></Description>
<Authors></Authors>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
<ItemGroup>
<BuildOutputInPackage Include="#(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')->WithMetadataValue('PrivateAssets', 'all'))" />
</ItemGroup>
</Target>
Ideally I would like to add a line to remove A.dll from the nuget package. Is this possible? A is a wrapper project which consuming code will never need to use. It is not possible for B, C and D to reference each other.
UPDATE
This is how I solved it (thanks #tom redfern)
I created a nuspec file manually:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>A</id>
<version>1.0.0-beta</version>
<authors>Foo</authors>
<owners>Bar</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>A package</description>
<dependencies>
<group targetFramework=".NETStandard2.0">
</group>
</dependencies>
</metadata>
<files>
<file src="bin\Release\netstandard2.0\B.dll" target="lib\netstandard2.0\B.dll" />
<file src="bin\Release\netstandard2.0\C.dll" target="lib\netstandard2.0\C.dll" />
<file src="bin\Release\netstandard2.0\D.dll" target="lib\netstandard2.0\D.dll" />
</files>
</package>
Then in my .csproj file for A I put the following to automatically pack it after a build:
<Target Name="__PackNuGetPackage" AfterTargets="Build">
<Exec Command="$(NugetPackage)nuget.exe pack "A.nuspec"" />
</Target>
Using patented(1) elite(2) debugging skills, we can figure out if it's possible without manually creating and maintaining a nuspec file.
First, let's start with NuGet's docs on creating a package with the dotnet CLI. It says "msbuild -t:pack is functionality equivalent to dotnet pack". So, first hint, it's just running MSBuild targets.
So, run dotnet msbuild my.csproj -pp:pp.txt. This "pre-processes" (evaluates all MSBuild import statements and writes the result into a single file) the csproj (just a standard MSBuild file). We then search for the pack target, and scroll up until we find the filename of the file that was imported. We see it's NuGet.Build.Tasks.Pack.targets, and since NuGet is open source on GitHub, I can point you to the source.
Searching NuGet.Build.Tasks.Pack.targets for Condition, to see what extensibility options the NuGet team has provided, I see <IncludeBuildOutput Condition="'$(IncludeBuildOutput)'==''">true</IncludeBuildOutput>. So, settings <IncludeBuildOutput Condition="'$(IncludeBuildOutput)'==''">false</IncludeBuildOutput> in your csproj, might work.
(1) not patented
(2) standard, but since people don't modify MSBuild files anywhere near as often as C#, the skills and tools aren't as well known
You can achieve this by using a nuspec file. Use nuspec when you need absolute control over the nuget pack process. A simple nuspec file:
<package >
<metadata>
<id>MyPackage</id>
<version>1.0</version>
<authors>Something</authors>
<owners>Something</owners>
<description>Somthing</description>
<copyright></copyright>
<dependencies>
<!-- any nuget package dependencies -->
<dependency id="AnotherPackage" version="2019.2.4.1" />
</dependencies>
</metadata>
<files>
<!-- this is where you can have complete control over which assemblies get added to your package. You can add them individually pr using wildcards. -->
<file src="..\obj\**\*.dll" target="lib" />
</files>
</package>
When you have created your .nuspec file, add it into your solution, and then make your "Nuget Pack" build step read the nuspec file rather than the project file.
I have a C++/CLI DLL that interfaces a third party native DLL. I want to pack this as Nuget.
I followed this official MS guide, this blog post and read through this other question.
So here is what I did:
First, I created the proper nuspec file:
<?xml version="1.0"?>
<package >
<metadata>
<id>CPlusPlusNativeIFace</id>
<version>1.0.4</version>
<title>CPlusPlusNativeIFace</title>
<authors>Jens Rabe</authors>
<owners>Who owns that</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>A DLL that makes a native third-party DLL available to .net</description>
<releaseNotes>foo</releaseNotes>
<copyright>errm...</copyright>
<tags>foo bar</tags>
</metadata>
<files>
<file src="..\Release\**" target="runtimes/win-x86/lib/net461" />
<file src="..\x64\Release\**" target="runtimes/win-x64/lib/net461" />
<file src="DummyAny\**" target="ref\net461" />
</files>
</package>
Then I compiled the DLL for Release x86 and Release X64. Then I created the DummyAny folder, copied the contents of the x86 one in, and used the corflags utility like in Links 2 and 3 to strip the 32 bit flag.
When I now nuget pack and nuget add, and try to reference that package in another project, I always get:
Could not install package 'CPlusPlusNativeIFace 1.0.4'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.6.1', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
I double checked that the files are right:
I have the x86 stuff in runtimes/win-x86/lib/net461
I have the x64 stuff in runtimes/win-x64/lib/net461
I have a ref/net461 folder with the manipulated dll in
But I still can't load the package.
I also tried putting the CPU specific DLLs into runtimes/win-x86/native and runtimes/win-x64/native to no avail.
What else am I missing? Does that not work for C++/CLI projects built against .net Framework?
Turned out that the official MS documentation was not usable here.
This question was/is listed as "related" here and the accepted answer there made it work for me. I used the example project on Github as a reference.
So here is how I got it to work:
Opened the project properties, went to Configuration Properties / General, selected All Configurations and All Platforms, and as Output Directory, I specified: $(ProjectDir)bin\$(Platform)\$(Configuration)\
Rebuilt the project for x86 and x64 in Release mode
Adapted the Nuspec to be like this:
<?xml version="1.0"?>
<package >
<metadata>
<id>CPlusPlusNativeIFace</id>
<version>1.0.5</version>
<title>Third Party Proxy</title>
<authors>Jens Rabe</authors>
<owners>foo</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>bar</description>
<releaseNotes>Further experimenting with nuget</releaseNotes>
<copyright>baz moo</copyright>
<tags>quux bletch</tags>
</metadata>
<files>
<file src="bin\Win32\Release\**" target="build\x86" />
<file src="bin\x64\Release\**" target="build\x64" />
<file src="bin\Win32\Release\**" target="lib\net461" />
<file src="CPlusPlusNativeIFace.props" target="build\net461" />
</files>
</package>
Added a CPlusPlusNativeIFace.props which contains the following:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Reference Include="CPlusPlusNativeIFace" Condition="'$(Platform)' == 'x86'">
<HintPath>$(MSBuildThisFileDirectory)..\x86\CPlusPlusNativeIFace.dll</HintPath>
</Reference>
<Reference Include="CPlusPlusNativeIFace" Condition="'$(Platform)' == 'x64'">
<HintPath>$(MSBuildThisFileDirectory)..\x64\CPlusPlusNativeIFace.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
Now I can do nuget pack CPlusPlusNativeIFace.nuspec and I get a Nuget package that installs correctly.
I have a project that depends on another nuget package that drops native binaries into the bin directory of my project.
I need to create a Nuget spec to package up my binaries. The simple method
<package>
<metadata>
<id>MY ID</id>
<version>$version$</version>
<title>MY TITLE</title>
<authors>ME</authors>
<owners>ME</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>MY DESC</description>
<releaseNotes>Internal Version</releaseNotes>
<copyright>Copyright 2018</copyright>
<dependencies>
<dependency id="foo" version="3.0.6" exclude="all"/>
<dependency id="bar" version="3.0.6" exclude="all"/>
<dependency id="baz" version="3.0.6.101" exclude="all"/>
<dependency id="gronk" version="11.0.2" exclude="all" />
</dependencies>
</metadata>
</package>
results in a huge nupkg with lots of dependent binaries present, along with a pile of warnings:
WARNING: Issue: Assembly outside lib folder.
An empty files element suppresses the bins, but I really need some files (namely, a readme.md and some samples) in the package as well.
When I add the following to the nuspec:
<files>
<file src=".\Content\EventsHelpers.cs" target="content\Helpers" />
<file src=".\Readme.md" target="content" />
</files>
I get the content I need, but I then get the (large) files from the dependent binaries.
How can I get the files I want while suppressing the dependent binaries?
EDIT: I can do this via the command line, however, the CI pipeline I'm using doesn't let me set the command line. So I need to do it via the nuspec.
I would like to package up an ILMerge'd dll using Nuget.
Currently I can do this however the package also includes the dlls that I've just merged and also installs some other nuget package dependencies that I have.
What I would like would be a way of specifying in the nuspec file that it should only include my merged dll, and that it should not add references to the nuget dependencies so effectively when a user installs this package they will get a single dll reference in their project and no additional nuget dependencies.
Is this possible to define within the nuspec? or is there a better approach to achieve this?
Well, while packaging the DLL(s), make sure you do not have the dependent references in the lib. Also, make sure in the nuspec file, there are no references added.
Directory Structure:
My_Package
| - lib
| - [Required Dll's]
| - My_Package.nuspec
Edit the nuspec file and remove all references:
<dependencies>
<dependency id="DLLDependency" version="1.0" />
</dependencies>
Like so:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<dependencies>
</dependencies>
</metadata>
<files>
<file src="bin\Release\mydll.dll" target="lib" />
<file src="bin\Release\mydll.pdb" target="lib" />
</files>
</package>