Create NuGet packages that contain COM interop assemblies

Packages that contain COM interop assemblies must include an appropriate targets file so that the correct EmbedInteropTypes metadata is added to projects using the PackageReference format. By default, the EmbedInteropTypes metadata is always false for all assemblies when PackageReference is used, so the targets file adds this metadata explicitly. To avoid conflicts, the target name should be unique; ideally, use a combination of your package name and the assembly being embedded, replacing the {InteropAssemblyName} in the example below with that value. (Also see NuGet.Samples.Interop for an example.)

<Target Name="Embedding**AssemblyName**From**PackageId**" AfterTargets="ResolveReferences" BeforeTargets="FindReferenceAssembliesForReferences">
  <ItemGroup>
    <ReferencePath Condition=" '%(FileName)' == '{InteropAssemblyName}' AND '%(ReferencePath.NuGetPackageId)' == '$(MSBuildThisFileName)' ">
      <EmbedInteropTypes>true</EmbedInteropTypes>
    </ReferencePath>
  </ItemGroup>
</Target>

Note that when using the packages.config management format, adding references to the assemblies from the packages causes NuGet and Visual Studio to check for COM interop assemblies and set the EmbedInteropTypes to true in the project file. In this case, the targets are overridden.

Additionally, by default the build assets do not flow transitively. Packages authored as described here work differently when they are pulled as a transitive dependency from a project to project reference. The package consumer can allow them to flow by modifying the PrivateAssets default value to not include build.