NuGet does not copy content and does not run install.ps1 - nuget

I am trying to create a Nuget package using NuGet.exe 1.2.20311.3, and the following specification:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
<id>SharedWebsitesMvc</id>
<version>1.0.16</version>
<authors>Ted</authors>
<owners>Ted</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Shared Websites Mvc Library</description>
<frameworkAssemblies>
<frameworkAssembly assemblyName="mscorlib" targetFramework=".NETFramework4.6" />
<frameworkAssembly assemblyName="System" targetFramework=".NETFramework4.6" />
<frameworkAssembly assemblyName="System.Core" targetFramework=".NETFramework4.6" />
<frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.6" />
</frameworkAssemblies>
</metadata>
<files>
<file src="D:\Projects\Websites\SharedWebsitesMvc.dll" target="lib\net46\SharedWebsitesMvc.dll" />
<file src="D:\Projects\Websites\SharedWebsitesMvc.xml" target="lib\net46\SharedWebsitesMvc.xml" />
<file src="D:\Projects\Websites\Scripts\backtalk.js" target="js\backtalk.js" />
<file src="D:\Projects\Websites\Scripts\shared.js" target="js\shared.js" />
<file src="D:\Projects\Websites\SharedWebsitesMvcInstall.ps1" target="tools\Install.ps1" />
</files>
Nuget generates a package, and package explorer shows the following:
js
backtalk.js
shared.js
lib
net46
SharedWebsitesMvc.dll
SharedWebsitesMvc.xml
tools
Install.ps1
The Install.ps1 looks like this:
param($installPath, $toolsPath, $package, $project)
Write-Host "hello from install.ps1"
When I install this package into an MVC project, the script files are not copied and no output is displayed from the script in the package console. I am using Visual Studio 2016.
What is wrong with my NuGet specification?

The JavaScript files need to have a target that starts with Content:
<file src="D:\Projects\Websites\Scripts\backtalk.js" target="Content\js\backtalk.js" />
<file src="D:\Projects\Websites\Scripts\shared.js" target="Content\js\shared.js" />
The above does not support project's that use a project.json file. For those you need to use a ContentFiles section in your .nuspec file:
<contentFiles>
<files include="D:\Projects\Websites\Scripts\backtalk.js" buildAction="None" />
</contentFiles>
The .nuspec file looks OK for the install.ps1 PowerShell script for projects that use a packages.config file. Note that install.ps1 is not supported in projects that use project.json files.

Related

Is there a way to create a nuget package consisting multiple projects including some which dont have reference to any other project?

I have following dll's among others in a solution:
Base
Core
Basics
R1
R2
Types
I want to put them all in one single nuget package and upload it to Azure DevOps -> Artifacts. Is this possible ?
Is there a way to create a nuget package consisting multiple projects
including some which dont have reference to any other project?
The short answer is Yes, We could use .nuspec to pack up the assemblies:
Download the nuget.exe.
Create a new project.
Open a cmd and switch path to nuget.exe
Use command line: nuget spec "PathOfProject\TestDemo.csproj"
Open the TestDemo.csproj.nuspec file and modify it and add the assemblies as file; below is my .nuspec file:
<?xml version="1.0"?>
<package>
<metadata>
<id>TestDemo</id>
<version>1.0.0</version>
<authors>Tester</authors>
<owners>Tester</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>TestDemo</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>Copyright 2017</copyright>
<tags>Tag1 Tag2</tags>
</metadata>
<files>
<file src="ThePathOfTheDll\*.Base.dll" target="lib\net461" />
<file src="ThePathOfTheDll\*.Core.dll" target="lib\net461" />
<file src="ThePathOfTheDll\*.Basics.dll" target="lib\net461" />
<file src="ThePathOfTheDll\*.R1.dll" target="lib\net461" />
<file src="ThePathOfTheDll\*.R2.dll" target="lib\net461" />
<file src="ThePathOfTheDll\*.Types.dll" target="lib\net461" />
</files>
</package>
Use pack command: nuget pack TestDemo.csproj.nuspec
Besides, if your project is donet project, you can edit your csproj file, add an ItemGroup to include the dlls as below: This will pack the other dlls along with your current project dll in the nuget package:
<ItemGroup>
<Content Include="<path to other dll>">
<Pack>true</Pack>
<PackagePath>lib\$(TargetFramework)</PackagePath>
</Content>
</ItemGroup>

Creating a nuget package to add a reference into type library

I am wanting to create a nuget that adds a dll reference into the type libary of visual studio and .net. Now normally you would use reserve32 nameof.dll is there a way to achieve this with nuget package explorer
I would normally run this command from an administrative comcmand prompt
regsvr32 nameof.dll
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MyPackage</id>
<version>1.0.0</version>
<title></title>
<authors>User</authors>
<owners>User</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>My package description.</description>
</metadata>
<files>
<file src="build\_._" target="build\_._" />
<file src="content\Sage50ApplicationObject.chm" target="content\Sage50ApplicationObject.chm" />
<file src="content\SageDataObjects2017.chm" target="content\SageDataObjects2017.chm" />
<file src="content\SageDataObjectsv24.chm" target="content\SageDataObjectsv24.chm" />
<file src="content\SageDataObjectsv25.chm" target="content\SageDataObjectsv25.chm" />
<file src="lib\SdoEng170.tlb" target="lib\SdoEng170.tlb" />
<file src="lib\SdoEng200.tlb" target="lib\SdoEng200.tlb" />
<file src="lib\SdoEng220.tlb" target="lib\SdoEng220.tlb" />
<file src="lib\SdoEng230.tlb" target="lib\SdoEng230.tlb" />
<file src="lib\SdoEng240.tlb" target="lib\SdoEng240.tlb" />
<file src="lib\SdoEng250.tlb" target="lib\SdoEng250.tlb" />
<file src="lib\sg50SdoEngine170.dll" target="lib\sg50SdoEngine170.dll" />
<file src="lib\sg50SdoEngine200.dll" target="lib\sg50SdoEngine200.dll" />
<file src="lib\sg50SdoEngine220.dll" target="lib\sg50SdoEngine220.dll" />
<file src="lib\sg50SdoEngine230.dll" target="lib\sg50SdoEngine230.dll" />
<file src="lib\sg50SdoEngine240.dll" target="lib\sg50SdoEngine240.dll" />
<file src="lib\sg50SdoEngine250.dll" target="lib\sg50SdoEngine250.dll" />
</files>
</package>
I then should be able to see it in the references section of the com in visual studio as per below its to help me speed up not always having to register these each project.
As per below screen shot
Edit 2
I found this code which should allow it to process the command through powershell.
param($installPath, $toolsPath, $package, $project)
regsvr32 Join-Path $toolsPath '\mycom.dll' /s
$project.Object.References | Where-Object { $_.Name -eq "MYCOMLib" } | ForEach-Object { $_.EmbedInteropTypes = $false }
But where do i place this code and how can I adjust it to take into account all my dlls. As they all require regsvr32.dll to be called.
see Can NuGet distribute a COM dll?
I could never find where this is clearly documented on the MS site, but here's what I did:
Create a folder and add the nuspec file to it.
Then create a subfolder: tools.
Put your dlls in the tools folder.
Name your Powershell script file 'install.ps1' and put it in the tools folder.
The nuget package will run the ps1 script during its install process. Put the dlls in a 'lib' folder (sibling to 'tools') if you want to add them as references to the project you're importing the nuget package into.
see also https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package#create-the-nuspec-file

nuspec contentFiles Example

Yesterday NuGet 3.3 was released (release notes) and there is a new contentFiles element supported (docs). However, I can't seem to get this working.
I'm using the NuGet.exe as the build process. It is updated to v3.3. I have also updated my Visual Studio to 2015 Update 1 and rebooted.
Here is my nuspec file (Hello.world.nuspec):
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata minClientVersion="3.3">
<id>Hello.world</id>
<version>1.0.0</version>
<title>Greeting library</title>
<authors>Timothy Klenke</authors>
<description>Greetings for the world</description>
</metadata>
<contentFiles>
<files include="*" />
</contentFiles>
</package>
I run from the command line using the following:
nuget.exe update -Self
nuget.exe pack Hello.world.nuspec
And I get the following:
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'. Attempting to build package from 'Hello.world.nuspec'. The element 'package' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd' has invalid child element 'contentFiles' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd'. List of possible elements expected: 'files' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd'.
I think I am running all the latest versions that should support the new contentFiles XML element, but the tools don't seem to know about it. What am I missing? I know the files include attribute is garbage, but does someone have a full example nuspec file using the new contentFiles element?
Element <contentFiles> has to be inside <metadata> according to NuSpec reference. So it should look like this:
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata minClientVersion="3.3">
<id>Hello.world</id>
<version>1.0.0</version>
<title>Greeting library</title>
<authors>Timothy Klenke</authors>
<description>Greetings for the world</description>
<contentFiles>
<files include="*" />
</contentFiles>
</metadata>
</package>
#Timothy,
You were right. It is a combination having a metadata/contentFiles element as well as a definition in the files element. I have a C# test utility library that needs to include PowerShell files in a projects output/bin folder when it is referenced using a PackageReference. I will include the XML below for you. I think you will be able to derive what you need from it.
Special Note:
Be sure to get your language and framework values right in the path (i.e. yours will something like cs/net45/YourFile.cs). I'm using any/any/MyFile.psm1 because I want the file to be treated as language and platform agnostic. If I don't, I get code analysis errors on build.
Additionally, placing the files in a 'contentFiles' directory is important.
(language and framework options defined in the .nuspec reference documentation)
https://learn.microsoft.com/en-us/nuget/reference/nuspec#including-content-files
<package>
<metadata>
<id>SomeLibrary</id>
<version>$version$</version>
<title>SomeLibrary</title>
<authors>Somebody</authors>
<owners>Somebody</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Some library that does things I enjoy.</description>
<releaseNotes />
<copyright>Copyright 2017</copyright>
<tags>PowerShell Testing</tags>
<contentFiles>
<files include="any/any/SomePS.psd1" buildAction="none" copyToOutput="true" />
<files include="any/any/SomePS.psm1" buildAction="none" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="*.dll" target="lib\net461" />
<file src="*.pdb" target="lib\net461" />
<file src="SomePS.psd1" target="contentFiles\any\any" />
<file src="SomePS.psm1" target="contentFiles\any\any" />
</files>
</package>
The "/" matters in the node. It will not work if used:
<files include="any/any/x.dll" buildAction="None" copyToOutput="true" flatten="true" />
It must be:
<files include="any\any\x.dll" buildAction="None" copyToOutput="true" flatten="true" />
But it doesn't work for .NET framework??!

I need to add a dll to a nuget package without referencing it and modify the csprof file to include the dll

I have a nuget package with one dll that needs to be referenced and one dll that just needs to be included in the output of the program.
Relavent info from nuspec:
<references>
<reference file="dllA.dll" />
</references>
</metadata>
<files>
<file src="dllA.dll" target="lib" />
<file src="dllB.dll" target="content" />
</files>
I have been playing around with the install.ps1 file to try to modify the .csproj to add this section:
<Content Include="<path to dllB.dll">
<Link>dllB.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
I don't know how to get the path to dllB and I'm having trouble modifying the .csproj during the nuget package install with powershell.

Issue with nuget config transformation files

I am creating a nuget package that besides other files contains also configuration files such as: f1.config, f2.config etc. These configuration files are in turn referenced in the web.config file.
As these configuration files may or may not exist in the project where this package would be installed, I have renamed them to f1.config.transform, f2.config.transform.
While the installation of the package runs flawlessly in all possible scenarios, uninstalling is not working as expected in one particular case. Namely, if let say the config file f2.config did not exist in the project before the installation, it will not be removed when uninstalling the package.
Any ideas?
EDIT: NuGet spec file
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>WCFServicesProxyPackage</id>
<version>1.0.3</version>
<title />
<authors>Shkelzen a. Saraqini</authors>
<owners>Shkelzen a. Saraqini</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>WCF services proxy package.</description>
<language>en-CA</language>
<references>
<reference file="WCFServices.Proxy.dll" />
</references>
</metadata>
<files>
<file src="content\config\system.serviceModel.behaviors.Local.config.transform" target="content\config\system.serviceModel.behaviors.Local.config.transform" />
<file src="content\config\system.serviceModel.behaviors.Production.config.transform" target="content\config\system.serviceModel.behaviors.Production.config.transform" />
<file src="content\config\system.serviceModel.behaviors.QA.config.transform" target="content\config\system.serviceModel.behaviors.QA.config.transform" />
<file src="content\config\system.serviceModel.bindings.Local.config.transform" target="content\config\system.serviceModel.bindings.Local.config.transform" />
<file src="content\config\system.serviceModel.bindings.Production.config.transform" target="content\config\system.serviceModel.bindings.Production.config.transform" />
<file src="content\config\system.serviceModel.bindings.QA.config.transform" target="content\config\system.serviceModel.bindings.QA.config.transform" />
<file src="content\config\system.serviceModel.client.Local.config.transform" target="content\config\system.serviceModel.client.Local.config.transform" />
<file src="content\config\system.serviceModel.client.Production.config.transform" target="content\config\system.serviceModel.client.Production.config.transform" />
<file src="content\config\system.serviceModel.client.QA.config.transform" target="content\config\system.serviceModel.client.QA.config.transform" />
<file src="content\Web.config.transform" target="content\Web.config.transform" />
<file src="lib\net40\WCFServices.Proxy.dll" target="lib\net40\WCFServices.Proxy.dll" />
</files>
</package>
How do you install/uninstall the config files? Could you share some PowerShell snippets from your scripts (assuming you're using PowerShell install.ps1/uninstall.ps1 scripts in your package)?
Maybe you can force the removal of the files: http://www.timvw.be/2011/10/18/force-the-removal-of-a-file-with-powershell/
Also, it is likely this functionality will be improved in the future, if and when XDT becomes OSS for NuGet to benefit from it.