I\'m working on creating a Visual Studio 2017 custom Check-In Policy extension. My current solution is structured as follows:
Note: I am taking advantage of
The option that works for Visual Studio 2017 is NuGet packages referenced via PackageReference don't include DLLs in VSIX. However, use the version suggested by the author:
<Target Name="IncludePackageReferenceDependencies" AfterTargets="GetVsixSourceItems">
<ItemGroup>
<VSIXSourceItem Include="@(ReferencePath)" Condition="$([System.String]::new('%(ReferencePath.FusionName)').StartsWith('NuGet.VisualStudio'))" />
</ItemGroup>
</Target>
Don't try the version suggested by Simon Mourier. That may have worked in VS 2015, but it doesn't work now. Also note that this solution is for the PackageReference version of NuGet. It may work for the packages.config, but I didn't have the patience to test it out.
For those poor guys like us who face this problem (nuget using PackageReference and VSIX dependencies), I found a workaround, inspired by this post: NuGet packages referenced via PackageReference don't include DLLs in VSIX that didn't fully worked for me (it was including the metadata-only version of the assembly, not the full assembly with code). For example, here, I reference 4 nuget packages manually:
<Target Name="IncludeNuGetPackageReferences" AfterTargets="GetVsixSourceItems">
<ItemGroup>
<VSIXSourceItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' == 'Microsoft.Win32.Registry'" />
<VSIXSourceItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' == 'System.CodeDom'" />
<VSIXSourceItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' == 'System.Configuration.ConfigurationManager'" />
<VSIXSourceItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' == 'System.ServiceProcess.ServiceController'" />
</ItemGroup>
</Target>
PS: Tested with Visual Studio 2017 from 15.5.4 to 15.7.3
I was able to successfully include NuGet packages in a template by performing the steps outlined in the following Microsoft tutorial: Packages in Visual Studio templates
SDKs that are installed using an MSI can install NuGet packages directly on the developer's machine. This makes them immediately available when a project or item template is used, rather than having to extract them during that time. ASP.NET templates use this approach.
I have seen others experiencing problems because of the NuGet packages they are using. For .NET Core, I have used Microsoft.Net.Http, although it does require Microsoft.BCL. Unless you are experiencing problems, I suggest leaving legacy systems as-is, especially since these namespaces seem to be moving targets.
It appears System.Net.Http is the correct choice, at least for .NET on the Windows platform. It is also worth nothing that this package has no external dependencies.
EDIT:
It appears this could be related to bugs with PackageReference
itself. I see a similar documented bug described here.
I you're looking for a more flexible way to other answers I have used the following.
<Target Name="IncludeProjectReferenceNuGetPackageAssemblies" AfterTargets="GetVsixSourceItems">
<!--Add project reference NuGet package assemblies to the package-->
<ItemGroup>
<VSIXSourceItem Include="@(ReferencedVSIXSourceItem)" Condition="'%(ReferencedVSIXSourceItem.NuGetSourceType)' == 'Package' and '%(ReferencedVSIXSourceItem.FrameworkFile)' != 'true'" />
</ItemGroup>
</Target>
This will add all resolved project reference NuGet references to the appropriate VSIXSubPath. This will also ignore framework references to NuGet package files.
The items are added in the target GetVsixSourceItems. I also had issues adding the project output assembly because by default it adds the assembly in the intermediate output path (obj) folder. This was causing issues for me because I sign the assembly in the bin folder. Here's a target to use the bin assembly instead of the intermediate output assembly.
<Target Name="SwapIntermediateAssemblyForTargetPath" AfterTargets="GetVsixSourceItems" Condition="'$(IncludeAssemblyInVSIXContainer)' == 'true'">
<!--Create an item for the primary output of the project. By default the intermediate assembly is packed in the VSIX. Use the output target path instead.-->
<ItemGroup>
<VSIXSourceItem Remove="@(IntermediateAssembly)" />
<VSIXSourceItem Include="$(TargetPath)">
<VSIXSubPath>$(AssemblyVSIXSubPath)</VSIXSubPath>
<InstallRoot>$(InstallRoot)</InstallRoot>
<Ngen>$(Ngen)</Ngen>
<NgenApplication>$(NgenApplication)</NgenApplication>
<NgenArchitecture>$(NgenArchitecture)</NgenArchitecture>
<NgenPriority>$(NgenPriority)</NgenPriority>
</VSIXSourceItem>
</ItemGroup>
</Target>