Visual Studio Project template add packages.config without downloading Nugets - visual-studio

I have .vstemplate file which has a reference to the Nuget like this:
<WizardExtension>
<Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
</WizardExtension>
The default behavior is that VisualStudio will go online, get needed packages, create packages.config and put references in there. But if you are offline, VisualStudio will throw an exception saying he cannot find packages and will not create package.config.
Now, is it possible to override that behavior? I want to get packages.config file regardless of the VisualStduio ability to download packages.

is it possible to override that behavior?
The answer for this questions is negative.
As we know the packages.config, The packages.config file is used in some project types to maintain the list of packages referenced by the project. If we install package to the project, nuget will add the packages.config to the project automatically. If you do not have any packages installed, the packages.config will not be added. This is the default behavior of nuget. It is so designed.
Besides, as far as I know for the template with preinstalled packages, to add preinstalled packages to your project template you need to:
1. Edit your vstemplate file and add a reference to the NuGet template wizard by adding a WizardExtension element
2. Add the list of packages to install in the project
There is no override for nuget default behavior. So If you want to override the nuget default behavior via Visua Studio template is not possible.
As a suggestion, your question is about challenging the design of nuget, you can ask this question on the GitHub.

Related

Where does the "Go To Definition" version number come from?

In Visual Studio 2019, if you right click on a symbol, you can select "Go To Definition". If the symbol is not defined in your code, it will attempt to generate the code from the dll.
When it generates this file, it puts a #region comment at the top of it. This is an example of what my region comment looks like:
#region Assembly Logging.Client, Version=6.0.1.0, Culture=neutral, PublicKeyToken=null
// C:\Users\myUserId\.nuget\packages\logging.client\7.0.0.43\lib\netstandard2.0\Logging.Client.dll
#endregion
The key part is that it says Version=6.0.1.0. I opened up the NuGet file, and, on the properties of Logging.Client.dll, the version says 7.0.0.43:
So, my question is: Where does the version number shown on the line of the #region comment get pulled from?
NOTE: I looked at this similar question, but the steps of deleting the existing packages, restarting Visual Studio and rebuilding did not resolve my issue: Latest version of nuget package still not up to date
Where does the “Go To Definition” version number come from?
It is from AssemblyVerion attribute on VS and it is set in your nuget project by the nuget author.
Please see the below interpretation.
===================================================================
I assume that logging.client nuget package is your own nuget package.(created by yourself)
This is a normal behavior of the nuget and assembly mechanism. It is not an issue and it is just defined that way by the author of the package.
These make sense and are defined by the author when the nuget package is created and can be modified by the author. It's just that they have different functions from each other to deal with the mechanism of nuget.
The Version=6.0.1.0 is the assembly version of the dll which used by framework. It is a built-in version number which is used during build or used at runtime. It can only be accessed by vs internally. To be precise, this is its real version number.
And File Version 7.0.0.43 is the version of the dll, which is used for external display and can be accessed externally.
And Product Version 7.0.0.43 means the nuget package version which also can access outside VS.
So, they all are defined by the author as he want.
See this official document about the function of these attributes: Use AssemblyVersion and AssemblyFileVersion attributes.
They all have professional terms in VS:
AssemblyVersion means 6.0.1.0, AssemblyFileVersion means File Version 7.0.0.43 and NugetVersion means Product Version 7.0.0.43. And they can be also access outside VS.
====================================================
In my side, I created a net standarad class library project called ClassLibrary1.
Right-click on your net standard class library project, right-click on your project Properties-->Package
1)
The Assembly version is used under Logging.Client, Version=6.0.1.0, Culture=neutral, PublicKeyToken=null.
When you install that package on the main project, on the main project, click on the dll on the References and you will see the internal version 6.0.1.0 under the Properties Window.
And when you install this package on a net framework project with packages.config, it will shows on the csproj file:
<ItemGroup>
<Reference Include="ClassLibrary1, Version=6.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClassLibrary1.7.0.0.43\lib\netstandard2.0\ClassLibrary1.dll</HintPath>
</Reference>
The version is used by the internal framework and at build or runtime and only be seen in VS.
2)
The Assembly File version is the file name, it shows on the dll's properties and shows outside VS as File Version which you described on the case.
3)
The Package Version is the version of the nuget package rather than the assembly dll version. They're different concepts.
In your side, it shows like this:
<ItemGroup>
<Reference Include="ClassLibrary1, Version=6.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClassLibrary1.7.0.0.43\lib\netstandard2.0\ClassLibrary1.dll</HintPath>
</Reference>
And in the dll's properties, it shows as Product Version.
Overall,it is not an issue and each of them has a meaningful and specific function. If you want to change this, you should change your nuget project's Properties-->Package as I said above, modify them as the same. Then, repack its as nuget package.

