VisualStudio Online and pack Nuget packages - c#

I'm creating a repository in Visual Studio OnLine when I have some class libraries. I want to create (pack) and push for each of them a Nuget package in my private repository.
In a project there is a dependency on Microsoft.ApplicationInsights. If I create on my computer a package, it is working fine. If I try to do the same on Visual Studio Online I have an error:
The nuget command failed with exit code(1) and
error(NuGet.CommandLine.CommandLineException: Unable to find
'Microsoft.ApplicationInsights.2.6.4.nupkg'. Make sure the project has
been built.
This is the full error:
NuGet Version: 4.1.0.2450 Attempting to build package from
'Vu.Common.Logging.AppInsightsEvent.csproj'. MSBuild auto-detection:
using msbuild version '15.6.85.37198' from 'C:\Program Files
(x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\bin'. Use
option -MSBuildVersion to force nuget to use a specific version of
MSBuild. Packing files from
'D:\a\1\s\Vu.Common\Vu.Common.Logging.AppInsightsEvent\bin\Release'.
Using 'Vu.Common.Logging.AppInsightsEvent.nuspec' for metadata. Add
file
'D:\a\1\s\Vu.Common\Vu.Common.Logging.AppInsightsEvent\bin\Release\Vu.Common.Logging.AppInsightsEvent.dll'
to package as 'lib\net462\Vu.Common.Logging.AppInsightsEvent.dll'
Found packages.config. Using packages listed as dependencies
NuGet.CommandLine.CommandLineException: Unable to find
'Microsoft.ApplicationInsights.2.6.4.nupkg'. Make sure the project has
been built. at
NuGet.CommandLine.ProjectFactory.AddDependencies(Dictionary`2
packagesAndDependencies) at
NuGet.CommandLine.ProjectFactory.ProcessDependencies(PackageBuilder
builder) at NuGet.CommandLine.ProjectFactory.CreateBuilder(String
basePath, NuGetVersion version, String suffix, Boolean buildIfNeeded,
PackageBuilder builder) at
NuGet.Commands.PackCommandRunner.BuildFromProjectFile(String path)
at NuGet.CommandLine.PackCommand.ExecuteCommand() at
NuGet.CommandLine.Command.ExecuteCommandAsync() at
NuGet.CommandLine.Command.Execute() at
NuGet.CommandLine.Program.MainCore(String workingDirectory, String[]
args)
My configuration is easy. I added two Nuget, the first it is packing my nuget and the second push in the repository it.
I tried different configuration and also created manually the nuspec file but without result.
Any ideas? What is the right way to pack and deploy nugget packages?
Update
During the build the error I saw is like that:
Then I tried to create the same package on my local folder. I've only removed OutputDirectory, NonInteractive and the initial path. I can create the package without problem.

According to the error message, seems your nuget packages failed to download the referenced nuget packages from url.
Instead of using customize nuget command, you could try to use Package: NuGet extension directly and select Pack NuGet packages and try agian.
Also enable Verbose Debug Mode to get more detail log by add system.debug=true for troubleshooting and narrow down the issue.

Related

How to trace resolving process of nuget package references

I have a solution with multiple projects in it (~400). A lot of them are using newtonsoft.json library. Some of them are using different version of the library. In a host project for web app, there is no direct reference to newtonsoft.json. Also, I believe, there are dependencies to packages that depend on newtonsoft.json. However, in bin folder of that project I began getting newtonsoft.json 9.0 instead of newtonsoft.json 11.0 as it used to be. And it causes load exception in runtime due to invalid version. If I include direct reference to newtonsoft.json 11.0, it still puts version 9.0 in the bin folder even if I clear all bin,obj folders. I use PackageReference for managing dependencies, and everything is in .net 4.6.1; I use binding redirects to resolve issues with different versions of the same library.
My question is if there is a way to diagnose how particular dll of package ref appears in bin folder? I would like to see some sort of comprehensive trace of dependency resolution so that I can fix it without using "trial and error" approach.
Upd.
Actually, thanks guys for pointing to structured logging. You are the best! So the issue was that one of the project had <OutputPath> pointing to the bin folder of the host project. So when the project was built, it was overriding binaries in the host project. Apparently, build order has changed due to continuous reference shuffling and the project with wrong <OutputPath> started building last. To find this out 1) I Newtonsoft.Json was recorded in DoubleWrites section 2) analyzing location from double writes I found out in _CopyFilesMarkedLocal section
Copying file from "\VenomousProject\bin\Debug\Newtonsoft.Json.dll" to "HostProject\bin\Debug\Newtonsoft.Json.dll".
That was it.
You can try MSBuild Binary and Structured Log Viewer (https://msbuildlog.com/)
build the project from command line with msbuild -bl - you will get msbuild.binlog
open the binlog with the log viewer and use the dll name as a search term
inspect all records related to the dll and backtrack a place (project and msbuild' target) where the wrong file version is taken.
With PackageReference, NuGet will write a file named project.assets.json in the project's obj folder. This file is used by the rest of the build to determine what files from packages should be included in the build, but it also contains a list of all the packages that were selected, what version was selected, and what dependencies each package has (package id and version). This is the closest thing to dependency resolving debugging that NuGet has.
In the file, search for "Newtonsoft.Json/, and you should find which version of Newtonsoft.Json that NuGet selected. Remove the / and replace it with ", and you can find all the packages that have dependencies on Newtonsoft.Josn. Search for newtonsoft.json.dll to find all the packages that ship that dll in its package (sometimes package authors perfer to ship multiple dlls in their package, rather than adding dependencies, which prevents NuGet from being able to version selection.
If there are multiple packages with which contain a dll with the same filename, NuGet will tell MSBuild about all of them, and it's up to MSBuild to select which one to use (pass to the compiler and copy to the bin/publish directory). As #Serg wrote in their answer, you can use binlogs (with the -bl argument on any MSBuild command, including dotnet restore or dotnet build). NuGet's inner workings are not output to MSBuild, so when your package graph has multiple packages that list Newtonsoft.Json as a dependency, it won't tell you why NuGet chose a specific version, but binlogs are very useful at debugging other build related issues.

MSBuild -t:pack ProjectReference

I have a C# solution that contains two net472 projects: Foo.csproj, and Bar.csproj.
The projects are in classic format (no SDK version).
The projects use PackageRefernce as package management.
Foo.csproj depends on Bar.csproj.
Bar.csproj isn't a nuget package.
I want to create a nuget package of Foo.
I followed this instruction, and I execute the command msbuild -t:pack Foo.csproj, that produces the Foo.nupkg file.
The problem is that Foo.nupkg contains Foo.dll, but it doesn't contain Bar.dll.
So, when I try to install via NuGet the package Foo, I receive the following error:
Unable to resolve dependency 'Bar'.
What I'm missing?
I hope I have provided all the necessary info.
I had the same problem as explained above.
My goal was to automate Azure Devops nuget package generation of two dependant assemblies and publishing one NuGet package.
One of the steps in the Azure pipeline, actually includes execution of msbuild with -t:pack arguments.
After reading this thread: about advanced technics of creating NuGet packages, I've concluded that it's better to have 2 different packages.
So I have ended up with modifiying inital pipeline job with additional 2 steps ("set assembly manifest data" and "Copy files") as on the picture.
One set (of these steps) for A assembly and the other set for B assembly.
At the end result was two published Nuget packeges to the feed, where installation of A package in another project resulted auto installation of dependent B referenced package.
Hope this will help further others.

How to add additional dll to Roslyn analyzer NuGet package?

In short: I referenced additional dll in my code-analyzer. All good with unit-tests & while I debugged analyzer by F5. But when this analyzer was installed as NuGet package to real project, it can't find that additional dll & crashes.
#Optional reading - detailed version of question:
I've wrote my code-analyzer (say MyAnalyzer). It finds some types forbidden to use in client code. And its codeFix replaces these types by allowed replacement-types from my custom dll (say myCustom.dll). I've added this dll as dependency to MyAnalyzer.CodeFixes project & to MyAnalyzer.Test unit tests project of analyzer solution.
And it works fine when started by F5 (at special opened VisualStudio instance) & successfully passes all unit tests.
But when I:
built NuGet package of analyzer (by building MyAnalyzer.Package - a special project from VS template to produce analyzer NuGet packege)
then coppied it to NuGet local feed (local path registered at NuGet manager as packages source)
& then install this NuGet package from that local feed to real project by NuGet manager,
diagnostics rise fine, but when I try use codefix, which should replace some type by one from that myCustom.dll, my analyzer can't find myCustom.dll & throws an exception:
System.IO.FileNotFoundException : Could not load file or assembly 'myCustom, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
I probably add reference to my dll at wrong way (not working with analyzers)? Or may be (its only my assumption) any dependency of NuGet package should be NuGet package too?
#Additional info (may be it matters):
Build output looks Ok: folder with build output contains that my referenced dll.
I copied it as is to NuGet local feed folder.
But cache folder of installed package, which appears after installing package, doesn't contain that myCustom.dll. It contains (except for a few small files) only:
C:\Users\user1\.nuget\packages\myanalyzer\0.0.1\MyAnalyzer.0.0.1.nupkg
& 2 dlls:
C:\Users\user1\.nuget\packages\myanalyzer\0.0.1\analyzers\dotnet\cs\MyAnalyzer.dll
C:\Users\user1\.nuget\packages\myanalyzer\0.0.1\analyzers\dotnet\cs\MyAnalyzer.CodeFixes.dll
And when I try to manually put my dll there - to package cahe folder, analyzer still throws exception.
And when I try to manually put my dll there - to package cahe folder,
analyzer still throws exception.
That is not a right way. The issue describes that you have some wrong old version of the nuget under the global cache. Since you do not change the new release version to another, the old wrong nuget package is the same as the new release one, nuget package manager always install the version under the global cache first and if it does not find the same version of the nuget package by nuget package manager UI, it will then download the specific, different version from the nuget package feed into global cache C:\Users\xxx\.nuget\packages\, and then install it into your project.
You should try the following steps to make a careful check:
1) check your new packed nuget package myanalyzer under the local feed. And you can use 7zip tool to unpack myanalyzer.0.0.1.nupkg.
Check whether the myCustom.dll is under the folder myanalyzer.0.0.1\analyzers\dotnet\cs\.
Also, I found the error is
Could not load file or assembly 'MyCustomDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
I am curious why the dll is not right. And the error is that you have used MyCustomDll.dll rather than MyCustom.dll. You should check your Analyzers file and make sure that use the right named file.
Then, repack the new nuget project, ensure the new release nuget package is right.
2) delete the cache folder under C:\Users\xxx\.nuget\packages\myanalyzer.
If you use packages.config nuget management format, and you should also delete the folder under your solution folder <solution_folder>\packages\myanalyzer.0.0.1.
3) after that, reinstall the right version under package manager UI.
Update
Sorry for that I ignored the pack steps of your analyzer nuget project.
Actually, if the dlls are referenced by your current nuget project, the pack button has no duty to pack these dlls into the nupkg file automatically.
You have to pack it manually, no matter how you did, you have to modify the csproj file.
Solution
Use your target or another is to add these under myanalyzer.package.csproj file:
<ItemGroup>
<None Include ="$(TargetDir)mycustom.dll" pack="true" PackagePath="analyzers/dotnet/cs"></None>
</ItemGroup>
Then, repack the project, clean the nuget caches, then install the new one.
I wonder, why all dlls are present twice at installed NuGet package:
as separate files at packages\myanalyzer\0.0.1\analyzers\dotnet\cs &
as part of archive in .nupkg file. Or all content of installed package
folder, except .nupkg file, is just unpacked .nupkg?
The nupkg is the file is the original version of your nuget package. It is generated by your pack nuget project. And the folder which contains the nupkg is a local nuget feed.
The folder is like nuget.org source. And this folder which contains it is the nuget package source(nuget download nuget files from this path and then download the nupkg and unpack it under C:\Users\xxx\.nuget\packages)
Besides, the C:\Users\xxx\.nuget\packages is the global nuget cache folder.
So it restores the download nuget packages from the local feed, and if you installed the old same version of the myanalyzer nuget package before, it will always install the old same version like 1.0.0 from the cache folder no matter you have packed a new release same 1.0.0 version. Because the version is the same, so VS IDE will judge that there is already has a same nuget package under the cache folder, it always install the old one rather than the new one.
So that is why I recommended that you should delete all cache files under that folder. Avoid VS installing older cache packages all the time. Or you should set a new version for the updated nuget package like 2.0.0.
This is the explanation and the difference between these two Folders.
One is the original local nuget package feed. Another is the storage path and unpacking path of the package downloaded from the local nuget package feed, and it will record the previously downloaded packages. You need to pay attention to this.

Could not resolve this reference. Could not locate the assembly "Microsoft.Practices.EnterpriseLibrary.Common"

I have a project that use the nuget package EnterpriseLibrary.Common version 5.0.505.0, but when I restore the package in another computer the next warning message appear.
Could not resolve this reference. Could not locate the assembly
"Microsoft.Practices.EnterpriseLibrary.Common".
I look for the fisical path and I do not found the dll, there is only a xml file. "Microsoft.Practices.EnterpriseLibrary.Common.xml"
It should not be included in the nuget package?
or should be in GAC?
if so, how do I install it?
This is something specific to your environment. Normally if you have the nuget package EnterpriseLibrary.Common version 5.0.505.0 referenced in your solution and you open the solution on a new machine and restore nuget packages, the dll is also restored.
You can try running this in Package Manager Console:
Update-Package EnterpriseLibrary.Common -Reinstall
and hope that it helps. If it does not, the nuget package itself (*.nupkg) should be located in
packages\EnterpriseLibrary.Common.5.0.505.0\EnterpriseLibrary.Common.5.0.505.0.nupkg
Make a copy of this file and change the extension to .zip. Open it with your favorite archive manager (Windows Explorer will do) and find all the dlls it contains in the lib folder inside the archive. Microsoft.Practices.EnterpriseLibrary.Common.dll is one of them.

Why the compilation error from Team City after adding Newtonsoft.Json?

I have a service that was sending bad DateTime data due to use of the JavascriptSerializer. I used Nuget to add Newtonsoft to the project, and utilized that. Here's the only place it's utilized in the code (old way, then new):
374
- var messageString = new JavaScriptSerializer().Serialize(messageDetails);
374
+ var messageString = Newtonsoft.Json.JsonConvert.SerializeObject(messageDetails);
Below is an error that occurs during the Team City build:
Consumer\MetricTrackingMQServiceConsumer.cs(374, 49): error CS0122: 'Newtonsoft.Json.JsonConvert' is inaccessible due to its protection level
Consumer\MetricTrackingMQServiceConsumer.cs(374, 61): error CS0117: 'Newtonsoft.Json.JsonConvert' does not contain a definition for 'SerializeObject'
The project compiles fine locally. Why is it failing in Team City?
As you're using NuGet to include the dependency here's the workflow I strongly suggest to avoid these type of issues.
Ensure that your reference to the Newtonsoft DLL is pointing at the NuGet packages folder.
Exclude the NuGet packages from source control.
Add a "Nuget Installer" type build step before your solution build step to restore all the NuGet packages referenced by the solution.
This has a number of advantages but most importantly given your current issue, it ensures that the version of the DLL referenced by your solution is available and in the correct location.
The following steps fixed this for me:
On your nuget installer step in your build: You may need to "Disable looking up packages from local machine cache"
Uninstall the newtonsoft reference via nuget in your project. Open the csproj file in a text editor and manually delete any remaining references to newtonsoft in there. Save the csproj file, reload your project
Reinstall newtonsoft via nuget
post your changes to your repository (git or whatever you have)
Rerun the teamcity build

Categories

Resources