CommunityToolkit / Microsoft.Toolkit.Win32

ARCHIVE - This repository contained XAML Islands wrapper controls and tooling for XAML Islands with WinUI 2, see readme for more info about XAML Islands with WinUI 3 and the WindowsAppSDK.
https://aka.ms/windowsappsdk
Other
383 stars 89 forks source link

DesktopWindowXamlSource taskbar icon #290

Open martinchrzan opened 3 years ago

martinchrzan commented 3 years ago

Describe the bug

I do have a WPF window which opens another child window which uses UWP control. Both windows have set ShowInTaskbar=false but when I open child window and close it, "DesktopWindowXamlSource" taskbar icon appear. I am disposing everything I can inside that child window when closing, but this taskbar icon still appears. Any workaround?

Expected behavior

No taskbar icon will appear

Screenshots

image

Environment

NuGet Package(s): 

Package Version(s): 

Project .NET Version:
- [ ] .NET Framework (version: )
- [x] .NET Core 3
- [ ] .NET Core 3.1 Preview (version: )

Windows 10 Build Number:
- [ ] Fall Creators Update (16299)
- [ ] April 2018 Update (17134)
- [ ] October 2018 Update (17763)
- [ ] May 2019 Update (18362)
- [ ] Insider Build (build number: )

App min and target version:
- [ ] Fall Creators Update (16299)
- [ ] April 2018 Update (17134)
- [ ] October 2018 Update (17763)
- [ ] May 2019 Update (18362)
- [ ] Insider Build (xxxxx)
- [x] April 2020 Update (19042)

Device form factor:
- [x] Desktop
- [ ] Xbox
- [ ] Surface Hub
- [ ] IoT

Visual Studio 
- [ ] 2017 (version: )
- [x] 2019 (version: ) 
- [ ] 2019 Preview (version: )

Additional context

Add any other context about the problem here.

ghost commented 3 years ago

Hello martinchrzan, thank you for opening an issue with us!

I have automatically added a "needs triage" label to help get things started. Our team will analyze and investigate the issue, and escalate it to the relevant team if possible. Other community members may also look into the issue and provide feedback πŸ™Œ

DarkCloud14 commented 3 years ago

Hi,

I have the same problem but I'm using .Net Framework 4.7.2 instead and I the minimum targeted Windows 10 version is May 2019 Update (18362), I'm also using VS2019 and work on an application which targets Desktop devices.

I found a not so nice workaround to solve this for me by creating a static window in the static constructor of my MainWindow like this:

    private static readonly Window s_windowsXamlHostWindow;

    static MainWindow()
    {
      s_windowsXamlHostWindow = new Window
      {
        Height = 0,
        Width = 0,
        WindowStyle = WindowStyle.None,
        ShowInTaskbar = false
      };

      s_windowsXamlHostWindow.Show();
      s_windowsXamlHostWindow.Content = new Microsoft.Toolkit.Wpf.UI.XamlHost.WindowsXamlHost();
      s_windowsXamlHostWindow.Hide();
    }

and then in the Closed event of the MainWindow I close the static window again, looks like if you've another window with a WindowsXamlHost initialized first the problem won't happen anymore for other windows.

This workaround isn't really nice and shouldn't be necessary at all but I didn't find any other way to get rid of the DesktopWindowXamlSource icon in taskbar. With the above I didn't have any problems yet but that doesn't mean anything so be careful and decide on your own if you really want to do that. I also didn't test with .Net Core 3 but I would guess that it'll work there too.

martinchrzan commented 3 years ago

@DarkCloud14 Interesting suggestion!

It really works, however when I open my window second time after I closed it, it is just a white rectangle - no content.

I tried to create that extra window in a non-static constructor of my window, or within visibility changed, but then the original issue surface again.

DarkCloud14 commented 3 years ago

@martinchrzan Hmm interesting that it doesn't work for you, just switched my app to .Net Core 3.1 and it still works. Maybe it depends on the controls you use?!

For the static window it was important to have everything setup so far, call Show and only after that initialize WindowsXamlHost as otherwise it doesn't work anymore for whatever reason.

Another possible alternative I found today was putting a WindowsXamlHost control without anything into my MainWindow and setting the visibility to collapsed so you can't see it.

So I just added the following to my MainWindow.xaml: <xamlhost:WindowsXamlHost Visibility="Collapsed"/>

This MainWindow has to stay open as otherwise it won't work anymore but if that is the case I can also open and close child windows which use UWP controls without having the issue. I personally like this workaround a bit more than the static window workaround.

martinchrzan commented 3 years ago

@DarkCloud14 When I add WindowsXamlHost into my MainWindow, it will work first time I open it, and then the application will die, without any exception.

I do have a slightly different scenario - I start with MainWindow hidden - I call Hide(); - in the MainWindow constructor and I only show it when some shortcut is pressed - once it is shown, I can show another ChildWindow which host UWP control - when I close that ChildWindow I also call Hide on MainWindow - after that it will just die.

DarkCloud14 commented 3 years ago

@martinchrzan Ok I understand, well then you might have to wait until the issue is solved correctly, sorry. Should I find anything else in the meantime I'll let you know here.

