如何在VSIX安装程序中包含NuGet包的程序集?

时间:2017-05-01 20:29:29

标签: nuget visual-studio-2017 vsix checkin-policy

我正致力于创建Visual Studio 2017自定义签到策略扩展。我目前的解决方案结构如下:

VSIX Solution Structure

注意:我正在利用新的NuGet PackageReference方法,这就是没有packages.config文件的原因。

我相信我已经适当地设置了我的VSIX清单,因为当我没有引用Microsoft.Net.Http时,一切都很完美(原来我在值中硬编码而不是检索值)。我不确定为什么包含的Microsoft.TeamFoundationServer.ExtendedClient NuGet包不会导致任何问题,而Microsoft.Net.Http NuGet包会这样做。

我查看了调试文件夹以查看正在编译的内容,并且我看到每个程序集都被拉入,但是如果我解压缩VSIX(我将其重命名为* .zip并解压缩它),则只包含项目程序集; Nuget引用的程序集未打包在VSIX包中。

我遇到了一些资源,但似乎没有任何效果:

这些问题/答案中的每一个似乎都没有解决我的具体问题。

更新

我相信用于生成VSIX包的工具可能不支持NuGet的新PackageReference功能。如果我使用旧的packages.config功能,一切正常。我已经加入UserVoice Ticket来支持新的NuGet功能。

4 个答案:

答案 0 :(得分:1)

对于那些像我们一样面对这个问题的穷人(nuget使用PackageReference和VSIX依赖),我找到了一个解决方法,受到这篇文章的启发:NuGet packages referenced via PackageReference don't include DLLs in VSIX并没有完全适合我(它包括了仅限元数据的程序集版本,而不是带代码的完整程序集。例如,在这里,我手动引用4个nuget包:

<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:使用Visual Studio 2017从15.5.4到15.7.3进行测试

答案 1 :(得分:1)

我正在寻找一种更灵活的方式来解决使用以下问题的其他答案。

  <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>

这会将所有已解析的项目引用NuGet引用添加到适当的VSIXSubPath。这也将忽略对NuGet软件包文件的框架引用。

将这些项目添加到目标GetVsixSourceItems中。在添加项目输出程序集时,我也遇到了问题,因为默认情况下,它将程序集添加到中间输出路径(obj)文件夹中。这给我造成了问题,因为我在bin文件夹中对程序集进行了签名。这里的目标是使用bin组件而不是中间输出组件。

  <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>

答案 2 :(得分:0)

通过执行以下Microsoft教程中列出的步骤,我能够在模板中成功包含NuGet包:Packages in Visual Studio templates

  

使用MSI安装的SDK可以直接在开发人员的计算机上安装NuGet包。这使得它们在使用项目或项目模板时立即可用,而不必在此期间提取它们。 ASP.NET模板使用这种方法。

我见过其他人因为他们正在使用的NuGet包而遇到问题。对于.NET Core,我使用了Microsoft.Net.Http,虽然它确实需要Microsoft.BCL。除非您遇到问题,否则我建议保留遗留系统,特别是因为这些命名空间似乎是移动目标。

似乎System.Net.Http是正确的选择,至少在Windows平台上是.NET。此包没有外部依赖性也是值得的。

修改 看来这可能与PackageReference本身的错误有关。我看到一个类似的文档错误描述here

答案 3 :(得分:-1)

适用于Visual Studio 2017的选项是NuGet packages referenced via PackageReference don't include DLLs in VSIX。但是,请使用作者建议的版本:

<Target Name="IncludePackageReferenceDependencies" AfterTargets="GetVsixSourceItems">
  <ItemGroup>
    <VSIXSourceItem Include="@(ReferencePath)" Condition="$([System.String]::new('%(ReferencePath.FusionName)').StartsWith('NuGet.VisualStudio'))" />
  </ItemGroup>
</Target>

不要尝试Simon Mourier建议的版本。这可能在VS 2015中有效,但它现在还不起作用。另请注意,此解决方案适用于NuGet的PackageReference版本。它可能适用于packages.config,但我没有耐心测试它。