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

Windows support #7

Open
molesmoke opened this issue Jul 6, 2023 · 23 comments
Open

Windows support #7

molesmoke opened this issue Jul 6, 2023 · 23 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@molesmoke
Copy link

Hi, this is awesome, thanks for sharing! Is it possible to add Windows support to the sample too?

@juwens
Copy link

juwens commented Sep 1, 2023

@kekekeks
Copy link
Member

kekekeks commented Sep 1, 2023

Avalonia for Windows is using Win32 API layer instead of UWP/WinUI one. You can try using UWP/WinUI APIs for embedding Win32 content.

@juwens
Copy link

juwens commented Sep 1, 2023

i created a draft PR #8

It's quite tough, i've done the obvious things.

But since i added the desktop/win32 i get super strange compile errors.

i didn't change anything in the xmlns.

2>------ Build started: Project: MauiSampleApp, Configuration: Debug Any CPU ------
2>CSC : error AXN0002: XamlX.XamlParseException: Unable to resolve type Shell from namespace http://schemas.microsoft.com/dotnet/2021/maui Line 2, position 2.
2>CSC : error AXN0002: XamlX.XamlParseException: Unable to resolve type ContentPage from namespace http://schemas.microsoft.com/dotnet/2021/maui Line 2, position 2.
2>CSC : error AXN0002: XamlX.XamlParseException: Unable to resolve type Application from namespace http://schemas.microsoft.com/dotnet/2021/maui Line 2, position 2.
2>CSC : error AXN0002: XamlX.XamlParseException: Unable to resolve type ResourceDictionary from namespace http://schemas.microsoft.com/dotnet/2021/maui Line 3, position 2.
2>Done building project "MauiSampleApp.csproj" -- FAILED.

Feel free to fork my PR and apply fixes.

Stacktrace

