Skip to content

Commit

Permalink
Project COM interop APIs (microsoft#830)
Browse files Browse the repository at this point in the history
* add COM interop API projections and tests

* revising tests

* Added cswinrt support for interop interfaces

* remove UAC check on IPrinting3DManagerInterop

* clarified wording

* updated to latest cppwinrt to disable mdmerge validation

* Removed Printing3DManager, as not in universal contract

* minor tweaks

* typo

* fix incorrect merge conflict

* add comment on unit tests

* restored cswinrt nuget package reference to resolve NETSDK1130 errors

* add COM interop wrappers

* fully automate COM interop support for Windows SDK projection

* PR feedback

Co-authored-by: Scott Jones <[email protected]>
  • Loading branch information
angelazhangmsft and Scottj1s authored Jun 11, 2021
1 parent fa038af commit 0a35e01
Show file tree
Hide file tree
Showing 27 changed files with 1,150 additions and 362 deletions.
2 changes: 1 addition & 1 deletion docs/interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ SetString(MarshalString.GetAbi(marshalStr));
```

#### Interop Interfaces
**Note:** The CLR still supports marshaling COM (IUnknown), but not WinRT (IInspectable), interop interfaces. There are two approaches to marshaling IInspectable interfaces in C#/WinRT.
The CLR still supports marshaling COM (IUnknown), but not WinRT (IInspectable), interop interfaces. The Windows SDK projection provides definitions for several COM interop interfaces, including ***Windows.Storage.Streams.IBufferByteAccess***, ***WinRT.Interop.IWindowNative***, and ***WinRT.Interop.IInitializeWithWindow***. The Windows SDK projection also provides wrappers for all WinRT interop interfaces included in the Universal API Contract, such as ***Windows.Security.Credentials.UI.UserConsentVerifierInterop***. For custom or extension SDK interop interfaces, C#/WinRT supports two marshaling techniques.

##### Projected
If possible, the interop interface should be defined in IDL and a C#/WinRT projection produced for it. This automatically generates all marshaling logic so that calling code can pass and receive projected types. This definition of `IUserConsentVerifierInterop` from one of our test components is an example of this:
Expand Down
1 change: 1 addition & 0 deletions nuget/Microsoft.Windows.CsWinRT.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<file src="Microsoft.Windows.CsWinRT.Prerelease*.targets" target="build"/>
<file src="Microsoft.Windows.CsWinRT.Authoring.Transitive.targets" target="build"/>
<file src="Microsoft.Windows.CsWinRT.Authoring.Transitive.targets" target="buildTransitive"/>
<file src="$cswinrt_exe$\..\..\obj\merged\WinRT.Interop.winmd" target="metadata"/>
<file src="readme.txt"/>
<file src="$net5_runtime$" target="lib\net5.0\"/>
<file src="$source_generator$" target="analyzers\dotnet\cs\"/>
Expand Down
8 changes: 7 additions & 1 deletion nuget/Microsoft.Windows.CsWinRT.targets
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,20 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<CsWinRTFilters Condition="'$(CsWinRTFilters)' == ''">
@(CsWinRTExcludeItems->'-exclude %(Identity)', '&#x0d;&#x0a;')
@(CsWinRTIncludeItems->'-include %(Identity)', '&#x0d;&#x0a;')
</CsWinRTFilters>
</CsWinRTFilters>
<CsWinRTInteropMetadata Condition="'$(CsWinRTInteropMetadata)' == ''">$([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', '..\metadata\WinRT.Interop.winmd'))</CsWinRTInteropMetadata>
<CsWinRTIncludeWinRTInterop Condition="$(CsWinRTFilters.Contains('-include Windows&#x0d;&#x0a;'))">
-input $(CsWinRTInteropMetadata)
-include WinRT.Interop
</CsWinRTIncludeWinRTInterop>
<CsWinRTParams Condition="'$(CsWinRTParams)' == ''">
$(CsWinRTCommandVerbosity)
-target $(TargetFramework)
$(CsWinRTWindowsMetadataInput)
-input @(CsWinRTInputs->'"%(FullPath)"', ' ')
-output "$(CsWinRTGeneratedFilesDir.TrimEnd('\'))"
$(CsWinRTFilters)
$(CsWinRTIncludeWinRTInterop)
</CsWinRTParams>
</PropertyGroup>
<MakeDir Directories="$(CsWinRTGeneratedFilesDir)" />
Expand Down
1 change: 1 addition & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<BuildOutDir Condition="'$(BuildOutDir)'==''">$([MSBuild]::NormalizeDirectory('$(SolutionDir)_build', '$(BuildPlatform)', '$(Configuration)'))</BuildOutDir>
<CsWinRTPath>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', 'cswinrt', 'bin'))</CsWinRTPath>
<CsWinRTPath Condition="'$(Platform)'=='ARM' or '$(Platform)'=='ARM64'">$([MSBuild]::NormalizeDirectory('$(SolutionDir)_build', 'x86', '$(Configuration)', 'cswinrt', 'bin'))</CsWinRTPath>
<CsWinRTInteropMetadata Condition="'$(CsWinRTInteropMetadata)' == ''">$(CsWinRTPath)..\obj\merged\WinRT.Interop.winmd</CsWinRTInteropMetadata>
</PropertyGroup>

<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vcxproj' or '$(MSBuildProjectExtension)' == '.wapproj'">
Expand Down
2 changes: 1 addition & 1 deletion src/Projections/Test/Test.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
Expand Down
74 changes: 39 additions & 35 deletions src/Projections/Windows/Windows.csproj
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
<Platforms>x64;x86</Platforms>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<ProjectReference Include="..\..\WinRT.Runtime\WinRT.Runtime.csproj" />
<ProjectReference Include="..\..\cswinrt\cswinrt.vcxproj" />
</ItemGroup>

<PropertyGroup>
<CsWinRTFilters>
-include Windows
# Exclude Windows.UI, Windows.UI.Text, Windows.UI.Xaml per Microsoft.Windows.SDK.WinUI.Contracts NuGet
-include Windows.UI.Popups
-exclude Windows.UI.Colors
-exclude Windows.UI.IColors
-exclude Windows.UI.ColorHelper
-exclude Windows.UI.IColorHelper
#-exclude Windows.UI.Text (must include Windows.UI.Text to work around WinUI nuget issues)
-exclude Windows.UI.Xaml
-exclude Windows.ApplicationModel.Store.Preview
# Allow Windows.UI.Text, Windows.UI.Xaml types used in other namespaces
-include Windows.UI.Text.FontStretch
-include Windows.UI.Text.FontStyle
-include Windows.UI.Text.FontWeight
-include Windows.UI.Text.UnderlineType
-include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute
</CsWinRTFilters>
</PropertyGroup>

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

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
<Platforms>x64;x86</Platforms>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<ProjectReference Include="..\..\WinRT.Runtime\WinRT.Runtime.csproj" />
<ProjectReference Include="..\..\cswinrt\cswinrt.vcxproj" />
</ItemGroup>

<PropertyGroup>
<CsWinRTFilters>
-include Windows
# Exclude Windows.UI, Windows.UI.Text, Windows.UI.Xaml per Microsoft.Windows.SDK.WinUI.Contracts NuGet
-include Windows.UI.Popups
-exclude Windows.UI.Colors
-exclude Windows.UI.IColors
-exclude Windows.UI.ColorHelper
-exclude Windows.UI.IColorHelper
#-exclude Windows.UI.Text (must include Windows.UI.Text to work around WinUI nuget issues)
-exclude Windows.UI.Xaml
-exclude Windows.ApplicationModel.Store.Preview
# Allow Windows.UI.Text, Windows.UI.Xaml types used in other namespaces
-include Windows.UI.Text.FontStretch
-include Windows.UI.Text.FontStyle
-include Windows.UI.Text.FontWeight
-include Windows.UI.Text.UnderlineType
-include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute
</CsWinRTFilters>
</PropertyGroup>

<PropertyGroup>
<DefineConstants>TRACE;MANUAL_IUNKNOWN,UAC_VERSION_13</DefineConstants>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions src/Samples/WinUIDesktopSample/WinUIDesktopSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
-->
<XamlCodeGenerationControlFlags>DoNotGenerateOtherProviders</XamlCodeGenerationControlFlags>
<Platforms>x86;x64</Platforms>
<SimulateCsWinRTNugetReference>true</SimulateCsWinRTNugetReference>
<CsWinRTEnabled>false</CsWinRTEnabled>
</PropertyGroup>

<ItemGroup>
Expand Down
15 changes: 10 additions & 5 deletions src/Tests/TestComponentCSharp/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >

<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

<!--Only need the WinUI winmd files for compiling idl, so stub out Xaml targets-->
<Target Name="MarkupCompilePass1" />
<Target Name="MarkupCompilePass2" />
<Target Name="Prep_ComputeProcessXamlFiles" />
<PropertyGroup>
<!--Avoid UniversalApiContract type not found error-->
<CppWinRTMergeNoValidate>true</CppWinRTMergeNoValidate>
</PropertyGroup>

<!--Only need the WinUI winmd files for compiling idl, so stub out Xaml targets-->
<Target Name="MarkupCompilePass1" />
<Target Name="MarkupCompilePass2" />
<Target Name="Prep_ComputeProcessXamlFiles" />

</Project>
46 changes: 0 additions & 46 deletions src/Tests/TestComponentCSharp/Directory.Build.targets

This file was deleted.

7 changes: 0 additions & 7 deletions src/Tests/TestComponentCSharp/TestComponentCSharp.idl
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,6 @@ namespace TestComponentCSharp
CustomDisposableTest();
}

// IInspectable-based interop interface
[uuid(39E050C3-4E74-441A-8DC0-B81104DF949C)]
interface IUserConsentVerifierInterop
{
Object RequestVerificationForWindowAsync(UInt64 appWindow, String message, GUID riid);
}

[default_interface]
runtimeclass CustomBindableVectorTest : Microsoft.UI.Xaml.Interop.IBindableVector
{
Expand Down
9 changes: 4 additions & 5 deletions src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.210504.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.210504.3\build\native\Microsoft.Windows.CppWinRT.props')" />
<Import Project="..\..\packages\Microsoft.WinUI.3.0.0-preview1.200515.3\build\native\Microsoft.WinUI.props" Condition="Exists('..\..\packages\Microsoft.WinUI.3.0.0-preview1.200515.3\build\native\Microsoft.WinUI.props')" />
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.200615.7\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.200615.7\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<CppWinRTVerbosity>high</CppWinRTVerbosity>
<CppWinRTOptimized>true</CppWinRTOptimized>
Expand Down Expand Up @@ -94,22 +94,21 @@
</ItemGroup>
<ItemGroup>
<None Include="Directory.Build.props" />
<None Include="Directory.Build.targets" />
<None Include="packages.config" />
<None Include="TestComponentCSharp.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.200615.7\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.200615.7\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="..\..\packages\Microsoft.WinUI.3.0.0-preview1.200515.3\build\native\Microsoft.WinUI.targets" Condition="Exists('..\..\packages\Microsoft.WinUI.3.0.0-preview1.200515.3\build\native\Microsoft.WinUI.targets')" />
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.210504.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.210504.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.200615.7\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.200615.7\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.200615.7\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.200615.7\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.WinUI.3.0.0-preview1.200515.3\build\native\Microsoft.WinUI.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.WinUI.3.0.0-preview1.200515.3\build\native\Microsoft.WinUI.props'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.WinUI.3.0.0-preview1.200515.3\build\native\Microsoft.WinUI.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.WinUI.3.0.0-preview1.200515.3\build\native\Microsoft.WinUI.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.210504.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.210504.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.210504.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.210504.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,5 @@
<None Include="TestComponentCSharp.def" />
<None Include="packages.config" />
<None Include="Directory.Build.props" />
<None Include="Directory.Build.targets" />
</ItemGroup>
</Project>
8 changes: 4 additions & 4 deletions src/Tests/TestComponentCSharp/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.200615.7" targetFramework="native" />
<package id="Microsoft.WinUI" version="3.0.0-preview1.200515.3" targetFramework="native" />
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.210504.3" targetFramework="native" />
<package id="Microsoft.WinUI" version="3.0.0-preview1.200515.3" targetFramework="native" />
</packages>
Loading

0 comments on commit 0a35e01

Please sign in to comment.