GithubHelp home page GithubHelp logo

microsoft / cswinrt Goto Github PK

View Code? Open in Web Editor NEW
514.0 27.0 101.0 36.18 MB

C# language projection for the Windows Runtime

License: MIT License

C++ 18.25% C 0.23% C# 80.64% Batchfile 0.65% PowerShell 0.23%
windows csharp desktop winui3 dotnet5 winrt

cswinrt's Introduction

Build Status

The C#/WinRT Language Projection

C#/WinRT provides Windows Runtime (WinRT) projection support for the C# language. A "projection" is an adapter that enables programming the WinRT APIs in a natural and familiar way for the target language. The C#/WinRT projection hides the details of interop between C# and WinRT interfaces, and provides mappings of many WinRT types to appropriate .NET equivalents, such as strings, URIs, common value types, and generic collections.

WinRT APIs are defined in *.winmd format, and C#/WinRT includes tooling that generates C# code for consumption scenarios, or generates a *.winmd for authoring scenarios. Generated C# source code can be compiled into interop assemblies, similar to how C++/WinRT generates headers for the C++ language projection. This means that neither the C# compiler nor the .NET Runtime require built-in knowledge of WinRT any longer.

Motivation

.NET Core is the focus for the .NET platform. It is an open-source, cross-platform runtime that can be used to build device, cloud, and IoT applications. Previous versions of .NET Framework and .NET Core have built-in knowledge of WinRT which is a Windows-specific technology. By lifting this projection support out of the compiler and runtime, we are supporting efforts to make .NET more efficient for .NET 5 onwards.

WinUI 3 is the effort to lift official native Microsoft UI controls and features out of the operating system, so app developers can use the latest controls and visuals on any in-market version of the OS. C#/WinRT is needed to support the changes required for lifting the XAML APIs out of Windows.UI.XAML and into Microsoft.UI.XAML.

However, C#/WinRT is a general effort and is intended to support other scenarios and versions of the .NET runtime. While our focus is on supporting .NET 5, we aspire to generate projections that are compatible down to .NET Standard 2.0. Please refer to our issues backlog for more information.

What's New

See our release notes for the latest C#/WinRT releases and corresponding .NET SDK versions. C#/WinRT runtime and Windows SDK projection updates typically become available in a future .NET SDK update, which follows a monthly release cadence. We also make updates to the C#/WinRT tool itself, which are shipped through the C#/WinRT NuGet package. Details on breaking changes and specific issues can be found in the releases notes.

Using C#/WinRT

Download the C#/WinRT NuGet package here: https://www.nuget.org/packages/Microsoft.Windows.CsWinRT/

You can also build a C#/WinRT package yourself from source: see our Contributor's Guide for more information on building the repo.

Documentation

For additional documentation and walkthroughs, visit http://aka.ms/cswinrt.

C#/WinRT Architecture

The C#/WinRT runtime assembly, WinRT.Runtime.dll, is required by all C#/WinRT assemblies. It provides an abstraction layer over the .NET runtime, supporting .NET 5+. The runtime assembly implements several features for all projected C#/WinRT types, including WinRT activation, marshaling logic, and COM wrapper lifetime management.

Contributing

The C#/WinRT team welcomes feedback and contributions! There are several ways to contribute to the project:

We ask that before you start work on a feature that you would like to contribute, please read our Contributor's Guide, which also includes steps on building the C#/WinRT repo.

Related Projects

C#/WinRT is part of the xlang family of projects that help developers create APIs that can run on multiple platforms and be used with a variety of languages. The mission of C#/WinRT is not to support cross-platform execution directly, but to support the cross-platform goals of .NET Core.

C#/WinRT is also part of the Windows App SDK - a set of libraries, frameworks, components, and tools that you can use in your apps to access powerful platform functionality across many versions of Windows. The Windows App SDK combines Win32 native app capabilities with modern API usage techniques, so your apps light up everywhere your users are. The Windows App SDK also includes WinUI, WebView2, MSIX, C++/WinRT, and Rust/WinRT.

License Info

Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

cswinrt's People

Contributors

