ClickOnce Application with PackageReferences auto to Prerequisites - c#

How can I get PackageReference packages to be included with the ClickOnce automatically?
I am trying to convert a ClickOnce application from packages.config to use PackageReferences as I have a good 30+ nuget packages (mostly dependencies) and it it makes it a lot easier to upgrade the few I actually need to reference.
The issue is that once I did that, all the nuget package assemblies are now considered "Prerequisites (Auto)" instead of "Include (Auto)", making ClickOnce deployments skip them. It also gives me the "...must be strong signed in order to be marked as a prerequisite" for any custom nuget packages.
Update:
It turned out that this didn't work at all. Assemblies like System.Runtime was not included by ClickOnce, period. There was no option to include it, and it ended up breaking the deployment (due to a FileNotFoundException for System.Runtime) even after setting all assemblies to Include manually. I had to revert back to packages.config. I'd love to see ClickOnce updated to work with PackageReferences

Related

Microsoft.NET.Sdk.Web and packages.config

I have a web project that I'm trying to convert to Microsoft.NET.Sdk.Web. When I make the change to the .csproj file, though, it seems to force it to be interpreted as a <PackageReference>-based project. Of course, <PackageReference> isn't supported in web projects, because it doesn't support persisting the results of installing a package. Web projects must use packages.config in order to support NuGet packages that inject static content into the site's space (such as NewRelic). But, after switching to Microsoft.NET.Sdk.Web, the build system seems absolutely stuck on the project being <PackageReference>-based. How do I resolve this? Surely the very existence of Microsoft.NET.Sdk.Web implies that it is possible to use packages.config with an SDK project. But, even if I set <RestoreProjectStyle>Packages.config</RestoreProjectStyle>, it still thinks the project is <PackageReference>-based. I've seen advice to try running Update-Package -Reinstall after clearing out obj, bin and .vs, but nothing I've tried has convinced it that this is not a <PackageReference>-based project:
In Visual Studio, all of the NuGet-inserted references are lumped in with other references under Dependencies\Assemblies, and the "Installed" tab of the NuGet Package Manager is empty.
What do I do?

How to handle NuGet dependency version resolution for the whole solution

I'm looking for a simple way to manage NuGet packages for the whole solution, to prevent conflicts between transitive NuGet packages when assembling all files into one installer.
When building a project all direct and indirect dependencies are analyzed and the NuGet resolution picks up the best matching version for each NuGet that is at least the same version as the lowest version and might also create binding redirects if necessary. (all good and fine)
The problem we have lately encountered was when we build the whole solution (200+ projects) at once, the resulting NuGet versions between all top level projects might not be identical. And due to the fact, that all resulting DLL and EXE files are installed into the same program files folder, the application can and will crash at runtime due to version mismatches when loading assemblies.
To better understand this issue I've created this sample repo.
The dependency graph looks like this:
Library1
Microsoft.IdentityModel.Tokens-5.2.1
Executable1
System.IdentityModel.Tokens.Jwt-5.3.0 (transitive reference: Microsoft.IdentityModel.Tokens-5.3.0)
Library1
results in: Microsoft.IdentityModel.Tokens-5.3.0
Executable2
Microsoft.IdentityModel.Tokens-5.2.1
results in: Microsoft.IdentityModel.Tokens-5.2.1
To demonstrate the problem, all projects compile to the same bin folder. When the whole solution is compiled and Executable2 is started, the application crashes, since the application expects Microsoft.IdentityModel.Tokens in version 5.2.1 but the actual version is 5.3.0.
For this constructed sample it is easy to find the problem and fix it with updating the Microsoft.IdentityModel.Tokens NuGet to the same version. (Manually, since Visual Studio Package Manager does not recognize this conflict in the consolidate tab).
But at a much greater scale it is far more complex to find those mismatches.
What we have found so far
Centrally managing NuGet package versions
Since it is not yet available, it cannot be used to solve the issue here.
Microsoft.Build.CentralPackageVersions
Unfortunately there is no IDE support for it, which makes managing NuGet packages very uncomfortable, which I would like to avoid if possible.
So my question is what is the best approach to avoid NuGet version conflicts between projects within the same solution?
We've experienced the same problem with some of our projects. We've been using Paket package manager since a couple of years and this has resolved that issue for us.
In short: you define on your solution level which packages you want to use in a file called 'paket.dependencies'. You can be very specific about versions, or let packet use the latest greatest. Then you can specify per project which NuGet package you want to use within that project in a 'paket.references' file. As the name implies, you reference to a package in the paket.dependencies file.
This will make sure, all references packages in your project will use the same package version. I hope this suits your needs as well.

Nuget Pack not including new files