Different references to the same library in two versions of a project

I have two versions of same project. Both have a reference to the same DLL, but at different locations.
The first csproj includes:
<Reference Include="Microsoft.Expression.Effects, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\3rdParty\Microsoft\Microsoft.Expression.Effects.dll</HintPath>
</Reference>
The second csproj, which uses a NuGet package, includes:
<Reference Include="Microsoft.Expression.Effects, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\3rdParty\NuGet\packages\Microsoft.SDK.Expression.Blend.1.0.0\lib\net45\Microsoft.Expression.Effects.dll</HintPath>
</Reference>
I try to understand the reason for that. Can I use the same hint path for them? Which to choose?
First Project
The Microsoft.Expression.Effects.dll was copied to the ..\..\..\3rdParty\Microsoft\ directory manually and then referenced in Visual Studio by e.g. right-click on the project then Add > Reference... > Browse... and selecting the DLL in the corresponding directory.
Your former co-worker most likely copied the library from the local installation folder of the Expression Blend SDK (or somewhere else) to a folder in the solution, so that it is always available. Otherwise the library would be referenced from the local installation folder and everbody working on the project would have to install the SDK to the same location or else the reference would not be found.
Second Project
In the second case a NuGet package was installed to the project via packages.config. This is just one mechanism to manage packages in your project that stores the information about referenced packages in a file called packages.config in your project. To install a package, right-click the project and choose Manage NuGet Packages.... In the tab Installed, you will see that you use the Microsoft.SDK.Expression.Blend package.
A package can contain a variety of different artifcats like DLLs. The power of packages is that you can manage dependencies much more conveniently than with the common way of referencing DLLs like in the first project. When you install a package, the contained libraries will automatically be referenced in your project file. You do not add or modify these references yourself, the package manager does that for you. Let's have a look at the HintPath.
..\..\..\3rdParty\NuGet\packages\ is the root path where the packages are installed and extracted
Microsoft.SDK.Expression.Blend.1.0.0\ is the root of the concrete package in version 1.0.0
lib\net45\ is the package internal path for libraries for .NET Framework >= 4.5
Can I use same hint path for them? Which to choose?
As you can see, the question is more like whether you should use NuGet packages or reference libraries manually. This depends on the requirements of you project. In general, I recommend to use NuGet packages, since they make it much easier to manage dependencies. However, if there is no package for the library you need, you will have to add references yourself.

How do you get NuGet package restore to work on locally deployed packages stored in VSIX targeting Visual Studio 2019?