martinchrzan commented 3 years ago

@DarkCloud14 Great, thanks! I will try to play around some more with your workaround to see if I cannot find some magical combination where it works :)

DarkCloud14 commented 3 years ago

@martinchrzan One last thing which might or might not help you, all the windows I use have ShowInTaskbar set to true except the static window.

I remember that one test I did was setting ShowInTaskbar to false in the Closing event of the child window which hosts the UWP control and after that DesktopWindowXamlSource was also not showing up anymore in the Taskbar but I wasn’t able anymore to create a new child window as that lead to a crash as soon as the child window tried to signup to the OrientationChanged event of DisplayInformation class...

I know this is again a different error and situation as yours and won’t really help you as you might not want the windows to show up in taskbar but maybe there is another problem regarding setting ShowInTaskbar to false at windows that use UWP controls with events etc.?!

DarkCloud14 commented 3 years ago

@martinchrzan I've one more workaround which could also work for you but not sure and I'm also not sure if you want to use it as I call native Windows API functions.

I mostly followed this article of Microsoft and created a custom Program.cs file. As I still use .Net Framework 4.7.2 I can't use the UWP application they suggest and so my Program class looks like this without the native Windows API functions (you must add the needed namespaces yourself...):

  public static class Program
  {
    [STAThread]
    public static void Main()
    {
      //using (new MyUWPApp.App())
      using (new XamlApplication(new List<IXamlMetadataProvider>()))
      {
        var app = new App();
        app.InitializeComponent();
        app.Run();
      }
    }
  }

As soon as I get to var app = new App() the DesktopWindowXamlSource window is already visible in the taskbar and so I tried the following with native Windows API functions:

  public static class Program
  {
    private const int SW_HIDE = 0;

    [DllImport("user32.dll")]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    [STAThread]
    public static void Main()
    {
      //using (new MyUWPApp.App())
      using (new XamlApplication(new List<IXamlMetadataProvider>()))
      {
        // var desktopWindowXamlSourceHandle = FindWindow(null, "DesktopWindowXamlSource");

        // DesktopWindowXamlSource should be our main window at this point so lets use .NET functionality instead of the
        // above FindWindow call which requires adjustments to make sure the retrieved handle belongs to our process.
        var desktopWindowXamlSourceHandle = Process.GetCurrentProcess()?.MainWindowHandle ?? IntPtr.Zero;
        if (desktopWindowXamlSourceHandle != IntPtr.Zero)
        {
          ShowWindow(desktopWindowXamlSourceHandle, SW_HIDE);
        }

        var app = new App();
        app.InitializeComponent();
        app.Run();
      }
    }
  }

And what should I say, this also solved the problem for me but as soon as the window title will change you must adjust it so in the end I hope that this will be fixed in the toolkit itself so we don't need any workarounds.

NOTE: When I tested the above with .NET Core 3.1 I had to use the UWP app instead as written in the Microsoft article, otherwise the application didn't even start, I guess it crashed during creation of the XamlApplication object?!

If that also doesn't work for you, you might be able to use the win api functions to hide the window after you closed your child window..

Also one more info about ShowInTaskbar, if I set this in the constructor of my child window, which hosts a UWP control, to false my application crashes at least when subscribing to the OrientationChanged event of the DisplayInformation class. The crash only happens when I try to open the child window a second time, first time is fine. This also happens when I don't hide the DesktopWindowXamlSource window. I was able to workaround this crash by setting ShowInTaskbar to true in the Closing event of the child window (Closed event is too late and doesn't work). Maybe this info also helps you somehow..

martinchrzan commented 3 years ago

@DarkCloud14 Thanks a lot for the extensive research in this area. For now, I have fixed my problem by simply hiding the window instead of closing it - it is a little more memory consuming and not very clean, but I basically never close the child window and just update content when I need to show it up again - doing so, I am not hitting this issue.

Later, I will try your latest approach, if that helps. Thanks again!

ghost commented 3 years ago

This issue has been marked as "needs attention πŸ‘‹" due to no activity for 15 days. Please triage the issue so the fix can be established.

ghost commented 3 years ago

This issue has been marked as "needs attention πŸ‘‹" due to no activity for 15 days. Please triage the issue so the fix can be established.

ghost commented 3 years ago

This issue has been marked as "needs attention πŸ‘‹" due to no activity for 15 days. Please triage the issue so the fix can be established.

ghost commented 3 years ago

This issue has been marked as "needs attention πŸ‘‹" due to no activity for 15 days. Please triage the issue so the fix can be established.

ghost commented 3 years ago

This issue has been marked as "needs attention πŸ‘‹" due to no activity for 15 days. Please triage the issue so the fix can be established.

ghost commented 3 years ago

This issue has been marked as "needs attention πŸ‘‹" due to no activity for 15 days. Please triage the issue so the fix can be established.

atiyka commented 3 years ago

Thank you guys, I had the same problem and the workaround to add a hidden XamlHost element to the main view solved the issue: <xamlhost:WindowsXamlHost Visibility="Collapsed"/>