I've added new models and helpers to my project, but when I run nuget pack and install the package in my project I don't see the new items in the Assembly Explorer nor can I use them. Am I missing something during the build that wouldn't include new files added to the package?
I'm using visual studio 2017 and the nuget cli
At a guess, you didn't change the package version when you changed the code and packed again. NuGet is designed such that the package id/version produces an immutable package. This means it's valid to download a package, say Newtonsoft.Json 12.0.1 from nuget.org just once, and every time you use that package in any project on the same computer you can re-use the same download, rather than having to download it every time you restore/build the project.
This causes some people problems when they're trying to test their packages. One option is to take advantage of Semantic Versioning and use 1.0.1-preview.1, 1.0.1-preview.2, so every single build of the project has a unique version number. In addition, or instead, you could use a nuget.config to set the globalPackagesFolder to a different location that gets cleared every time you change the package. If you delete the "cache", it can't reuse the old contents. But this only works if you control the machines that use the package. Once you publish the package where anyone else can use the package, you will cause problems if you change the contents, which is why nuget.org doesn't allow deleting packages, only unlisting them.
However, another possible solution is to just not use packages and simply use project references. Some people have the misconception that if you have two packages, one depends on the other, that they need to use package references to make sure NuGet dependency information flows. That's not correct. If you pack with the MSBuild pack targets (highly recommended, and the default option for SDK style projects), NuGet will always convert project references into NuGet dependencies. nuget pack will convert project references into dependencies when the other project also has its own nuspec file. When you test your project with project references, you never have to worry about immutable packages. Just pack when it's ready, but it's not needed for testing.
Maybe you have a .nuspec file (at the same level than your .csproj) that you need to edit to include new files?

How to stop build of nuget package if it has references to dev/beta packages in TeamCity?

I am using Git and would like it when I merge to my master branch it would automatically stop the process in TeamCity if my nuget-package had references to other dev/beta packages. This way I can be sure that my releases always references other release packages and no pre-releases.
Is there a way to solve this using MSBuild, Nuget or TeamCity?
EDIT:
As I understand it, this does not work out of the box using MSBuild or Nuget. Is it a good way to make a pre-build step for TeamCity that checks if the projects have pre-release references?
In the release branch of the solution that references these packages you have to restrict references to be non-pre-release only and run update references.
You can rebase the dev branch to this later on when you merge release to dev and master, then dev could deviate by using pre-release packages again.
There is nothing special required from your CI server or Nuget to support this.
But there is no real way to stop the build, unless you create a special tool that will check versions in package.config files. You can separate feeds for release and pre-release packages and limit the restore to release only feed during the build but nuget will scan all configurations and eventually will find both feeds. The only solution that I know is to use paket instead of Nuget. Paket allows you to specify feed configuration per solution. It also gives you clear indicator on which versions you have referenced and any pre-release restrictions. It also prevents you from having multiple version of the same package for different projects in one solution.
When using paket, you could check the paket.lock file for any occurrences of -unstable in it (assuming you follow SemVer for your packages). like this:
$ findstr "-unstable" paket.lock

All projects referencing sub-project must install NuGet package Microsoft.Bcl.Build (C#/Windows Phone 7)?

I'm having a particularly difficult refactoring session involving a C# solution with multiple projects in Visual Studio 2012. I needed to pull out a bunch of code into their own assemblies so that code could be shared across several projects, all in the same solution. However, no matter what I try, I get warnings for the projects that reference the new shared projects that "All projects referencing {shared project name} must install nuget package Microsoft.Bcl.Build".
I have been over the dependent projects and the shared projects with a fine-tooth comb, verifying in detail that they all use the same version and exact same DLL for the Microsoft.Bcl version 1.0.1.19 and Microsoft.Bcl.Async version 1.0.16 packages:
System.Runtime
System.Threading.Tasks
Microsoft.Threading.Task
Microsoft.Threading.Tasks.Extensions
Microsoft.Threading.Tasks.Extensions.Phone
The DLL paths are all resolved and identical. The XAP file does build but I still get that warning telling me that Microsoft.Bcl.Build is not referenced in the dependent projects, despite the fact that I can see that it is.
If I try instead to uninstall and then reinstall those two packages using NuGet for each project involved, I get references with empty paths and the warning icon for the 5 DLL references involved. For some reason NuGet adds the references but can't find the DLLs. Also, if I do this, I find myself with the problem frequently of having projects where I get the "Can't add reference" error when trying to add a reference. Then I have close and re-open the solution, and that leads to a "project failed to load" error. So I have to edit the project file manually, remove the faulty package import statements, and reload the project.
How can I fix this problem and what is the general technique for avoiding this headache in the future? Letting NuGet manage missing packages didn't help at al.
In case anyone else comes across this and #Swell's solution made you go "wtf":
I recently went through an older MVC project and updated it (updated razor, asp, http, etc. nuget packages). The project, independent of itself, built fine, but when i went to publish it failed with the OP's errors.
It turns out it's because I didn't update the *.Tests project associated with it (should have figured, though not sure why Tests is that closely tied to the project). So, to fix:
Right-click the Solution and manage nuget packages.
Go through all the packages that were updated in the web project and apply them to the other projects as well (each "Update" will display a tree with the applicable projects, I was fine just OKAY-clicking through).
Rebuild.
You should now be good and it shouldn't bark at you. Hope that helps others.
I just came throught the same issue and a bug is opened here: http://nuget.codeplex.com/workitem/3268
What I've done is the following, I added to the solution level the package Microsoft.Bcl.Build
In my dev env if you don't have the package loaded, just right click the solution and select manage nuget packages, you see a yellow bar with a restore button, just click it and you will be fine.
In my build script before compiling the project I run this command:
.\myproject\.nuget\NuGet.exe install .\myproject\.nuget\packages.config -OutputDirectory .\myproject\packages
This will restore solution level packages and you will be fine.
This should be fixed by the end of this summer in version 2.7 according to the issue report

Categories