Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed Type libraries inside COMhost dll's #51243

Closed
BickelLukas opened this issue Apr 14, 2021 · 4 comments · Fixed by dotnet/sdk#16915
Closed

Embed Type libraries inside COMhost dll's #51243

BickelLukas opened this issue Apr 14, 2021 · 4 comments · Fixed by dotnet/sdk#16915

Comments

@BickelLukas
Copy link

Background and Motivation

.NET core does not support generating Type libraries for COM visible dlls. Instead it creates a seperate .comhost.dll file that is actually used by other com components.

It is possible to write your own IDL files and generate a Type library from them using midl. However there is currently no way to embed the type library inside the comhost dll.

This issue was created after discussion with @AaronRobinsonMSFT on #3740
As far as I could see, prerequesits in the comhost were already implemented with #50986

Proposed API / Usage Example

Optimally I would be able to include the idl file/s with a corresponding Build Action.

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

  <PropertyGroup>
    <TargetFramework>net5.0-windows</TargetFramework>
    <EnableComHosting>true</EnableComHosting>
  </PropertyGroup>


  <ItemGroup>
+    <ComHostTypeLibrary Include="MyTypes.idl" />
  </ItemGroup>

</Project>

This would autmatically compile the idl and add it as a type library to the comhost dll.

Alternative Designs

Specify the Idl file in the PropertyGroup

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

  <PropertyGroup>
    <TargetFramework>net5.0-windows</TargetFramework>
    <EnableComHosting>true</EnableComHosting>
+    <ComHostTypeLibrary>MyTypes.idl<ComHostTypeLibrary />
  </PropertyGroup>

</Project>

Specify the tlb file in the PropertyGroup. This would require us to compile the idl ourselves

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

  <PropertyGroup>
    <TargetFramework>net5.0-windows</TargetFramework>
    <EnableComHosting>true</EnableComHosting>
+    <ComHostTypeLibrary>MyTypes.tlb<ComHostTypeLibrary />
  </PropertyGroup>

</Project>

Risks

None that I am aware of.

@BickelLukas BickelLukas added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Apr 14, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added area-Interop-coreclr untriaged New issue has not been triaged by the area owner labels Apr 14, 2021
@AaronRobinsonMSFT AaronRobinsonMSFT removed the untriaged New issue has not been triaged by the area owner label Apr 14, 2021
@AaronRobinsonMSFT AaronRobinsonMSFT added this to the 6.0.0 milestone Apr 14, 2021
@AaronRobinsonMSFT
Copy link
Member

@BickelLukas Thanks for filing this issue. @jkoritzinsky has started this and it seem you found it. I think the current plan would be to go with having users provide a .tlb rather than an .idl. One of the reasons for this is the MIDL compiler isn't known to a .NET SDK install and that isn't something we would want to know about to be honest. Then we would need to think about various arguments to pass to the MIDL compiler and it gets in the weeds of COM which is something we would like to avoid in the .NET SDK when possible. Creating a pre-build step for .tlb generation should be straightforward and push how the MIDL compiler should be called onto the people that know best – the project owners.

@jkoritzinsky and @elinor-fung It is probably worth update one of our samples (e.g., Out-of-proc server) to use this and have a simple pre-build step people can reference.

@BickelLukas
Copy link
Author

@AaronRobinsonMSFT It would be awsome if the tlb generation could also be abstracted away for noobs like me. But I can understand that this is not something that aligns with the goals of the .NET Team.

I am actually invoking midl as a pre build step at the moment. However as you said .NET is not does not know about midl and that's why it was not straight forward at all.
But its also possible that this was just my fault since I am not very familiar with msbuild or the Windows SDK.

I had trouble locating midl from the build task and I don't think providing an absolute path is a good option. The way I settled on was pretty much just instantiating a new Developer powershell and invoking midl from there since it has all the right include paths. If @jkoritzinsky or @elinor-fung know of a better way of doing this, It would be greatly appreciated.

My Code:

csproj File:

  <Target Name="GenerateTypelib" AfterTargets="ComputeFilesToPublish">
    <!-- Generate tlb from idl file -->
    <Exec Command="powershell.exe -command &quot;&amp; { .\GenerateTlb.ps1 } &quot;" />

    <!-- Include file in publish output -->
    <ItemGroup>
      <TlbFiles Include="Consolidate.Client.tlb"></TlbFiles>
      <ResolvedFileToPublish Include="@(TlbFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>%(TlbFiles.Identity)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
      </ResolvedFileToPublish>
    </ItemGroup>
  </Target>

GenerateTlb.ps1:

$vsInstallPath = & "${env:ProgramFiles(x86)}/Microsoft Visual Studio/Installer/vswhere.exe" -prerelease -latest -property installationPath;
Import-Module "$vsInstallPath/Common7/Tools/Microsoft.VisualStudio.DevShell.dll"
Enter-VsDevShell -VsInstallPath $vsInstallPath -SkipAutomaticLocation

& midl Consolidate.Client.idl

@AaronRobinsonMSFT
Copy link
Member

@BickelLukas I would personally avoid PowerShell here as it is not my favorite, much slower in practice, and creates a horrid build system to debug. MSBuild should be discovering where VS is installed already and it is possible to determine the MSBuild property to use by looking at a binlog of the build or passing /v:diag to MSBuild. In fact, I think MSBuild will also attempt to discover the Windows 10 SDK but I could be wrong and if so, one can do that discovery much faster than what PowerShell is doing. I personally have a strong dislike for PowerShell so my view is tainted but keeping as much in MSBuild as possible would be my recommendation – something a sample we provide will likely do.

My rant on PowerShell aside, your example is sound and will be in the spirit of what a sample we produce would provide.

@AaronRobinsonMSFT
Copy link
Member

@BickelLukas Seems I was mistaken about building from dotnet on Windows and it discovering the VS install. After chatting with @jkoritzinsky and @elinor-fung they have convinced me that the PowerShell approach is likely the cleanest since it includes the environment set up too. Regardless of that misunderstanding on my part your approach is sound and we will be adding a sample with some recommended guidance. Thanks for sharing your approach.

@AaronRobinsonMSFT AaronRobinsonMSFT added feature-request and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Apr 15, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jun 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants