Skip to content

Migrate own classic-COM interop to ComWrappers (IPolicyConfigVista, IAudioPolicyConfigFactory) #22

@hoobio

Description

@hoobio

Problem

Earmark's own COM interop in src/Earmark.Audio/Interop/ is declared with classic [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]:

Marshalling these interfaces depends on System.StubHelpers.InterfaceMarshaler in CoreLib. The .NET 10 trimmer feature-switches that helper out and prints IL2026: Built-in COM support is not trim compatible (see PR #19 for the failed attempt and #21 for the trimming follow-up that this unblocks). Until our own COM declarations are migrated, the trimmer will strip the marshalling stubs regardless of what NAudio does upstream (#22).

Proposed Solution

Migrate to [GeneratedComInterface] / [GeneratedComClass] source-generators:

  1. Convert IPolicyConfigVista to [GeneratedComInterface(...)] with the existing IID 568b9108-44bf-40b4-9006-86afe5b5a620. Update the CoCreateInstance call site in AudioPolicyService.EnsurePolicyConfig to use StrategyBasedComWrappers.GetOrCreateObjectForComInstance instead of Activator.CreateInstance(Type.GetTypeFromCLSID(...)).
  2. Convert IAudioPolicyConfigFactory similarly. Keep the IInspectable-vtable padding (three reserved methods at the start) as [PreserveSig] slots in the source-generated interface; the activation path through RoGetActivationFactory against the Windows.Media.Internal.AudioPolicyConfig runtime class remains the same.
  3. Replace HString.cs's manual combase!WindowsCreateString / WindowsDeleteString plumbing with the runtime's [MarshalAs(UnmanagedType.LPWStr)] HSTRING marshaller now that ComWrappers handles the rest of the call shape, OR keep HString and only swap the interface declarations.
  4. Once both interfaces use [GeneratedComInterface], the UnconditionalSuppressMessage for IL2072 on EnsurePolicyConfig can come out (it was added in PR perf(installer): shrink MSI size #19 but reverted with the rest of the trimming work).

Alternatives Considered

  • Stay on classic-COM in our code, never trim. Cheap, costs the trimming win documented in Enable PublishTrimmed for Release builds #21.
  • Wait for the .NET runtime to add a "preserve classic-COM stubs" feature switch. No tracking; Microsoft's published guidance at https://aka.ms/dotnet-illink/com is explicit that classic COM is not trim compatible and ComWrappers is the path forward.

Additional Context

Checklist

  • I searched existing issues and this hasn't been requested yet

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions