Issue with nuget config transformation files - nuget

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.

Related

Why is my Nuget-lib not available from .NetStandard 2.0?

I've created the Nuget "Uplink.NET" with the following Nuspec:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/01/nuspec.xsd">
<metadata>
<id>uplink.NET</id>
<version>1.3.1</version>
<title>Connector to the storj-network</title>
<authors>TopperDEL,Storj Labs Inc.</authors>
<owners>TopperDEL,Storj Labs Inc.</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<projectUrl>https://github.com/TopperDEL/uplink.net</projectUrl>
<iconUrl>https://storj.io/press-kit/Storj-symbol.png</iconUrl>
<description>This library provides access to the secure and decentralised Storj-network. It allows you to:
- create and delete buckets
- upload and download files
It is - like Storj itself - open source and developed on GitHub.</description>
<releaseNotes>Initial release</releaseNotes>
<copyright>(c) 2019 TopperDEL, Storj Labs Inc.</copyright>
<tags>storj tardigrade storage decentralised secure bucket file xamarin android</tags>
<repository type="git" url="https://github.com/TopperDEL/uplink.net.git" />
<contentFiles>
<files include="uplink.NET\bin\release\netstandard2.0\storj_uplink.dll" buildAction="None" copyToOutput="true" flatten="true" />
</contentFiles>
</metadata>
<files>
<file src="uplink.NET.targets" target="build\uplink.NET.targets" />
<file src="uplink.NET.Droid\bin\Release\uplink.NET.Droid.dll" target="lib\MonoAndroid7.0\uplink.NET.Droid.dll" />
<file src="uplink.NET.Droid\bin\Release\uplink.NET.Droid.dll" target="lib\MonoAndroid7.1\uplink.NET.Droid.dll" />
<file src="uplink.NET.Droid\bin\Release\uplink.NET.Droid.dll" target="lib\MonoAndroid8.0\uplink.NET.Droid.dll" />
<file src="uplink.NET.Droid\bin\Release\uplink.NET.Droid.dll" target="lib\MonoAndroid8.1\uplink.NET.Droid.dll" />
<file src="uplink.NET.Droid\bin\Release\uplink.NET.Droid.dll" target="lib\MonoAndroid9.0\uplink.NET.Droid.dll" />
<file src="uplink.NET\bin\Release\netstandard2.0\uplink.NET.dll" target="lib\netstandard2.0\uplink.NET.dll" />
<file src="uplink.NET\bin\Release\netstandard2.0\uplink.NET.dll" target="netstandard2.0\uplink.NET.dll" />
<file src="uplink.NET\bin\Release\netstandard2.0\uplink.NET.dll" target="lib\uap10.0.16299\uplink.NET.dll" />
<file src="uplink.NET\storj_uplink.dll" target="storj_uplink.dll" />
</files>
</package>
I can add it to a NetStandard2.0 class library, but it gets Added as a PackageReference with the following entries:
<PackageReference Include="uplink.NET" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
I now cannot access the objects within my lib. But the same Nuget is working with Xamarin.Android and UWP.
Can someone help with this?
Yes, when a package is a development dependency, as our NuGet docs say:
With PackageReference (NuGet 4.8+), this flag also means that it will
exclude compile-time assets from compilation.
A linked page further explains:
when package's developmentDependency is true, then set PrivateAssets
to All and ExcludeAssets to Compile on PackageReference item in
project, while:
Installing package through VS NuGet UI or PMC
Executing dotnet add
package command Migrating existing project from packages.config to
PackageReference
Even though developmentDependency is true, don't do anything treat it as normal
PackageReference, while:
Manually adding PackageReference item in project to add a package
Upgrading existing VS instance from previous version to latest (which started supporting developmentDependency)

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

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

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.

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??!

How to include content files in project if resources are specified in nuspec file?

I am creating a nuget package definition to include a whole bunch of DLLs. Some of them are needed only at design time, so according to the Nuspec Reference I created a references section to specify which assemblies should be referenced by the project.
I also specified a list of files to be included. Some of these files being the libraries, one is a PowerShell script that gets executed during package installation and one is simply a content file that should be added to the project lateron.
These are the relevant sections of my nuspec file:
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<!-- Most of the metadata stuff left out for brevity -->
<dependencies />
<references>
<reference file="MyComponent.dll" />
<reference file="MyComponent.Data.dll" />
<reference file="MyComponent.Other.dll" />
</references>
</metadata>
<files>
<file src="MyPackage.install.ps1" target="tools\install.ps1" />
<file src="MyComponent.ReadMe.txt" target="ReadMe.txt" />
<file src="C:\Some\Path\MyComponent.*.dll" target="lib\net45" />
<file src="C:\Some\Path\MyComponent.*.xml" target="lib\net45" />
<file src="C:\Some\Other\Path\*.dll" target="lib\net45" />
</files>
</package>
Now here is my problem: The licenses.licx file does not get included in the project when the package is being installed. What must I change to achieve this?
Adding it to the references section does not work, because, well, it is no library...
I found out what was wrong. To include a file into the targeted project the file needs to be placed in a sub-folder named content in the package's folder structure:
The correct files section of the nuspec file would then look like this:
<files>
<!-- other files omitted for brevity -->
<file src="MyComponent.ReadMe.txt" target="content\ReadMe.txt" />
</files>