Nuget files not accessible from the referenced project - nuget

I recently converted from nuspec to package reference using csproj file. While doing so, I have encountered the following situation.
My nupkg contents look like this. When I reference this nuget in any of my projects, I do not see the json files and cannot access them. Where are those files and what am I doing wrong?
My nuget csproject has the following code for including the json files. If I keep the PackagePath to "content;contentFiles" I could see the json files in the referenced project. However, they are following the folder structure rather than a flat one like the one in the screenshot.
<ItemGroup>
<None Include="xyz\abx\aturesMap.json" CopyToOutputDirectory="Always" Pack="True">
<PackageCopyToOutput>true</PackageCopyToOutput>
<PackagePath/>
</None>

Related

Nuget does not include ancillary (license) files in output

We are using nuget to package an older library (dll) file for use in our enterprise nuget share. We have done this successfully with numerous other libraries.
With the current one I'm packaging, there is a license file (.lic file) that must be copied along with the dll and xml files, but which is not getting included with the build output. Here is my <files> section from .nuspec:
<files>
<file src="Lic\test.lic" target="lib" />
<file src="net4.0\test.dll" target="lib" />
<file src="net4.0\test.XML" target="lib" />
</files>
This results in all three files being packaged in the lib folder of .nupkg file (as expected). However, when the consuming project is built, the .lic file is missing from the \bin folder:
licence file missing from output
I've tried many variations of the <file> tag, and have even tried variations of the <contentFiles><files...> tag.
Does anyone have any idea how to get the .lic file to be copied with the compiled output?
Edit 6/30/2020:
Ok I have tried the technique suggested by #thatguy, but it is not working. The .lic file is not getting included in the bin folder when the project is compiled; it is not even referenced in the .nupkg file when I unzip it.
I verified my visual studio project is using PackageReferences by opening the project file. That the .lic file is missing from the .nupkg suggests an error in the .nuspec file content. Here is screenshot of my nuspec file. Is there still something awry with the tags or content?
Screenshot of my .nuspec content
If you use PackageReference instead of packages.config, then you can use the contentFiles tag. It has to be contained in the metadata tag. Place content files like test.lic in a subfolders any\any\, otherwise it will not work. The following snippet will cause the content files to be copied to the output folder when building the project.
<contentFiles>
<files include="any/any/test.lic" buildAction="None" copyToOutput="true" />
</contentFiles>
You can upgrade existing .NET Framework projects to use PackageReference. .NET Core projects will have it by default. If you cannot upgrade or you do not want to use contentFiles because of its contraints, you can also use props and targets files for MS Build. One the one hand, it is much more complex to implement and get right, on the other hand, it offers maximum flexibility and enable you to use features of MS Build which is much more beyond copying files. You can find an example for your use-case here.

Output Directory of native dll bundled with NuGet

I am trying to build a NuGet package that includes native DLLs which are to be placed in the output folder when a project uses the package. I have tried to use the several suggestions from this question, but I am always running in the same problem.
My current NuGet package layout is like this:
\build
packageId.targets
file1.dll
file2.dll
\lib
\netstandard1.4
assembly.dll
The contents of packageId.targets is:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)\*.dll"/>
<None Include="#(NativeLibs)" Link="$(RecursiveDir)$(Filename)$(Extension)">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
This should, according to the answers of the other questions, lead to my DLLs being placed in the bin\Debug directory of the project using the package. However, they are not. Instead, they are placed in bin\Debug\packages\packageId\build.
Now I have experimented a lot, and I noticed more and more strange behavior which I cannot make any sense of:
If I move the DLLs to the root of the NuGet package (like one answer suggests) and change the .targets file accordingly, they are not copied at all. There also is no error message.
If I change the .targets file to only reference file1.dll in both Include= and Link=, both files get copied anyway.
So I wondered if some policy just ignores the .targets file and copies whatever is in build to that path in the output folder, but when I remove the .targets file, the DLL files will not get copied anymore.
Now I understand even less what's happening.
What do I need to change to get the DLLs copied right into bin\Debug?
The new way to handle runtime-specific assents in NuGet is to use the runtimes folder to place native assets:
\lib
\netstandard2.0
ManagedWrapper.dll
\runtimes
\win-x86
\native
NativeThing.dll
\win-x64
\native
NativeThing.dll
\linux-x64
\native
libNativeThing.so
\osx-x64
\native
libNativeThing.dylib
If the package is consumed from a .NET Framework project, you may need to add a reference to the Microsoft.NETCore.Platforms package wich provides the runtime graph (runtimes.json) for NuGet to provide proper RID mappings if you don't use base RIDs (e.g. win10-x64 falls back to win-x64 resources).

