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

18

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

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功能。


1
我可能会来得晚,但这个线程解决了我的问题:https://dev59.com/4FgQ5IYBdhLWcg3wynCn - Amaury Levé
@AmauryLevé:那个问题可能解决了你的问题,但它与我所提到的问题完全无关,那个问题与VSIX打包程序自动通过NuGet的PackageReference功能包含程序集有关。那个问题/答案是通过直接引用程序集来添加资源的。 - myermian
4个回答

5
对于像我们这样面临此问题的可怜人(使用PackageReference和VSIX依赖项的nuget),我找到了一个解决方法,受到这篇文章的启发:通过PackageReference引用的NuGet包在VSIX中不包括DLL 对我来说并没有完全起作用(它只包括元数据版本的程序集,而不是具有代码的完整程序集)。例如,在这里,我手动引用了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>

0

我成功地按照Microsoft的教程Visual Studio模板中的NuGet包,将NuGet包包含在模板中。

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

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

看起来System.Net.Http是正确的选择,至少对于Windows平台上的.NET而言。值得注意的是,这个包没有外部依赖。


编辑: 看起来这可能与PackageReference本身的错误有关。我在这里看到了一个类似的已记录错误here


我觉得你误解了我的问题。我不是在创建项目或模板,而是一个自定义的Check-In策略。我遇到的问题是VSIX包生成时没有包含我程序集所依赖的NuGet程序集。你提供的链接是关于如何确保项目/模板自动引入NuGet包到使用这些模板的项目中。此外,问题集中在NuGet的新PackageReference功能上。如果我使用NuGet的packages.config方法,一切都可以正常工作。 - myermian
只是出于好奇,您是否有使用NuGet的PackageReference功能的原因或需求? - lax1089
1
是的,http://blog.nuget.org/20170316/NuGet-now-fully-integrated-into-MSBuild.html -- 基本上它有很多好处,并且是NuGet的未来。 - myermian
虽然我同意它是NuGet的未来,但我认为它仍然存在相当多的错误。我更新了我的答案。 - lax1089
2
即使您更新了,您的回答仍然在谈论完全无关的事情(项目和模板)。 - myermian
显示剩余2条评论

-2
Visual Studio 2017 的可行选项是 通过 PackageReference 引用的 NuGet 包不包含 VSIX 中的 DLL。然而,请使用作者建议的版本:
<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,但我没有耐心测试它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接