Custom NuGet package not installing in wix project - nuget

I generate a NuGet that is is just a number of redist files that I want to use in one of my projects. If I install it in a C# or C++ projects, it works. But when I try to install it in a wixproj project and I get the following message:
Could not install package 'package-1.0.0'. You are trying to install this package into a project that targets 'Unsupported,Version=v0.0', 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 generate the package through a TeamCity task (using NuGet 5.6.0). When trying to generate the package with a NuGet CLI 5.8.1, I get the following warning:
*WARNING: NU5128: Some target frameworks declared in the dependencies group of the nuspec and the lib/ref folder do not have exact matches in the other location. Consult the list of actions below:
Add a dependency group for native0.0 to the nuspec*
Looked at https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu5128, one of the solutions was trying a dependencies group targetFramework, (I used "native0.0") with no success. My nuspec is as follows:
<?xml version="1.0"?>
<package>
<metadata>
<id>package</id>
<version>1.0.0</version>
<authors>package</authors>
<owners>owner</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>my package</description>
<copyright>© 2021 company, Inc</copyright>
<tags>native</tags>
</metadata>
<files>
<file src="downloads\Folder\win32.vs2017\file1.lib" target="lib\native\lib\win32.vs2017\" />
<file src="downloads\Folder\win32.vs2017\file1-debug.lib" target="lib\native\lib\win32.vs2017\" />
<file src="downloads\Folder\Include\**" target="lib\native\include\" />
<file src="build\package.props" target="build\native" />
</files>
</package>
And my props file
<Project>
<PropertyGroup>
<MyVersion>1.0.0</MyVersion>
</PropertyGroup>
</Project>
I can install other NuGet packages into wixprojects, so how I configure mine to work? Thanks.

OK I found it, the issue lies at the line
<file src="build\package.props" target="build\native" />
changing target to "build\" allows the NuGet to be loaded to any project type, included WixProj. Note that the NU5128 warning still exists though, but not an issue for me.

Related

Excluding the library being built from nuget package in .NET Standard

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.

Packing static content in Nuget for PackageReferece projects