21:19:03.870  1:24>CSC : error AXN0002: XamlX.XamlParseException: Unable to resolve type Shell from namespace http://schemas.microsoft.com/dotnet/2021/maui Line 2, position 2. [C:\github\juwens_AvaloniaMauiHybrid\MauiSampleApp\MauiSampleApp.csproj::TargetFramework=net7.0-windows10.0.19041.0]
                     at XamlX.Transform.Transformers.TypeReferenceResolver.ResolveTypeCore(AstTransformationContext context, String xmlns, String name, Boolean isMarkupExtension, List`1 typeArguments, IXamlLineInfo lineInfo, Boolean strict) in /_/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/src/XamlX/Transform/Transformers/TypeReferenceResolver.cs:line 109 (TaskId:83)
                     at XamlX.Transform.Transformers.TypeReferenceResolver.ResolveType(AstTransformationContext context, String xmlns, String name, Boolean isMarkupExtension, List`1 typeArguments, IXamlLineInfo lineInfo, Boolean strict) in /_/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/src/XamlX/Transform/Transformers/TypeReferenceResolver.cs:line 35 (TaskId:83)
                     at XamlX.Transform.Transformers.TypeReferenceResolver.ResolveType(AstTransformationContext context, XamlAstXmlTypeReference xmlref, Boolean strict) in /_/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/src/XamlX/Transform/Transformers/TypeReferenceResolver.cs:line 147 (TaskId:83)
                     at XamlX.Transform.Transformers.TypeReferenceResolver.Transform(AstTransformationContext context, IXamlAstNode node) in /_/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/src/XamlX/Transform/Transformers/TypeReferenceResolver.cs:line 135 (TaskId:83)
                     at XamlX.Transform.AstTransformationContext.Visitor.Visit(IXamlAstNode node) in /_/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/src/XamlX/Transform/AstTransformationContext.cs:line 58 (TaskId:83)
                     at XamlX.Ast.XamlAstNode.Visit(IXamlAstVisitor visitor) in /_/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/src/XamlX/Ast/Common.cs:line 56 (TaskId:83)
                     at XamlX.Ast.XamlRootObjectNode.VisitChildren(IXamlAstVisitor visitor) in /_/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/src/XamlX/Ast/Intrinsics.cs:line 195 (TaskId:83)
                     at XamlX.Compiler.XamlCompiler`2.Transform(XamlDocument doc, Boolean strict) in /_/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github/src/XamlX/Compiler/XamlCompiler.cs:line 70 (TaskId:83)
                     at Avalonia.Generators.Common.XamlXViewResolver.ResolveView(String xaml) in /_/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs:line 47 (TaskId:83)

@juwens
Copy link

juwens commented Sep 1, 2023

@kekekeks why is the axaml-compiler trying to parse non-axaml files?

I deduct, because the problem started when i included the avalonia.win32 nuget, that the culprit is somewhere in the targets/props of the Avalonia.Desktop or Avalonia.Win32 package.

@juwens
Copy link

juwens commented Sep 1, 2023

The problem is ALL xaml files get added to the msbuild property "AdditionalFiles" and the avalonia source generator tries to parse ALL additional xaml files, and fails on the maui xaml files.

image

image

@juwens
Copy link

juwens commented Sep 1, 2023

@maxkatz6 @emmauss @danwalmsley

I'm really stuck here, can you help pls?

I'm evaluating avalonia for a gradual migration from maui to avalonia.
It's essential that i can get a mixed avalonia+maui UI working with all three platforms.

@juwens
Copy link

juwens commented Sep 1, 2023

AFAIK one solution could be to relax ResolveView in the SourceGenerator to not throw a terminating exception, but to ignore (warn) if processing a imcompatible (non-avalonia) xaml-files was unsuccessful.

https://github.com/AvaloniaUI/Avalonia/blob/0230bf782af1f15544804126cd3390dd8959d6bc/src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameGenerator.cs#L45C50-L45C50

@juwens
Copy link

juwens commented Sep 4, 2023

i guess, this might be related too.

AvaloniaUI/Avalonia#4045 (comment)

@jeremy-visionaid
Copy link

@juwens Great to see someone looking into this. Thanks for your efforts 👍

@kekekeks
Copy link
Member

kekekeks commented Sep 5, 2023

Not sure how to fix that additional files problem, since .xaml file can be added as AvaloniaXaml item and it's being used in existing apps.

Does Roslyn see custom MSBuild metatadata for AdditionalFiles? If so, we could update our targets to mark ones converted from AvaloniaXaml

juwens added a commit to juwens/AvaloniaMauiHybrid that referenced this issue Sep 8, 2023
@maxkatz6 maxkatz6 added enhancement New feature or request help wanted Extra attention is needed labels Sep 21, 2023
@maxkatz6
Copy link
Member

It would simplify things a lot, if WinUI supported HwndHost or a similar "islands" approach at least.

@juwens
Copy link

juwens commented Sep 21, 2023

@maxkatz6 I’m still trying to implement it in a separate fork of the main avalonia repo. But I have a lot of question marks. For example: do you mean it’s literally impossible with the current state of WinUI?
Or would it be “just” easier with HWndHost?
And what is the most tricky part? Is it the Platform “Mapping”, like Pointer Position, input forwarding, Focus, etc?

@juwens
Copy link

juwens commented Sep 21, 2023

@maxkatz6 it seems to work the other way around: microsoft/microsoft-ui-xaml#2828

maybe we can host a WinUI App inside an avalonia App? 😬

@maxkatz6
Copy link
Member

maybe we can host a WinUI App inside an avalonia App? 😬

Yeah, it should be easier. Creating a small WinUI window for each control to be hosted inside of Avalonia.

For example: do you mean it’s literally impossible with the current state of WinUI?

Just easier with HwndHost. HwndHost would handle pointers, inputs and others.
Without HwndHost there should be a special ITopLevelImpl created, and rendering target needs to be created from the winui control. Essentially. it would be similar to rendering avalonia into a bitmap image and redirecting all input.

We had similar integration for WPF before - https://github.com/AvaloniaUI/Avalonia/tree/release/0.10.22/src/Windows/Avalonia.Win32.Interop/Wpf. Except it used Direct2D backend, which is not an option anymore.
This WPF interop was replaced with HwndHost based implementation later as it's more stable - https://github.com/maxkatz6/AvaloniaHwndHostSample/blob/main/Avalonia.Win32.Interoperability/AvaloniaHwndHost.cs

@juwens
Copy link

juwens commented Sep 22, 2023

@maxkatz6 big thanks for the detailed answer.

@cesarchefinho
Copy link

if we have instructions to adjust csproj to have avaloniamauihybrid, aka use maui/use essentials and etc only when compiling android and ios but not having maui nor maui things when compiling windows or brwser then we can have an solution with windows and browser implemantantion of some feature and use maui essentials in ios and android only.

can someone help with this ?

I tried but i have failed...

@gentledepp
Copy link

gentledepp commented May 2, 2024

I kind of agree.
We are now at a point where we must migrate away from Xamarin.Forms, but Maui just isn't "ready yet" and I am almost sure it never will be.

But since we are a line of business app and we need to be backward compatible so our customers can keep working, we need

  • platform APIs (i.e. Maui.Essentials)
  • and a QR Code scanner

AvaloniaUI ticks all of the (many other) boxes, but not being able to support barcodes is just a game stopper.

Regarding the platform APIs:
Using Maui.Essentials is paramount to us - since implementing all the nasty platform-specifics takes time and costs money. Since Microsoft is offering this out of the box, we thankfully take it.
I will try to figure out if I can get it to run on Windows too. Then that problem would be one of the past.

But the QR Code Scanner still bogs me.
There is currently one single library we could use - https://github.com/Redth/ZXing.Net.Maui
However, as the name implies, it is for MAUI.

So we would need:

  • a way to host MAUI controls in AvaloniaUI on iOS, Android, Windows
  • or at least be able to say "use AvaloniaMauiHybrid", but if you run on Windows, show some AvalonieUI stuff instead. (so we'd implement it ourselves somehow on Windows)
    But I could not get your sample to run on windows.

Since @maxkatz6 you seem to be an expert in windows interoperability:

@Gillibald
Copy link

It looks like you only need https://github.com/Redth/ZXing.Net.Maui/tree/main/ZXing.Net.MAUI which seems to generate bitmaps or receive bitmaps from a platform-specific implementation. So in the end you need to add an Avalonia version of these: https://github.com/Redth/ZXing.Net.Maui/tree/main/ZXing.Net.MAUI.Controls/Controls

@gentledepp
Copy link

Ok, so we found a project called FlashCap that supports video frame capturing on Avalonia (Desktop).

And it turns out, it was quite easy to modify their sample to get our QR code scanner to work, since they all rely on SkiaSharp.
kekyo/FlashCap#29 (comment)
This is, honestly, quite awesome.

So now, the only thing left is:

Being able to reference AvaloniaMauiHybrid and still being able to build on windows... I'll give it a try

@maxkatz6
Copy link
Member

maxkatz6 commented May 2, 2024

The biggest problem of MAUI Windows is that MAUI uses WinUI framework, while Avalonia works on a lower level of Win32 APIs. And WinUI has a bad reputation of being very unfriendly with any kinds of integrations.
So, I don't think there going to be any kind of embedding WinUI controls into Avalonia or the other way.

Using platform APIs, on the other hand, doesn't require that. No need to embed any controls.

If you need to use Maui.Essentials - just reference the package. https://www.nuget.org/packages/Microsoft.Maui.Essentials/.
You will need to change (or add) target framework to net8.0-windows10.0.20348 (or net8.0-windows10.0.19041) since Maui.Essentials doesn't support Windows bindings in a shared net8.0 target. Platform.Init doesn't seem to be required for Windows too.

platform APIs (i.e. Maui.Essentials)

In general, Maui.Essentials is a nice abstraction, making it easier to use platform specific code. Just like Avalonia itself has some APIs, like clipboard of file dialogs.
But you shouldn't limit your app by only these abstractions. You still can reference platform APIs directly.
I.e., in net8.0-android project you can reference Android APIs directly. Same on iOS and Windows.
You also can PInvoke some APIs on any target, but that is harder for sure.

Is there any specific you want to Avalonia to do here?

@maxkatz6
Copy link
Member

maxkatz6 commented May 2, 2024

Being able to reference AvaloniaMauiHybrid and still being able to build on windows... I'll give it a try

Add target framework conditions in your csproj.
So, for example, if you csproj has <TargetFrameworks>net8.0;net8.0-android;net8.0-ios</TargetFrameworks>, then you can include nugets like this:

<!-- This is only android/ios package reference: -->
<PackageReference Include="Package" Version="1.0.0" Condition=''$(TargetFramework)' == 'net8.0-android' OR '$(TargetFramework)' == 'net8.0-ios'' />

Or, if your projects are separated by platform (Project.Android, Project.iOS, Project.Desktop...), then don't need any conditions, just include package only in android+ios projects.

@gentledepp
Copy link

@maxkatz6 thank you for your valuable insights - honestly :-)

However, I already tried this approach, and as soon as I include any of those target frameworks required for Maui.Essentials for Windows, the following happens:

AvaloniaUI/Avalonia#12956 (comment)

@maxkatz6
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

8 participants