I am aware there are multiple questions on this topic already, but they all seem outdated. To clarify, I am using the "new" VSIX manifest format, and trying to follow the official instructions here: https://learn.microsoft.com/en-us/nuget/visual-studio-extensibility/visual-studio-templates
I have one project template and a couple of item templates that go with it. They all depend on deploying a NuGet package that should come bundled locally with the VSIX. I have examined the resulting VSIX file and all the files seem to be in the right place:
The project template has the required XML for declaring which packages to install:
<WizardExtension>
<Assembly>NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>NuGet.VisualStudio.TemplateWizard</FullClassName>
</WizardExtension>
<WizardData>
<packages repository="extension" repositoryId="VsixID.etc.etc">
<package id="Rx-Linq" version="2.2.5" />
</packages>
</WizardData>
The repositoryID matches the ID attribute in the .vsixmanifest file.
There is an individual Asset entry for each package, with the form:
<Asset Type="Rx-Linq.2.2.5.nupkg" d:Source="File" Path="Packages\Rx-Linq.2.2.5.nupkg" d:VsixSubPath="Packages" />
I have removed all packages.config and all the package references from the .csproj file installed by the VSIX (and even from the VSIX project itself just for good measure).
I have inspected the output VSIX and there is indeed a Packages folder in the VSIX containing all the .nupkg files. This folder is indeed unpacked and copied into the Visual Studio Extensions folder.
Despite all this, when I create a new project with the template, VS displays an error message saying: Failed to restore package from C:\users\<pathtoextensions>\Packages.
The thing is, the .nupkg files are actually present in the exact folder that the error message refers to.
I have been searching this for days and I can't seem to find any reference to best practices that actually work. It seems like these VSIX manifests are geared towards the legacy packages.config way of doing things, and there are discussions about how to extend them to use PackageReference instead.
Can anyone give any advice at all at how we are supposed to proceed going forward? Are packages not supposed to be deployed with the VSIX anymore? Are we supposed to just fill in the project with PackageReference entries and just let the user resolve them manually?
I feel like I am missing something fundamental here and any insight would be extremely valuable.
Update: I have also opened an issue on the NuGet github repository, as this is clearly a problem with the PackageRestore feature when restoring packages stored in a VSIX installer. Everything else mentioned in this question is working as intended and expected, except the package restore.
How do you actually include NuGet packages in Visual Studio Project
Templates VSIX targeting Visual Studio 2019?
Actually, there is no way to specify in a VS project template project that nuget packages can be used both using packages.config and PackageReference. Only two project templates of nuget management types can be created separately.
I have an easy way and since you have some issues with PackageReference format, you can try this funtion:
PackageReference
1) add these reference node in projecttemplate.csporj file:
<ItemGroup>
<PackageReference Include="Rx-Linq">
<Version>2.2.5</Version>
</PackageReference>
</ItemGroup>
2) When you create a project by this project template, please check these two options and VS will automatically read xxx.csproj and then recover the corresponding nuget package based on the information in it during build process.
Note: also make sure that the nuget url is checked and can be access under Package Source.
packages.config
In additon, for packages.config, you can just create a file named packages.config and then add your nuget info into it:
1)
2) add these into projecttemplate.csproj file:
<ItemGroup>
<Content Include="packages.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Reference Include="Rx-Linq, Version=2.2.5, Culture=neutral, PublicKeyToken=eb42632606e9261f, processorArchitecture=MSIL">
<HintPath>..\packages\Rx-Linq.2.2.5\lib\net472\xxxxxxx.dll</HintPath>
</Reference>
</ItemGroup>
Note: if this nuget package has dependencies, you should also add them(above steps) into packages.config and xxxx.csproj file. This funcution is a little more complicated than yours but it works. So, I recommend that you use PackageReference format.
More info you can refer to this similar issue.

How to make Visual Studio Setup Project detect nuget dependencies consistent with build?