aaronrobinsonmsft avatar adambraden avatar angelazhangmsft avatar asklar avatar ataridreams avatar benjkuhn avatar dependabot[bot] avatar dongle-the-gadget avatar dunhor avatar hez2010 avatar j0shuams avatar jeremy-price avatar jevansaks avatar jkoritzinsky avatar jkotas avatar jlaanstra avatar kant2002 avatar karkarl avatar kennykerr avatar kmgallahan avatar manodasanw avatar mcooley avatar microsoft-github-operations[bot] avatar microsoftopensource avatar richlander avatar scottj1s avatar shashanknay avatar stevenbrix avatar ujjwalchadha avatar wjk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cswinrt's Issues

Missing System.Uri and System.Type projections

I'm filing this issue just so that it is made a bit more visible. I brought this up in the meeting on Friday and want to make sure that it's properly prioritized. I've only seen a general task related to type mappings, and don't see a more fine grained one - so if that is incorrect then please dupe this.

This issue, along with #91 are blocking WinUI from making any progress on consuming CS/WinRT. Once the WinRT.Runtime assembly and ccw work is checked in, this will immediately become blocking.

interfaces in ABI namespace are not accessible

I'm creating a derived component that uses our WinUI projection, and am getting errors like this:

1>Win32XamlHost.cs(109,57,109,69): error CS0122: 'IApplication' is inaccessible due to its protection level

The code that causes this error looks like this:

 internal XamlApplication(global::ABI.Win32XamlHost.IXamlApplication ifc)
            : base(ifc.As<global::ABI.Microsoft.UI.Xaml.IApplication>())
{
    _default = ifc;
}

Enable CI on PR runs

Currently we only run our CI builds on master. We should also run them on PR runs to validate that we don't break CI.

Non-deterministic NRE on GC finalizer thread

Repro Steps

  1. Open cmd window and pushd \\arobins-server4\shared
  2. Extract repro app from \\poseidon-dev\public\net5app.zip and place it on disk
  3. From a separate cmd, run the following commands to properly setup environment:
set DOTNET_ROOT=Z:\v2\ret\dotnet-runtime-5.0.0-dev-win-x64\
set DOTNET_MUSBUILD_SDK_RESOLVER_CLI_DIR=%DOTNET_ROOT%
set PATH=%DOTNET_ROOT%;%PATH%
set DOTNET_MULTILEVEL_LOOKUP=0
set DOTNET_ROLL_FORWARD=Major
  1. cd to location where you extracted the app in step 2
  2. execute dotnet run command

Expected results

App runs and outputs time to console

Actual results

App crashes on GC finalizer thread with the following callstack:

     WinRT.Runtime.dll!WinRT.IObjectReference.Release() Line 97    C#
     WinRT.Runtime.dll!WinRT.IObjectReference.Dispose(bool disposing) Line 86    C#
>    WinRT.Runtime.dll!WinRT.IObjectReference.~IObjectReference() Line 37    C#

Testing local changes to the repro app

  • To use a locally built WinRT.Runtime.dll, you can place it in the \lib\netcoreapp5.0\ location in the repro.
  • The WinUI winmds are in the \lib\uap10.0 folder if you need to create a new WinUI projection. The projection can go into the \lib\netcoreapp5.0 folder and is named Microsoft.WinUI.dll. Or, you can remove that reference and compile the projection directly into the app

Parameterized constructors generated code blocks RCW identity

The generated code for parameterized constructors creates an RCW, unwraps it, and then makes the object being constructed a new RCW with the underlying default interface object. This breaks RCW identity since the initially created RCW will be designated the default RCW, not the .NET object being constructed.

Provide method for projections to add "default-implemented" interfaces for CCWs

To match parity with the .NET projections system, CsWinRT needs to provide a way for libraries to provide implementations of native interfaces for the native wrappers of managed objects. For example, CsWinRT needs to supply 2 implementations of Windows/Microsoft.UI.Xaml.Data.ICustomPropertyProvider (one for .NET objects, one for CCWs that wrap RCWs); however, these types don't exist without running cswinrt to generate a projection.

.NET Projections should not have WinRT types in them

the winrt to .net projections were never implemented fully properly and is really confusing. sometimes you use the regular .NET types, and in other places you use the WinRT version. I think that .net developers should use the APIs they are comfortable and used to using. On top of that, I've heard from customers that it makes code re-use and sharing more difficult.

Any API that uses xLang to project into .NET should use the .NET APIs that already exist, especially those in the System.ComponentModel, System.Collections, and System.IO namespaces.

