【问题标题】:How to include assemblies from NuGet packages in a VSIX Installer?如何在 VSIX 安装程序中包含来自 NuGet 包的程序集?
【发布时间】:2017-05-01 20:29:29
【问题描述】:

我正在创建一个 Visual Studio 2017 自定义签入策略扩展。我目前的解决方案结构如下:

注意:我正在利用新的 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 功能。

【问题讨论】:

  • 我可能来晚了,但这个帖子解决了我的问题:stackoverflow.com/questions/42201923/…
  • @AmauryLevé:这个问题可能已经解决了您的问题,但它与我引用的问题完全无关,这与 VSIX 打包程序通过 NuGet 的 PackageReference 功能自动包含程序集有关。该问题/答案通过直接引用程序集来处理添加资产。

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


【解决方案1】:

对于像我们这样面临这个问题的可怜人(使用 PackageReference 和 VSIX 依赖项的 nuget),我找到了一个解决方法,受这篇文章的启发: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 测试

【讨论】:

    【解决方案2】:

    我正在寻找一种更灵活的方式来获得其他答案,我使用了以下方法。

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

    【讨论】:

      【解决方案3】:

      通过执行以下 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

      【讨论】:

      • 我认为您误解了我遇到的问题。我不是在创建项目或项目模板,而是自定义签入策略。我遇到的问题是生成的 VSIX 包不包含我的程序集所依赖的 NuGet 程序集。您引用的链接是如何确保项目/项目模板自动将 NuGet 包拉入使用这些模板的项目中。此外,该问题围绕 NuGet 的新 PackageReference 功能展开。如果我改用 NuGet 的 packages.config 方法,一切正常
      • 出于好奇,您是否有理由想要/需要使用 NuGet 的 PackageReference 功能?
      • 是的,blog.nuget.org/20170316/…——基本上它有很多好处,是 NuGet 的未来。
      • 虽然我同意它是 NuGet 的未来,但我认为不幸的是它仍然存在大量错误。更新了我的答案。
      • 即使您的更新,您的回答是在谈论完全不相关的东西(项目和项目模板)。
      【解决方案4】:

      适用于 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,但我没有耐心测试它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-28
        • 1970-01-01
        • 2017-08-17
        相关资源
        最近更新 更多