We're just dipping our toes into the VS 2015 water. Our references to internal NuGet packages seemed to be a pickle so I forced a reinstall on one particular package.
It reinstalled it, and all its dependencies, for the whole solution. Afterwards, the .csproj files are missing their traditional references.
For example, this block/element existed in the project file before I updated:
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
My guess is that this is new behaviour, that now all references are NuGet packages. I actually thought this was only for new ASP.NET projects, these are old ASP.NET projects, so I didn't expect this new behaviour (if that's what it is).
Is this new behaviour? Will all the team now have to move to VS 2015 because the refs will be missing if I commit these changes and they open it in 2013?
Thanks
Update: No response (Christmas) so x-posted at GitHub
https://github.com/NuGet/Home/issues/1866
To answer the question here: no, this is not how it should work; reference elements are not removed from the XML in the .csproj file.
Related
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.
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.
Sometimes, after updating NuGets, ReSharper marks specific lines as errors, even though the solution builds, due to inability to recognize the type in use e.g. marks methods or properties in red, marks usage of object in red. In these cases the ReSharper intellisense is broken too.
In these cases sometimes reanalyzing all files in the "Errors in Solution" window and cleaning, closing Visual Studio, deleting the .suo file, reopening Visual Studio and Solution and building does not help.
Is there any way to fix this?
I encountered this a few times, in all these cases, editing the .csproj file with the code misidentified as erroneous and modifying the references to the assemblies with the types not recognized from:
<Reference Include="AssemblyNameGoesHere, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\AssemblyNameGoesHere.1.3.0\lib\net45\AssemblyNameGoesHere.dll</HintPath>
<Private>True</Private>
</Reference>
to
<Reference Include="AssemblyNameGoesHere">
<HintPath>..\packages\AssemblyNameGoesHere.1.3.0\lib\net45\AssemblyNameGoesHere.dll</HintPath>
</Reference>
Solved this issue.
I reached this solution by comparing the .csproj files of the project with the "errors" other projects in the solution containing similar code that is was not marked as erroneous by ReSharper.
I have a solution with many projects. In Visual Studio 2010, clicking properties for an assembly reference displays a newer version when comparing with the actual reference in the csproj file.
Specifically the csproj file has:
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies\System.Web.Mvc.dll</HintPath>
</Reference>
But VS2010 links and displays version 4.0.0.0 obvioussly because of <SpecificVersion>False</SpecificVersion>
Do I have to manually update every singe assembly reference in every project??? by deleting and re-adding the 3.0.0.0 ?
Is there a way to search & replace all the .csproj files in one operation?
Are you looking to have your assemblies all reference version 3.0.0.0 again? If so, then you would just need to set SpecificVersion back to true for all projects that reference the assembly. This could be done from the references of the project using the properties for the reference.
You could also do this by editing the csproj files in a text editor and remove "False" from the assemblies that you want to reference 3.0.0.0 again as the default value is true.
If you are only looking to do this for a specific assembly, then I expect this to be a manual process as I am not aware of a tool that will help do this.
If you were looking to set specific version to true for all assemblies in all of your projects, then you may be able do a find and replace in the project files replacing "False" with "".
I have a Visual Studio project that relies on several DLL references. Here is a sample of those references in my csproj:
<ItemGroup>
<Reference Include="Class1.Project1">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\bin\Class1.Project1.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Class1.Project2">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\bin\Class1.Project2.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
However, when I include this class as a project dependency in a web site project, Visual Studio is finding dependencies of the dependencies shown above. During build Visual Studio is then defaulting the "Copy Local" property to "True" and copying these dependencies into my web site's ~/bin directory.
This, in turn, is overwriting the versions of the DLL files that already exist in this directory. This causes the following error:
Could not load file or assembly
'Class5.Project5, Version=3.6.1861.2,
Culture=neutral,
PublicKeyToken=dfeaee0e3978ac79' or
one of its dependencies. The located
assembly's manifest definition does
not match the assembly reference.
(Exception from HRESULT: 0x80131040)
How do I make Visual Studio default the "Copy Local" setting to "False" for everything? I do not want Visual Studio to copy DLL files automatically during build. Nor do I want to tie my build to very specific versions of a DLL.
It sounds to me as though you have multiple projects configured to output into the same directory - is this true?
If so, you'll need to review your configuration as Visual Studio assumes (nay, requires) that each project has a unique output directory.
Also, you wrote:
This, in turn, is overwriting the versions of the DLL files that already exist in this directory.
Where did these existing files come from?
Visual Studio assumes that it has full rights to make whatever changes it sees fit in the build output directories - trying to argue with it is a fine route to a whole new world of pain.
(Unfortunately, I speak from experience. Sigh.)
I had this problem once,
On Publish: The easiest way to prevent writing over the existing dll files is to set them as ReadOnly. You will get a warning on publish for each file that could not be replaced but it will do the job.
On Build: To set the CopyLocal automatically off you need to place the dll files on the GAC.
Why were there other versions already in the bin directory?
In any case, I wonder if you would get the same problem using a Web Application Project. Since it's a project, it has a single file listing the direct references, and if these are project references (references to the output of other assemblies in the same solution), then MSBUILD can ensure that the correct version is used.
See if you can reproduce this by starting with a new web application project and just adding the references.
You could try the following in your project file.
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
And then, in your code try this.
<ItemGroup>
<Reference Include="Class1.Project1">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\bin\Class1.Project1.dll</HintPath>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</Reference>
<Reference Include="Class1.Project2">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\bin\Class1.Project2.dll</HintPath>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</Reference>
</ItemGroup>