如何发布具有 COM 互操作的控制台应用程序并修剪未使用的代码

问题描述 投票:0回答:1

我有一个简单的控制台应用程序,它引用一个小型第三方 COM 互操作 .NET 程序集。

我想在发布时修剪未使用的代码。

Enter image description here

但是,当我运行修剪后的已发布应用程序时,出现错误:

未处理的异常。 System.IO.FileNotFoundException:文件名: '3rdPartyInteropLibrary,版本=1.3.0.0,文化=中性,PublicKeyToken=null' 在 ClassLibrary1.Class1.Print() 在 Program.Main()

即使我手动将 3rdPartyInteropLibrary.dll 文件复制到输出文件夹,我也会收到错误。

如何配置修剪,以便它只修剪我的代码并保持外部库不变?

--------------------------------- .csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <Reference Include="Interop.bpac">
      <HintPath>Interop.bpac.DLL</HintPath>
    </Reference>
  </ItemGroup>

</Project>

public class Program
{
    public static void Main()
    {
        var printer = new bpac.Printer();
        var printers = printer.GetInstalledPrinters() as Array;
    }
}
.net com publish com-interop self-contained
1个回答
0
投票

我知道 COM 互操作与程序集修剪不兼容,但我希望有一些解决方法,例如修剪除互操作程序集引用的程序集之外的所有内容(例如,保留所有 .NET Standard API 不变)

从评论来看,

dotnet/runtime
问题78038
MissingMethodException
System.Management.WmiNetUtilsHelper
调用期间从
wmi
引发(.NET6自包含)”,以及微软文档“已知的修剪不兼容性”,它是显然,修剪和 COM 互操作之间存在固有的不兼容性,这可能会导致像您看到的那样的运行时错误。

核心问题是.NET 修剪功能旨在通过删除被视为“未使用”的代码路径来减小最终发布的应用程序的大小。

但是,此过程依赖于静态分析,无法解释在运行时动态调用的依赖项,这通常是 COM 互操作的情况。

您看到这些是因为修剪器正在删除 COM 互操作所需的代码,并且

BuiltInComInteropSupport
属性在启用时可以禁用某些 COM 互操作功能。 GitHub 问题讨论澄清了 COM 互操作和修剪从根本上不兼容,.NET 团队的建议是在需要 COM 互操作时避免使用修剪。

由于您想要一个解决方案来缩小应用程序大小,同时还使用 COM 互操作,您可能会考虑:

  • 完全避免修剪:这是最安全的方法,并且可以确保存在所有必要的 COM 互操作代码,但它也会导致应用程序大小更大。

  • 手动修剪:使用

    DynamicDependency
    属性手动注释代码以显式保留所需的依赖关系。这不受支持,并且很容易出错,因为维护是您的责任。

  • 实现与修剪兼容的自定义 com 包装器:这并不简单。

  • 为 .NET 运行时做出贡献,按照 .NET 团队成员的建议,使

    System.Management
    库修剪兼容。这将是一个有利于整个 .NET 社区的长期解决方案,但超出了单个项目的直接需求范围。

为了立即解决问题,...最好避免修剪。

© www.soinside.com 2019 - 2024. All rights reserved.