ActivationFactory's constructor does an unconditional replace of "WinRT" with "Windows" for the class name

The constructor contains the line:

using (HString runtimeClassId = new HString(typeof(T).FullName.Replace("WinRT", "Windows")))

Which doesn't seem correct. First, I'm not entirely sure why this is present anyway? From the way that it's written, it seems like there are scenarios where the leading namespace of "Windows" is replaced with "WinRT", but I can't seem to find any evidence of this being done. The namespace used in WinRT.cs is WinRT, but AFAICT none of these types are activatable. But anyway, i'd expect that at best this should only occur if (1) the full name starts with "WinRT" and (2) has a trailing dot (i.e. starts with "WinRT.").

ObjectReference<T> copies v-table contents locally

ObjectReference<T> hast the members:

        readonly Interop.IUnknownVftbl _vftblIUnknown;
        public readonly T Vftbl;

Both IUnknownVftbl and T are structs, which seems like it will effectively copy over the entirety of both v-tables (and IUnknown's v-table will be copied twice). Seems like it would be much better to store pointers to these v-tables. Or perhaps ideally just eliminate these members since that's what ThisPtr already is.

Attribute types are missing from generated code

Nuget Version: 1.0.200219.1

Attribute types are missing from the generated code. If you look at the Microsoft.UI.Xaml.Markup.cs file generated from the winuitest project, you'll see that Microsoft.UI.Xaml.Markup.ContentPropertyAttribute is missing

Module ref counts appear to be handled incorrectly

The IObjectReference base type has a Module member that calls FreeLibrary on destruction. This is a divergence from the way that WinRT works and will break developer assumptions since the established pattern is for the library's DllCanUnloadNow function to return S_OK when it is safe to be unloaded and S_FALSE otherwise. E.g. just because all of our references to objects in some binary are gone, it could still be the case that the module in question has running code e.g. asynchronous tasks, etc. Such binaries that are correctly written to return S_FALSE under these circumstances may be unloaded and AV with the current behavior.

Type Mapping initialization - fallback behavior if not initialized

WinRT.ComWrappersSupport.InitializeComWrappers() exists so that tooling can provide a more efficient RCW factory by providing a custom implementation of ComWrappers that knows the appโ€™s type universe. There are scenarios where this doesn't get called and WinRT.Runtime needs load the default and register it globally if no one else calls InitializeComWrappers before theyโ€™re needed.

Need to handle (rare) collisions of inherited members

The warnings below, from building the WinUITest project, are the only remaining issues related to inheritance support. Probably best to explicitly implement all collisions, versus picking a 'new' winner.

2>Generated Files\Microsoft.UI.Composition.cs(5946,48,5946,78): warning CS0108: 'VisualIslandSite.CreateTransformChangedDeferral()' hides inherited member 'CompositionIslandSite.CreateTransformChangedDeferral()'. Use the new keyword if hiding was intended.
2>Generated Files\Microsoft.UI.Xaml.Automation.Peers.cs(3302,21,3302,28): warning CS0108: 'PivotItemDataAutomationPeer.Realize()' hides inherited member 'ItemAutomationPeer.Realize()'. Use the new keyword if hiding was intended.
2>Generated Files\Windows.UI.Xaml.Automation.Peers.cs(3867,21,3867,28): warning CS0108: 'PivotItemDataAutomationPeer.Realize()' hides inherited member 'ItemAutomationPeer.Realize()'. Use the new keyword if hiding was intended.
2>Generated Files\Windows.UI.Xaml.Controls.Maps.cs(1368,58,1368,71): warning CS0108: 'MapControl.StyleProperty' hides inherited member 'FrameworkElement.StyleProperty'. Use the new keyword if hiding was intended.
2>Generated Files\Windows.UI.Xaml.Controls.Maps.cs(1788,25,1788,30): warning CS0108: 'MapControl.Style' hides inherited member 'FrameworkElement.Style'. Use the new keyword if hiding was intended.

Add support for IRestrictedErrorInfo

Our current usage of Marshal.ThrowExceptionForHR doesn't support IRestrictedErrorInfo correctly. To fully support the WinRT platform, we need to add support for IRestrictedErrorInfo, at least to a matching level as CoreCLR.

CS/WinRT and WinUI integration

CS/WinRT and WinUI integration spec

Outline

This spec has the following high-level goals:

  1. Detail the fundamental principles of how CS/WinRT interop assemblies will work
  2. Detail the type projections
  3. Callout any outstanding questions or issues related to how CS/WinRT will work

Table of Contents

Overview of CS/WinRT

This section aims to give a high level overview of the CS/WinRT project, and some basic principles of how the tool works.

What is CS/WinRT?

CS/WinRT is a new language projection implementation to allow the .NET runtime to interop with the Windows Runtime (WinRT). The Windows Runtime is a set of libraries, whose APIs are defined in the .winmd file format.

Why CS/WinRT?

The WinRT API surface defines many APIs that are very similar to those that live in .NET. In order to make .NET development feel more natural to .NET developers, there are a set of The current WinRT projections are baked into the .NET Native runtime and compiler. This special and hardcoded knowledge has proved problematic and buggy, and does not scale. The goal with CS/WinRT is to create the proper layer of abstraction for these projections, so that the .NET runtime has no special knowledge of WinRT, and instead just operates on the assemblies like they are regular .NET assemblies (because they are!)

When will CS/WinRT ship?

The plan is to have CS/WinRT ready for the release of .NET5, to be consumed by WinUI3.0. It will ship as a Nuget package on nuget.org.

How does CS/WinRT work?

At a conceptually high level, CS/WinRT works much like Cpp/WinRT. The tool, cswinrt.exe creates wrapper classes, defined in CSharp, that understand the Application Binary Interface (ABI) of the WinRT libraries based off of the .winmd files that are used as inputs.

There will be a single CS/WinRT runtime interop dll (name TBD) that is shared between any CS/WinRT interop assembly. TBD more on this

TODO: Link to tool implementation and/or spec

WinRT to .NET Projections

Foundational types

Below is a list of the foundational types (as they show in the .winmd) and the corresponding .NET type they project to. While many of these are primitive types, this list also consists of many other basic types such as collections.

WinRT Type Projected .NET Type
Windows.Foundation.Object System.Object
Windows.Foundation.Int32 System.Int32
Windows.Foundation.Int64 System.Int64
Windows.Foundation.UInt32 System.UInt32
Windows.Foundation.UInt32 System.UInt64
Windows.Foundation.Object System.Object

Interfaces

TODO: Finish filling this in with collection types

WinRT Type Projected .NET Type
Microsoft.UI.Xaml.Input.ICommand System.Windows.Input.ICommand
Microsoft.UI.Xaml.Interop.IBindableIterable System.Collections.IEnumerable
Microsoft.UI.Xaml.Interop.IBindableVector System.Collections.IList
Microsoft.UI.Xaml.Inteorp.INotifyCollectionChanged System.UInt32
Microsoft.UI.Xaml.Data.INotifyPropertyChanged System.ComponentModel.INotifyPropertyChanged
Microsoft.UI.Xaml.Data.INotifyDataErrorInfo System.ComponentModel.INotifyDataErrorInfo

Structs

The following types don't have a projection into .NET, although the structs do have more functionality than a classic WinRT struct.

TODO: more on why these aren't projected to the System.Windows.* types, and should they?

WinRT Type
Windows.Foundation.Point
Windows.Foundation.Rect
Windows.Foundation.Size

Struct Helper classes

Xaml types that get extra members in the CSharp projection.

For example, Xaml's CornerRadius is just a struct:

struct CornerRadius
{
    DOUBLE TopLeft;
    DOUBLE TopRight;
    DOUBLE BottomRight;
    DOUBLE BottomLeft;
};

But when it's projected in CSharp, it acquires a constructor and comparison operators:

public struct CornerRadius
{
    public CornerRadius(double topLeft, double topRight, double bottomRight, double bottomLeft);

    public double BottomLeft { get; set; }
    public double BottomRight { get; set; }
    public double TopLeft { get; set; }
    public double TopRight { get; set; }

    public override bool Equals(object obj);
    public bool Equals(CornerRadius cornerRadius);
    public override int GetHashCode();
    public override string ToString();
    public static bool operator ==(CornerRadius cr1, CornerRadius cr2);
    public static bool operator !=(CornerRadius cr1, CornerRadius cr2);
}

There is actually a way for non-CSharp developers to get access to this same functionality with some Helper classes. For example, there's a CornerRadiusHelper class that has these members on it.

These Helper classes are not projected by CSharp, since the functionality is on the structs already.

Note that Point/Rect/Size are Windows.Foundation structs, but the helper classes are in Xaml's namespace (e.g. RectHelper).

The structs and their helpers:

Struct Struct helper
CornerRadius CornerRadiusHelper
Duration DurationHelper
DurationType
GridLength GridLengthHelper
Thickness ThicknessHelper
GeneratorPosition GeneratorPositionHelper
Matrix MatrixHelper
KeyTime KeyTimeHelper
RepeatBehavior RepeatBehaviorHelper
RepeatBehaviorType

Note that in addition to adding members to these structs, the projections add ToString() overrides. For example, the ToString for Thickness is something like "10,2,10,2" rather than just the type name.

Exceptions

These exception types live in System.Runtime.WindowsRuntime.UI.Xaml.dll and are automatically created at runtime by the interop layer:

ElementNotAvailableException
ElementNotEnabledException
LayoutCycleException
XamlParseException

The Type Type

WinRT doesn't officially have the notion of a type. There is no Windows.Foundatation.Type. You can ask an object (IInspectable) for runtime class name, but that's only a string.

But, Xaml has a type named Windows.UI.Xaml.Interop.TypeName (and associated TypeKind enum) that projects in CSharp to System.Type.

With WinUI3, this type will eventually move to Microsoft.UI.Xaml.Interop.TypeName, however this work has not been done yet because we are still using .NET Native. Once the project system work has been done to move off of .NET Native, we can move this type. Ideally, CS/WinRT already has support for Microsoft.UI.Xaml.Interop.TypeName at that point, and we can make the change in metadata and move all of our test projects at the same time.

ICustomPropertyProvider

Xaml calls to CCWs today and QIs for ICustomPropertyProvider to get properties for data binding. The implementation of that interface uses reflection on the target .Net object.

TODO: More on how this interop will work

System IO

Some of the .NET APIs in the System.IO namespace, for example, System.IO.File were removed from the .NET Native API surface because they did not conform to the sandboxed environment of the app container. Instead, developers used the WinRT equivalent APIs, and to keep along with the example, would use Windows.Storage.StorageFile instead. With moving to .NET5 and CS/WinRT, we want there to be a single runtime and a more uniform API surface area, however that still leaves what to do with these APIs unresolved.

TODO: Gather a complete list of these APIs

WinRT Type .NET Type
Windows.Storage.StorageFile System.IO.File
Windows.Storage.StorageFolder System.IO.Directory

Streams

WinRT APIs that either returned or accepted a stream would use the Windows.Storage.Streams.IRandomAccessStream class at the API surface. There existed some helper extension methods in the .NET/WinRT interop assembly. Rather than relying on those, can we instead just project the Windows.Storage.Streams.IRandomAccessStream as a System.IO.Stream? The extension methods can still exist so that code can compile with minimal changes, but will no longer be required. Another option would be to have the app conversion tool remove the use of these extension methods.

Consuming CS/WinRT

WinRT library authors will consume the CS/WinRT tool through the Nuget. For WinUI control authors writing C++ winrt components, this will be abstracted through some MSBuild targets. The MSBuild targets should generate the CSharp wrappers and compile the code into an interop assembly, and not require the need for a second project for doing so. If developers don't have the CSharp workload installed, they can opt-out of this by setting an MSBuild property, although we don't want this to be the default behavior. It should first be validated and confirmed how C++ WinRT component authors generate their Nuget packages. The Win2D Nuget is probably a good starting point for seeing how these Nugets are generated.

Authoring WinRT APIs in CSharp

Compiling CSharp WinRT components into a .winmd allows for the following scenarios:

  • C++ Applications referencing a C# component
  • C# background tasks

In order to do this, the winmdexp tool needs to be updated to work with the new projections.

Delegate ref counting is wrong

Currently the Delegate type is initialized with its reference count at zero. It seems like this is an "optimization" to avoid the need to call Release at the call-site and the expectation seems to be that the caller will AddRef the delegate since presumably they are going to hold a reference to it. However, this is incorrect for a couple of reasons.

Reason 1: The consumer need not do the "final" AddRef first. For example, consider the following consuming code:

HRESULT DoSomething(IMyDelegate* d)
{
    d->AddRef();
    d->Release();
    d->AddRef();
    m_delegate = d;
    // ...

In this example the object will get destroyed after the Release call since the ref count will drop to zero, but from their perspective this should be safe since the caller should also be holding a ref. This example looks kind of silly, but actually exists in real life; the only difference being that the first AddRef is typically a QueryInterface (e.g. a QI for IAgileObject)

Reason 2: If the caller does not take a reference to the object, it will be leaked. For example, consider the following consuming code:

HRESULT DoSomething(IMyDelegate* d)
{
    if (SomeCondition()) return E_SOME_FAILURE;
    // ...

In this case the consumer never called AddRef (or equivalent) and therefore has no reason to call Release. But then neither does the caller, so even though the ref count remains at zero when all is said and done, the object will be leaked.

Boolean values are not blittable

In .NET AFAICT boolean values are 1 byte, whereas in WinRT they are 4 bytes. This probably does not impact most scenarios (e.g. I believe all calling conventions requires "upgrading" all integers less than 32-bits to 32-bits, albeit that's my recollection of printf, which is a different calling convention, anyway), however it does impact things like arrays, struct sizes, etc. We should probably account for this in the helpers and whatever fallout comes out of that.

FWIW here's some decent documentation on what is and is not blittable: https://docs.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types

Generic delegates need some work

With the delegate helpers:
FromAbi needs to support dynamic invocation.
ToAbi needs to return an InitialReference to the projection, to stabilize the managed delegate and prevent premature GC (see AsyncTest comments)

Delegate's AddRef/Release implementation is thread unsafe

There are calls to System.Threading.Interlocked.Increment/Decrement followed by tests of the value, e.g. to call _Dispose if the count has gone to zero. This is not thread safe. The result of the Increment/Decrement should be used for these comparisons

Convert WinRT String to .NET string type in projections

When generating API surface area for consumption, the .NET string should be used instead of WinRT.String.

type_mappings[] =
{
{"bool", "Boolean"},
{"char", "Char"},
{"sbyte", "SByte"},
{"byte", "Byte"},
{"short", "Int16"},
{"ushort", "UInt16"},
{"int", "Int32"},
{"uint", "UInt32"},
{"long", "Int64"},
{"ulong", "UInt64"},
{"float", "Float"},
{"double", "Double"},
{"WinRT.HString", "WinRT.HString"},
};

[Deprecated] attribute application is causing csc.exe to crash

as well as VBCScompiler.exe.

In existing C#, F12 to view the metadata for a type like Windows.UI.Xaml.Controls.InkToolbarRulerButton shows that the code-gen is correct, with the same constructor string expression:
[Deprecated("InkToolbarRulerButton is deprecated starting from Windows 10 Creators Update. Please use InkToolbarStencilButton going forward. For more info, see MSDN.", DeprecationType.Deprecate, 262144, "Windows.Foundation.UniversalApiContract")]

But somehow it still smells bad to csc.exe

Virtual override methods are resulting in a StackOverflow

In the same sample as #110, if you get COM aggregation working correctly, you will hit a StackOverflow. The callstack looks like this:

     Microsoft.WinUI.dll!Microsoft.UI.Xaml.Application.Microsoft.UI.Xaml.IApplicationOverrides.OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) Line 213    C#
     Microsoft.WinUI.dll!ABI.Microsoft.UI.Xaml.IApplicationOverrides.Vftbl.Do_Abi_OnLaunched_1(System.IntPtr thisPtr, System.IntPtr args) Line 9970    C#
     Microsoft.WinUI.dll!ABI.Microsoft.UI.Xaml.IApplicationOverrides.OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) Line 10115    C#
     Microsoft.WinUI.dll!Microsoft.UI.Xaml.Application.Microsoft.UI.Xaml.IApplicationOverrides.OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) Line 213    C#

Support referencing managed assembly

It would be helpful to be able to provide a managed DLL reference during code generation which implies there is no need to generate those types already contained in an assembly. Consider the following scenario:

  1. Generate WinUI API surface
  2. Compile generated source from (1) into assembly WinUI.dll
  3. Create a new API contract that consumes WinUI APIs - Foo.idl
  4. Generate source from Foo.idl

The code generator requires passing all winmds from WinUI in step (4). This means that the source for WinUI will be regenerated. Instead the user should be able to pass WinUI.dll and that provides the definition and only source for types not provided via winmds should be generated.

Boxing performance analysis

Investigate boxing performance. Currently boxing is being done by both .NET and WinRT, investigate this and other things we can do in the projection.

Return/out params erroneously 'AddRef' class/interface types

E.g. the function:

HRESULT GetValue([out, retval] IInspectable** result);

Gets projected as:

        public unsafe IInspectable GetValue()
        {
            IntPtr __return_value__;
            Marshal.ThrowExceptionForHR(_obj.Vftbl.GetValue_2(NativePtr, out __return_value__));
            return IInspectable.FromNative(__return_value__);
        }

And IInspectable.FromNative is implemented as:

public static WinRT.ObjectReference<Vftbl> FromNative(IntPtr @this) => WinRT.ObjectReference<Vftbl>.FromNative(@this);

And WinRT.ObjectReference<Vftbl>.FromNative is implemented as:

        public static ObjectReference<T> FromNative(IntPtr thisPtr)
        {
            // Retrieve module handle from QueryInterface function address
            IntPtr qi;
            unsafe { qi = (*(IntPtr**)thisPtr.ToPointer())[0]; };
            IntPtr moduleHandle;
            if (!Platform.GetModuleHandleExW(4, qi, out moduleHandle))
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }
            return FromNative(new DllModuleHandle(moduleHandle), thisPtr);
        }

