VSIX扩展 - 如何确保引用的dll或程序集被包含在VSIX文件中?

12
当用户安装我的扩展程序时,如果没有安装最新的Visual Studio更新,则该扩展程序无法解析Microsoft.CodeAnalysis.CSharp.dll,并显示以下消息:
“无法加载文件或程序集'Microsoft.CodeAnalysis.CSharp, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'或其其中之一的依赖项。系统找不到指定的文件。”
我确保扩展程序实际上引用了这个程序集,事实上也是如此,但为什么这个程序集会被排除在VSIX文件之外?
我将VSIX文件重命名为ZIP文件,查看其内容,但并未发现该程序集已经包含在其中,即使其他“Microsoft.CodeAnalysis.*.dll”程序集已经包含在VSIX文件中。
我还确认了引用的“Copy Local”属性设置为True。

我这里也有同样的情况。有些程序集无论你怎么做都无法放入vsix中。 - Hugo Quintela Ribeiro
嗨@HugoQuintelaRibeiro,请看下面我找到的解决方案。希望它也能帮到你。 - Martin Lottering
4个回答

9
我找到了解决这个问题的方法,现在我可以看到dll已经包含在VSIX中,并且有一个用户确认它对他有用。
  1. 在Visual Studio中打开扩展方案
  2. 双击.vsixmanifest文件
  3. 打开“Assets”选项卡
  4. 点击“New”按钮
  5. 将“Type”设置为“Microsoft.VisualStudio.Assembly”
  6. 将“Source”设置为“文件系统上的文件”
  7. 点击“Browse”按钮以设置dll的路径(不用担心,引用会被添加为相对路径或强名称程序集)
  8. 你可以将“Embed in this folder”留空
  9. 点击“OK”
  10. 重新构建方案,此时文件应该已经包含在VSIX文件中。

enter image description here

然后将此行添加到vsixmanifest文件中:

<Asset Type="Microsoft.VisualStudio.Assembly" d:Source="File" Path="Microsoft.CodeAnalysis.CSharp.dll" AssemblyName="Microsoft.CodeAnalysis.CSharp, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

这对我有用,但应注意许多DLL,特别是微软的DLL,都带有许多单独的外语资源程序集。如果没有这些程序集,这些文本将始终为英语,这些程序集必须按正确的文件夹排列。此外,VS奇怪地将新的“Asset” DLL复制到项目文件夹的根目录;不确定是否可以防止这种情况发生。相关链接:https://dev59.com/l1rUa4cB1Zd3GeqPfwSW - Qwertie
遗憾的是,从项目中删除额外的副本并手动更改vsix以添加路径(例如将Path="Microsoft.CodeAnalysis.dll"更改为Path="..\packages\Microsoft.CodeAnalysis.Common.3.6.0\lib\netstandard2.0\Microsoft.CodeAnalysis.dll")不起作用 - 一旦您删除了额外的副本,该dll就不再包含在vsix中。 - Qwertie

1

对于不喜欢为缺失的dll添加引用的人,我发现以下方法非常有效:

https://www.cazzulino.com/include-dlls-in-vsix.html

我在我的.csproj文件末尾添加了以下内容,所有缺失的dll都被包含在了.vsix中。

<PropertyGroup>
    <GetVsixSourceItemsDependsOn>$(GetVsixSourceItemsDependsOn);IncludeNuGetResolvedAssets</GetVsixSourceItemsDependsOn>
</PropertyGroup>
<Target Name="IncludeNuGetResolvedAssets" DependsOnTargets="ResolveNuGetPackageAssets">
    <ItemGroup>
        <VSIXCopyLocalReferenceSourceItem Include="@(ReferenceCopyLocalPaths)"  />
    </ItemGroup>
</Target>

0
将以下内容添加到csproj文件中:
  <Target Name="IncludePackageReferenceDependencies" AfterTargets="GetVsixSourceItems">
    <ItemGroup>
      <!-- <VSIXSourceItem Include="@(ReferencePath)" Condition="$([System.String]::new('%(ReferencePath.FusionName)').EndsWith('.dll'))" /> -->
      <VSIXSourceItem Include="@(ReferencePath)" />
    </ItemGroup>
  </Target>