I have a Class Library (net47) project and I'd like to pack into a nuget my dll and several files of static content (js, css, images...). I want to use this dll and the content from the consumer projects. These projects will be MVC PackageReference projects. In these projects the local static files are in the wwwroot folder.
I have tried this: NuGet ContentFiles Demystified but I get my js and css files referenced (they aren't copied to my project content).
In my nuspec I've tried with all build options: EmbeddedResource, Content, None and Compile, but these references are imported always in Compile mode. So I get a compile error when I start debugging.
I know this was possible with Package.config projects and it's very simple but all my consumer projects will be PackageReference.
This is my nuspec
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MyProject</id>
<version>1.0.0</version>
<authors>My</authors>
<owners>My</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>LVP</description>
<copyright>Copyright 2018</copyright>
<tags>Tag1 Tag2</tags>
<contentFiles>
<files include="any/any/bd.js" buildAction="content" flatten="true" copyToOutput="false"/>
</contentFiles>
</metadata>
<files>
<file src="contentFiles/any/any/bd.js" target="contentFiles/any/any/bd.js" />
</files>
</package>
I pack my nuget with this powershell command:
nuget pack MyProject.nuspec
Although I have also tried with the csproj:
nuget pack MyProject.csproj
And my source folder structure is this:
C:\...[projectPath]...\contentFiles\any\any\bd.js
Installation is ignoring my build action.
Why is always trying to compile my content files? Is there a better way to add static content to the consumer project?
Installation is ignoring my build action. Why is always trying to compile my content files? Is there a better way to add static content to the consumer project?
To answer your previous question Packing files on nuget, I have created a sample nuget package and set the build action to content for the content files, after install that nuget package, the build action would be set content:
Then I checked your .nuspec file, found it should be correct. So the issue is not related to your .nuspec file.
Besides, in the above image, you will notice that the path of the content file is nuget local cache:
C:\Users\<UserName>\.nuget\packages\
NuGet will first extract the nuget package from the local cache when install the nuget package to avoid downloading packages that are already on the computer. In other wards, although we have updated the nuget package in the local, nuget will detect the local cache first, if it found the same package in the cache, nuget will install it from cache rather than local feed.
To resolve this issue, please try to remove your nuget package in the local cache before installing the updated nuget package. Generally, when we package the same package again, wed better change the package version in the.nuspec` file so nuget local cache will not catch them.
Update for comment:
I've tried increasing the version number and deleting the nuget cache and the problem persists. My build action is always set to "C# Compiler". I just tried changing the name of the js file and the project imports the new name so I do not think it's a cache problem
After test your nuget package, I found the reason why you get that issue, we should keep the path the src and target paths are the same in the .nuspec file. Since you want set content file to the wwwroot folder, you should set the file in the wwwroot folder, then pack the .nuspec:
<contentFiles>
<files include="any/any/wwwroot/css/bd.css" buildAction="Content" copyToOutput="false" flatten="true" />
<files include="any/any/wwwroot/js/bd.js" buildAction="Content" copyToOutput="false" flatten="true" />
</contentFiles>
Following in my .nuspec scripts(Not need content node):
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>BancaDigitalViewProvider</id>
<version>1.0.37</version>
<authors>Ibercaja</authors>
<owners>Ibercaja</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Login View Provider</description>
<copyright>Copyright 2018</copyright>
<tags>Banca Digital View Provider</tags>
<dependencies />
<contentFiles>
<files include="any/any/wwwroot/css/bd.css" buildAction="Content" copyToOutput="false" flatten="true" />
<files include="any/any/wwwroot/js/bd.js" buildAction="Content" copyToOutput="false" flatten="true" />
</contentFiles>
</metadata>
<files>
<file src="contentFiles/any/any/wwwroot/css/bd.css" target="contentFiles/any/any/wwwroot/css/bd.css" />
<file src="contentFiles/any/any/wwwroot/js/bd.js" target="contentFiles/any/any/wwwroot/js/bd.js" />
<file src="bin\debug\BancaDigitalViewProvider.dll" target="lib\net47\BancaDigitalViewProvider.dll" />
</files>
</package>
This is nuget package:
https://1drv.ms/u/s!Ai1sp_yvodHfhTk5xutPpaBZLC-A
You can download it and test.
Then install it to the ASP.NET core MVC project:
Hope this helps.

Options for placing and updating PowerShell files in Project folder using NuGet

I am building a NuGet package that only contains a set of PowerShell scripts. The desired behavior is for the scripts to be placed in the project and/or solution folder, removed when the package is uninstalled, and updated when the package is updated. These scripts just need to live in the folder, and be copied to output folder (they are deploy scripts).
I've done this before using content target in a nuspec, but this does not work in netstandard/.NET Core applications (i.e., anything that uses PackageReference). The NuGet documentation mentioned the contentFiles element under the metadata element, but that also does not work with PackageReference. The only thing that I have been able to get working at all is copying the PowerShell scripts in tools/init.ps1. I have something partially working, but it doesn't handle the uninstall or upgrade path. And DTE is never fun.
Is there a way to use content files in netstandard?
If not, does there exist a sample or example of how to properly manage the NuGet lifecycle (copy file, update file, delete file)?
EDIT: This is for a console application, but it also should work in an asp.net application.
EDIT2: This is the nuspec that I have tried to do things via the contentFiles element. When I install the package, I don't see anything in project or solution.
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Test</id>
<version>1.0.0</version>
<contentFiles>
<files include="Build.ps1" buildAction="Content" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="Build.ps1" target="content" />
</files>
</package>
Thanks,
Erick
As you have noticed, NuGet packages referenced via PackageReference no longer modify the project when installing. This is also the case for .NET Framework projects using this new feature (it was made public for non-core projects in VS 2017 15.2).
The content/someScript.ps1 file is still necessary for compatibility with "classic" packages.config based project, but a new feature for PackageReference projects is contentFiles.
When packing manually using a nuspec file, copying a file on build can be done by adding a contentFiles section:
<package>
<metadata>
...
<contentFiles>
<files include="**/*.ps1" buildAction="Content" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="Build.ps1" target="content" />
<file src="Build.ps1" target="contentFiles/any/any" />
</files>
</package>
See the documentation on contentFiles for more details my example on GitHub.

How to use a native NuGet package from a managed project?

I have a managed project that uses a C-style native DLL through P/Invoke.
What is the correct way to package the native DLL so it can be added as a NuGet package to the managed project, and have the DLL be copied automatically to the output folder?
I have currently created a package using CoApp for the native DLL but i can't use it from the managed project; I get the following error when trying to add the package:
Could not install package 'foo.redist 1.0.0'. You are trying to
install this package into a project that targets
'.NETFramework,Version=v4.5.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.
Currently i only have these "pivots" in the autopkg file:
[Win32,dynamic,release] {
bin: release\foo.dll;
}
[Win32,dynamic,debug] {
bin: debug\foo.dll;
}
... do i need to add something else?
I'm in a similar situation. I opted not to use CoApp for this project, but to create a fresh nuspec/.targets file combination instead.
Inside the nuspec file I use a <files> element to list my native dlls.
In the .targets file you have access to the msbuild Condition attribute, which allows basic Configuration pivoting. In our case we always deploy 64 bit binaries, so the Platform pivot is not needed, but you could also add it if needed.
I get warnings when running nuget pack since the binaries are not inside lib, but it works fine otherwise.
Steps:
run nuget spec in the folder that contains your vcxproj
create a .build folder, in that folder create an empty mydll.targets file (match the nuspec filename)
manually populate the files similarly to the examples below;
Example mydll.nuspec:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
...your metadata here
</metadata>
<files>
<file src="x64\Release\my.dll" target="x64\Release\my.dll" />
<file src="x64\Debug\my.dll" target="x64\Debug\my.dll" />
</files>
</package>
Example mydll.targets:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\..\x64\Release\my.dll" Condition="'$(Configuration)'=='Release'">
<Link>my.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)\..\x64\Debug\my.dll" Condition="'$(Configuration)'=='Debug'">
<Link>my.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

How to exclude a folder from a nuget package

I'm using Octopack / Nuspec file to build my nuget package.
I would like to exclude certain folders which exist in the project. e.g. the "obj" file. I've been trying to get the exclude tag to work, but haven't had any luck. The nuget file builds, but the folder is still there.
Sadly, all the examples on the net specific file types and not folder.
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Foo</id>
<title>Foo</title>
<version>$version$</version>
<authors>NA</authors>
<owners>NA</owners>
<licenseUrl>http://Foo</licenseUrl>
<projectUrl>http://Foo</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Foo</description>
<releaseNotes>NA</releaseNotes>
</metadata>
<files>
<file src="obj\**\*.*" exclude="*.*" />
</files>
</package>
I needed to create a WebApplication, but deploy it as a standard ASP.NET website using "CodeFile" attributes.
This was basically to update a page in the standard ADFS login site.
<files>
<file src="**" exclude="**\*.dll;**\*.designer.cs;**\*.csproj;**\*.pdb;**\*.user;**\*.vspscc;bin\*.cs;bin\*.aspx;bin\*.config;bin\*.asax;bin\*.pubxml" />
</files>
To directly answer the posters question, if you want to exclude only the obj folder from a Nuget package use the following in your nuspec xml
<files>
<file src="*\**" target="\" exclude="obj\**\*.*"/>
</files>
Depending on the project you are building, you shouldn't need to exclude anything.
If you are building a Windows Service/Console application, OctoPack should only package your bin\release directory.
If you are building a web application, you should use a 'publish' command to have MSBuild sent the binaries and content files to a temporary folder, and OctoPack will package that. This way your obj folders and C# files won't be packaged.
For information on how to do this, please see the section on Web Application Publishing at:
http://octopusdeploy.com/documentation/packaging/octopack