I created a setup project using Microsoft Visual Studio Installer Projects (0.9.3, this is latest for Visual Studio 2019). After setup is executed it installs Nuget package assemblies that are different from the assemblies generated during build.
Why is it doing that and how can I make it to chose assemblies consistent with build assemblies?
My application is for 4.7.2 framework. Typical example is System.ValueTuple.dll (4.0.2)
Build retrieves assembly from:
C:\Users\.nuget\packages\system.valuetuple\4.5.0\lib\net47\System.ValueTuple.dll
Install retrieves assembly from:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7.2\Facades\System.ValueTuple.dll
While install based on 4.0.2 creates a concern but works, when I upgrade nuget package to version 4.6 (and assembly to 4.0.3) install switches to using assembly C:\Users\vgdev.nuget\packages\system.valuetuple\4.5.0\ref\net47\System.ValueTuple.dll
If you look closer, you will notice path above has \ref folder and it contains "reference" assembly. Reference assemblies are not meant to be installed and cause errors BadImageformatException.
The build after Nuget package upgrade continues to pull packages from the correct \lib folder and application works fine. So what I want to do is to make installer work consistently with build. Any advice?
Install retrieves assembly from: C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.7.2\Facades\System.ValueTuple.dll
Which way do you reference that package? I can only reproduce this issue when I add reference manually.(Right-click project=>Add reference=>Browse...) If you're doing so, please remove that reference, and add that reference back by Nuget Package Manager UI.
My application is for 4.7.2 framework. Typical example is
System.ValueTuple.dll (4.0.2). When I upgrade nuget package to version 4.6 (and assembly to 4.0.3)
I can only find it with latest 4.5.0 here. And I think it contains the assembly version 4.0.3 instead of 4.0.2.
(I guess something corrupts the process when VS recognize your assembly version cause in most machines it displays 4.0.3 while in one machine, it displays 4.0.2, quite strange...)
The build after Nuget package upgrade continues to pull packages from
the correct \lib folder and application works fine. So what I want to
do is to make installer work consistently with build. Any advice?
Cause of the issue:
This strange behavior may have something to do with Setup project. I can reproduce same situation and I found this issue only occurs when I use PackageReference format to manage nuget packages in my application.(.net 4.7.2)
PackageReference format is the new nuget package manage format after VS2017. I'm not sure if the Setup project fully support for it.
Here're two suggestions which may help:
1.I found this issue only occurs when using PackageReference format. So you can try using Packages.config format in your application. And I've checked the setup project can recognize this format well.
Uninstall all PackageReference format packages, and go Tools=>Nuget Packages Manager=>Nuget Package Manager to set the Allow format selection... to true.
Clean all nuget cache and click ok. After that delete bin and obj folders, then restart VS to add those packages back using Packages.config format.
2.If you continue to use PackageReference format. Try excluding the assembly from ref folder, and manually add that from lib folder by Add=>Assembly=>Browse.
Note: Since Setup project may not fully support packageReference format projects, actually I think #1 could be more suitable for your situation. And you can create a new simple project with packages.config format to check if the issue can be resolved by Packages.config format. Hope it helps :)
It seems that the root cause of the problem is the usage of the BuiltProjectOutputGroupDependencies target by visual studio setup projects instead of the ReferenceCopyLocalPathsOutputGroup target (see PackageReferences put ref instead of lib assemblies in the output group used by VS installer projects).
The proposed workaround is to overwrite the BuiltProjectOutputGroupDependencies target at the end in the project file of your main project:
<Target
Name="BuiltProjectOutputGroupDependencies"
DependsOnTargets="$(BuiltProjectOutputGroupDependenciesDependsOn)"
Returns="#(BuiltProjectOutputGroupDependency)">
<ItemGroup>
<BuiltProjectOutputGroupDependency Include="#(ReferenceCopyLocalPaths->'%(FullPath)');
#(ReferenceDependencyPaths->'%(FullPath)');
#(NativeReferenceFile->'%(FullPath)');
#(_DeploymentLooseManifestFile->'%(FullPath)');
#(ResolvedIsolatedComModules->'%(FullPath)');
#(ReferenceComWrappersToCopyLocal->'%(FullPath)')"/>
</ItemGroup>
</Target>

Nuget: Add file to consuming project?

I would like to add an XSD file to a Nuget package. When a project installs the Nuget package, this file should be included in the project, in order to allow Intellisense in the project's app.config file.
I can add the XSD to the Nuget package just fine, but I don't know how to make it show up in the project that uses the dependency.
Can this be done?
FWIW There are some extra sections injected in the project's app.config file (via Nuget's "transform" capability). The XSD offers Intellisense for those extra sections, and Visual Studio automatically picks up XSD schemas included in the project (or even solution) that match the declared namespace of the XML elements.
Nuget has the option to run custom install Powershell scripts that get a reference to the project that is installing the package.
Details:
http://docs.nuget.org/docs/creating-packages/creating-and-publishing-a-package#Automatically_Running_PowerShell_Scripts_During_Package_Installation_and_Removal
Here are some usage examples:
http://www.codeproject.com/Articles/209522/PowerShell-Script-Examples-for-NuGet-Packages

Resources