0

我找到了一个类似于Martin的解决方法,但是没有副作用,不需要将DLL的副本放在项目文件夹中。(我仍然没有弄清楚如何添加缺失的非英语资源程序集。)

步骤0:如果您有间接依赖关系 - vsix依赖于使用NuGet包C的项目B,该包又依赖于包D - 请确保C和D的DLL包含在vsix的bin \ Debug文件夹中。如果没有,请为vsix项目添加对包C和D的引用以确保安全。在我的情况下,VS决定将一些间接依赖项(例如System.Numerics.Vectors.dll和System.Threading.Tasks.Extensions.dll)包含在VSIX中,但它决定省略四个间接依赖项:Microsoft.CodeAnalysis.dll、Microsoft.CodeAnalysis.CSharp.dll、System.Reflection.Metadata.dll和System.Collections.Immutable.dll。

步骤1:重新构建并查找VSIX中缺少的文件。您可以将.vsix重命名为.zip以查看其中的内容,并将其与vsix项目文件夹中的bin \ Debug的内容进行比较以查找缺少的项目。

步骤2:使用“添加 > 现有项...”并选择“添加为链接”,将缺失的 DLL 添加到您的项目中(如果您不确定 DLL 的位置,请在引用列表中查找它,并在属性面板中查看其路径属性)。

Step 2a Step 2b

步骤3:对于每个缺失的DLL,重复步骤2。

步骤4:选择新的DLL,在属性面板中设置“包含在VSIX中”的标志。

Step 4

在我(旧式)的 csproj 中,我最终得到了一个类似这样的 ItemGroup

  <ItemGroup>
    <Content Include="..\packages\Microsoft.CodeAnalysis.Common.3.6.0\lib\netstandard2.0\Microsoft.CodeAnalysis.dll">
      <Link>Microsoft.CodeAnalysis.dll</Link>
      <IncludeInVSIX>true</IncludeInVSIX>
    </Content>
    <Content Include="..\packages\Microsoft.CodeAnalysis.CSharp.3.6.0\lib\netstandard2.0\Microsoft.CodeAnalysis.CSharp.dll">
      <Link>Microsoft.CodeAnalysis.CSharp.dll</Link>
      <IncludeInVSIX>true</IncludeInVSIX>
    </Content>
    <Content Include="..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll">
      <Link>System.Collections.Immutable.dll</Link>
      <IncludeInVSIX>true</IncludeInVSIX>
    </Content>
    <Content Include="..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll">
      <Link>System.Reflection.Metadata.dll</Link>
      <IncludeInVSIX>true</IncludeInVSIX>
    </Content>
  </ItemGroup>

步骤5:重新构建并验证文件是否已包含在vsix中。您无需将文件添加到资产列表中。然后在Visual Studio中进行测试。祝你好运!

P.S. 我想过,也许VSIX不包括这些文件的原因是因为VS知道Visual Studio已经安装了这些文件。但是这种解释仍然不令人满意,因为例如,Visual Studio有System.Memory.dllSystem.Numerics.Vectors.dll的副本,但VS仍然选择将这些DLL包含在我的VSIX中。

无论如何,我的扩展都不能加载 Visual Studio 2019 的文件副本。我注意到我的 Microsoft.CodeAnalysis.dll 版本是 "3.6.0-4.20269.4+...",而在 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\ManagedLanguages\VBCSharp\LanguageServices 中的版本是 "3.5.0-beta4-20153-05+..."(假设这是重要的版本 - 我不知道,在 Program Files 中还有其他 5 个版本)。通过将我的 VSIX 降级到使用早于 3.5.0-beta4 的版本(假设 beta 版本不在 NuGet 上),也许我的扩展程序将能够使用 Visual Studio 的版本。但那是另一天的测试,即使它有效,如果我想针对 Visual Studio 2017 和 Visual Studio 2019,我怀疑如果我不在 vsix 中包含我需要的所有 DLL,我就不能同时针对两个版本进行目标定位。

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