Nesting files in Nuget package without PowerShell

The title says it all. I have files that I want to nest during the installation of a NuGet package but can't use PowerShell scripts since they won't be run any longer (see here).
Are there any other ways to achieve this goal?
UPDATE: By nested I mean like *.resx and *.Designer.cs or *.xaml and code-behind files *.xaml.cs. I know I can achieve that by adding a <DependentUpon> element in the *.csproj file but I don't know how I can add that element without using PowerShell.
UPDATE2: init.ps1 runs the first time a package is installed in a solution. That won't cut it though. I would need the script to run when the package is installed into a project just like install.ps1 was run up to NuGet3.
UPDATE3: What I want to do is to add 3 files into the Properties folder of the target projects (Resources.resx, Resources.tt and Resources.Designer.cs). They are a replacement for the usual resources implementation. These files are installed by the nuget package when it is added to the project.
This is the part of the *.nuspec file that adds them to the Content folder of the package. As only one of them is actually content (the others being an Embedded Resource and Compile respectively) it would be nice to be able to set their build actions accordingly but one step at a time.
<files>
<file src="Properties\Resources.resx" target="content\Properties\Resources.resx" />
<file src="Properties\Resources.tt.pp" target="content\Properties\Resources.tt.pp" />
<file src="Properties\Resources.Designer.cs" target="content\Properties\Resources.Designer.cs" />
</files>
As these files are added to the projects I want the nesting inside the *.csproj file and not happen via a separate *.props file if that is somehow possible.
Packages can add MSBuild items like this to a project by using a .props file in the package. It would contain the same content that you would put into the .csproj file.
The down side of this is that the content cannot be modified by the user. If you need to modify the user's actual project file and copy content to the project folder you would have to include a .targets file in your package and set BeforeTargets="Build" on your target. This would give you a chance to run before build and make changes as needed.
The build folder works for both packages.config and PackageReference (NETCore SDK) projects. You can find more out about it here: https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package

Building content only/dependency meta package using csproj and nuget (teamcity build)

I have a project that pulls in dependencies and adds some code templates, but isntalling the resulting nuget causes my project to get polluted by an empty dll.
I tried making a .nuspec, but I find the documentation lacking on this topic.
I ran nuget spec and deleted the irrelevant metadata, then added a files section, with a single file entry:
<file src="src/*.pp" target="dst/" />
But the resulting .nuget still contains an empty dll under lib/net462.
The pp file is placed into Content/src in the nuget, but I am guessing the target will be applied properly when installed.

Is there an alternative to contentFiles with projects that use packages.config?

I have a nuget package with content that I want to be copied to the build output when users install my package. There is support for this: NuGet ContentFiles Demystified in NuGet v3.3. However, it only works in projects that use project.json. The contentFiles are not copied to my build output when I have a project that uses packages.config.
Is there an alternative or workaround I could use in order to make my NuGet package work on projects that use either a project.json or packages.config?
A quick search on StackOverflow reveals the following question which I think covers what you are asking for:
Set content files to "copy local : always" in a nuget package
You can put your files inside a Content directory inside the NuGet package.
In your .nuspec file:
<file src="css\mobile\*.css" target="content\css\mobile" />
When you install that into your project it will add the css\mobile directory to your project and the files inside that directory.
However that only adds the files to the project. In order to get them to be copied to your output directory you would either need to use a PowerShell script to modify the project item's copy local information.
An alternative, possibly a better way, would be to use a custom MSBuild .targets file. This will be added as an import to your project and then inside your .targets file you can add the files you want and specify the copy to output information directly as though it was part of your project. NuGet .nupkg file content:
\build
\Net45
\MyPackage.targets
\Foo.txt
MyPackage is the id of the NuGet package above.
Inside the .targets file you specify the files (e.g. Foo.txt).
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="Foo.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>