Terminal.Gui icon indicating copy to clipboard operation
Terminal.Gui copied to clipboard

Detect UWP environment and use its APIs instead of kernel32.dll

Open InvictusMB opened this issue 5 years ago • 10 comments

Fixes #700

InvictusMB avatar Jun 18 '20 19:06 InvictusMB

I think it's great. I would just add a new UWP project to more easily test that platform, if possible. Thank you. I hope it will please both @migueldeicaza and @tig.

BDisp avatar Jun 18 '20 21:06 BDisp

This is indeed great and I agree with @bdisp is there any simple way to test and use that scenario? Should we have documentation for the users on how to use this?

migueldeicaza avatar Jun 18 '20 21:06 migueldeicaza

@migueldeicaza There is no extra effort required to use this. We pick the preferred bindings based on the environment. Win 10 and above use Win 10 SDK bindings, older versions use Win32 bindings.

A way to test this would be to have a copy of UICatalog defined as UWP app and built with .NET Native tool chain.

It would also be nice to test this on Win 8 but I can't find a VM anymore. Microsoft seems to have removed their IE test VMs and left only Win 10 here.

InvictusMB avatar Jun 19 '20 09:06 InvictusMB

I think that just adding a solution with a UWP Console project that you already have at https://github.com/InvictusMB/TerminalGuiUwpInputBug and adding a reference to the Terminal.Gui project would be enough for users using this platform. Like the FSharpExample solution that exposes another type of language.

BDisp avatar Jun 19 '20 10:06 BDisp

I am not very good at Windows.

So how does a console app determine that it can use the UWP APIs vs the Win32 ones?

migueldeicaza avatar Jun 19 '20 20:06 migueldeicaza

So how does a console app determine that it can use the UWP APIs vs the Win32 ones?

Based on Environment.OSVersion.Major. If we are in Win 10 environment we use UWP APIs from Win10 SDK otherwise we stick to Win32. However, as I've mentioned in #700 I'm not able to validate if using UWP APIs has any impact at all. So the real fix here seems to be only ReadConsoleInput marshaling.

I have no way to verify if there are any Win 10 environments where kernel32.dll is not available. I also ran Windows App Certification Kit and got successful reports for both Win32 and UWP bindings. @migueldeicaza Could you ask one of Microsoft gurus to enlighten us on this topic and benefits (if any) of using UWP bindings over kernel32.dll?

InvictusMB avatar Jun 20 '20 17:06 InvictusMB

@clairernovotny points out that her https://www.nuget.org/packages/OSVersionHelper library provides the properties you need to check. The source is at https://github.com/novotnyllc/OSVersionHelper

KirillOsenkov avatar Jun 20 '20 18:06 KirillOsenkov

The environment variables lie depending on the manifest for compat.

clairernovotny avatar Jun 20 '20 18:06 clairernovotny

@KirillOsenkov @clairernovotny Thank you very much! Could you elaborate if using these APIs has any benefits over consuming kernel32.dll directly or if it affects the certification for MS Store in any way? So far I'm not convinced it does and therefore the version check itself might not be necessary. Is it safe to depend on kernel32.dll directly and only verify that a given API is listed as available for UWP apps?

InvictusMB avatar Jun 20 '20 18:06 InvictusMB

I think the store will block use of the kernel32... I had to do similar for SkiaSharp just to LoadLibrary.

https://github.com/mono/SkiaSharp/blob/master/binding/Binding/GRGlInterface.cs#L183

I cheated with UWP and created a uap dll, but this should just be a matter of checking the major version. Although, I believe it will still fail if that import makes it to the final package. Not sure if the linker knows to remove the extern.

mattleibow avatar Jun 21 '20 11:06 mattleibow