Which forwards to:

        public static ObjectReference<T> FromNative(object module, IntPtr thisPtr)
        {
            var obj = new ObjectReference<T>(module, thisPtr, true);
            obj._vftblIUnknown.AddRef(obj.ThisPtr);
            return obj;
        }

This seems incorrect since the returned pointer should already have its reference count bumped

Handle scenarios when the transitive closure of types is known.

There are scenarios in WinRT where the transitive closure of all types is known. This would imply there are opportunities to optimize the RCW code generation logic and avoid querying the runtime for these types - see

internal static Func<IInspectable, object> CreateTypedRcwFactory(string runtimeClassName)

Reasons for considering this are: AOT and linkability (reduce memory footprint).

WinRT.cs should support shared use across interop assemblies

All types in WinRT.cs that are accessed by the projection should be consistently either internal (so replicated) or public (so shared), but not a mixture as exists today. This is preventing multiple cswinrt interop assemblies from coexisting in an app.

Port over remaining System.Runtime.WindowsRuntime public surface area

We should make sure to port over the rest of the System.Runtime.WindowsRuntime surface area. The public types are tracked below:

  • System.WindowsRuntimeSystemExtensions
  • System.IO.WindowsRuntimeStorageExtensions
  • System.IO.WindowsRuntimeStreamExtensions
  • System.Runtime.InteropServices.WindowsRuntime.AsyncInfo
  • System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBuffer
  • System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions
  • Windows.Foundation.Point
  • Windows.Foundation.Rect
  • Windows.Foundation.Size
  • Windows.UI.Color

Delegate's QueryInterface implementation is incomplete

The obvious missing part is that it does not respond to QIs for the delegate interface (e.g. some IFooHandler). But additionally, there are other interfaces that we likely should respond to. For example, Windows.System.Threading.ThreadPool.RunAsync takes in a delegate type and queries for the IAgileObject marker interface. That's an example of something that we should probably respond to by default and maybe make it opt-out if necessary (or opt-in if we don't default to that).

Consider renaming to .NET instead of C#

Presumably, this projection will be relevant for any .NET language, not just C#. Is that accurate? If so, should this project be called DotnetWinRT instead of CsWinRT?

com aggregation is not working

Aggregation of types doesn't seem to be working. I've attached a link to a simple repro app.

You should be able to put a breakpoint in the OnLaunched method and see it get hit. It's currently not being hit because the WinUI runtime does not have an outer object

Build: need to validate with Mono & .NET 5

Ideally, the unit test can be targeted on-demand for any runtime, by developers and by the build pipeline. E.g., for Mono 5.4 validation, mcs.exe would build and mono.exe would run. There are some issues with nearly all unit test frameworks fully supporting .NET Core unit tests on various runtimes (e.g., Mono does not have a specific moniker to target). But should be able to cobble something together.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.