skip to Main Content

The Goal

Creating and rendering a simple WinUI3 GUI in PowerShell 7.5 which is based on .NET 9. Nothing complicated, just a window and a button in it, such as this XAML

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="App1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
    </StackPanel>
</Window>

  • Using, importing or defining C# code in PowerShell is totally okay too for the solution.
  • The only thing I don’t want to do is to build/compile binaries of my own such as executables or DLLs. I want to use .cs CSharp files uncompiled in PowerShell if there is a need for CSharp code.
  • Loading and using Microsoft-signed DLLs is completely okay.

What I’ve tried so far

I’ve created a fully working WinUI3 app in Visual Studio 2022 using the latest WindowsApps SDK. Then inside of the Winui3 projectApp1binx64Debugnet8.0-windows10.0.22621.0win-x64 folder I’ve tried loading all of the DLLs in there in PowerShell. Some 200 dlls loaded and a few failed to load.

In PowerShell now I have access to the type [Microsoft.UI.Xaml.Window] but when I try to create an instance of it

New-Object -TypeName Microsoft.UI.Xaml.Window
# Or
[Microsoft.UI.Xaml.Window]::new()

I get the following error

MethodInvocationException: Exception calling ".ctor" with "0" argument(s): "The type initializer for '_IWindowFactory' threw an exception."

It looks like there is a dependency missing for _IWindowFactory.

This is the full error message


Exception             : 
    Type           : System.Management.Automation.MethodInvocationException
    ErrorRecord    : 
        Exception             : 
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Exception calling ".ctor" with "0" argument(s): "The type initializer for '_IWindowFactory' threw an exception."
            HResult : -2146233087
        CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : TypeInitializationException
        InvocationInfo        : 
            ScriptLineNumber : 1
            OffsetInLine     : 1
            HistoryId        : 4
            Line             : [Microsoft.UI.Xaml.Window]::new()
            Statement        : [Microsoft.UI.Xaml.Window]::new()
            PositionMessage  : At line:1 char:1
                               + [Microsoft.UI.Xaml.Window]::new()
                               + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    TargetSite     : 
        Name          : ConvertToMethodInvocationException
        DeclaringType : [System.Management.Automation.ExceptionHandlingOps]
        MemberType    : Method
        Module        : System.Management.Automation.dll
    Message        : Exception calling ".ctor" with "0" argument(s): "The type initializer for '_IWindowFactory' threw an exception."
    Data           : System.Collections.ListDictionaryInternal
    InnerException : 
        Type           : System.TypeInitializationException
        TypeName       : _IWindowFactory
        TargetSite     : 
            Name          : get_Instance
            DeclaringType : [Microsoft.UI.Xaml.Window+_IWindowFactory]
            MemberType    : Method
            Module        : Microsoft.WinUI.dll
        Message        : The type initializer for '_IWindowFactory' threw an exception.
        InnerException : 
            Type           : System.TypeInitializationException
            TypeName       : WinRT.ActivationFactory`1
            TargetSite     : 
                Name          : As
                DeclaringType : [WinRT.ActivationFactory`1[T]]
                MemberType    : Method
                Module        : Microsoft.WinUI.dll
            Message        : The type initializer for 'WinRT.ActivationFactory`1' threw an exception.
            InnerException : 
                Type       : System.Runtime.InteropServices.COMException
                ErrorCode  : -2147221164
                TargetSite : 
                    Name          : ThrowExceptionForHR
                    DeclaringType : [System.Runtime.InteropServices.Marshal]
                    MemberType    : Method
                    Module        : System.Private.CoreLib.dll
                Message    : Class not registered (0x80040154 (REGDB_E_CLASSNOTREG))
                Source     : System.Private.CoreLib
                HResult    : -2147221164
                StackTrace : 
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
   at WinRT.BaseActivationFactory..ctor(String typeNamespace, String typeFullName)
   at WinRT.ActivationFactory`1..ctor()
   at WinRT.ActivationFactory`1..cctor()
            Source         : Microsoft.WinUI
            HResult        : -2146233036
            StackTrace     : 
   at WinRT.ActivationFactory`1.As(Guid iid)
   at Microsoft.UI.Xaml.Window._IWindowFactory..ctor()
   at Microsoft.UI.Xaml.Window._IWindowFactory..cctor()
        Source         : Microsoft.WinUI
        HResult        : -2146233036
        StackTrace     : 
   at Microsoft.UI.Xaml.Window._IWindowFactory.get_Instance()
   at Microsoft.UI.Xaml.Window..ctor()
   at CallSite.Target(Closure, CallSite, Type)
    Source         : System.Management.Automation
    HResult        : -2146233087
    StackTrace     : 
   at System.Management.Automation.ExceptionHandlingOps.ConvertToMethodInvocationException(Exception exception, Type typeToThrow, String methodName, Int32 numArgs, MemberInfo memberInfo)
   at CallSite.Target(Closure, CallSite, Type)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at System.Management.Automation.Interpreter.DynamicInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : TypeInitializationException
InvocationInfo        : 
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : 4
    Line             : [Microsoft.UI.Xaml.Window]::new()
    Statement        : [Microsoft.UI.Xaml.Window]::new()
    PositionMessage  : At line:1 char:1
                       + [Microsoft.UI.Xaml.Window]::new()
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1


Other people have tried this too and had similar results. Another issue related to this problem asking for some guidance from Microsoft.

I don’t know how Visual Studio does this that makes it all so easy and automated, but I believe I need to do the same tasks manually in PowerShell.

2

Answers


  1. Starting a WinUI3 app is quite involved, and supporting full XAML is another difficulty as it also requires compiled XAML files (.xbf), resource files (.pri), etc. These can be built with SDK tools but here I will just demonstrate how to start a WinUI .NET 8 application based on PowerShell 7.4 with or without simple XAML (no automatic binding), without the need for Visual Studio, with zero compilation at deployment time.

    First create a directory and put in there:

    • The following .ps1 file,
    • The content of the latest Microsoft.WindowsAppSDK package nuget, only the libnet6.0-windows10.0.18362.0 directory (as of today, it’s not targeting .NET 8),
    • Add to that WinRT.Runtime.dll from the Microsoft.Windows.CsWinRT nuget
    • Add to that Microsoft.Windows.SDK.NET.dll from the Microsoft.Windows.SDK.NET.Ref nuget
    • Add to that Microsoft.WindowsAppRuntime.Bootstrap.dll from WinAppSDK Runtime (you can find it in a place like C:Program FilesWindowsAppsMicrosoft.WindowsAppRuntime.1.5_5001.95.533.0_x64__8wekyb3d8bbwe as of today). Note: obviously, the Windows App Runtime must be installed on the PC for all this to work.
    • Optionaly put a .ico file if you want nice icons for your windows

    This is how your folder should look (you can delete the .xml files they are for SDK documentation):

    enter image description here

    Now here is the content of BasicWinUI.ps1 (as you can see it’s 95% C#)

    Add-Type -Path ".WinRT.Runtime.dll"
    Add-Type -Path ".Microsoft.Windows.SDK.NET.dll"
    Add-Type -Path ".Microsoft.WindowsAppRuntime.Bootstrap.Net.dll"
    Add-Type -Path ".Microsoft.InteractiveExperiences.Projection.dll"
    Add-Type -Path ".Microsoft.WinUI.dll"
    
    $referencedAssemblies = @(
        "System.Threading" # for SynchronizationContext
        ".WinRT.Runtime.dll"
        ".Microsoft.Windows.SDK.NET.dll"
        ".Microsoft.WindowsAppRuntime.Bootstrap.Net.dll"
        ".Microsoft.InteractiveExperiences.Projection.dll"
        ".Microsoft.WinUI.dll"
    )
    
    #Note: we remove warning CS1701: Assuming assembly reference 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
    #  used by 'Microsoft.WindowsAppRuntime.Bootstrap.Net'
    #  matches identity 'System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime',
    #  you may need to supply runtime policy
    Add-Type -ReferencedAssemblies $referencedAssemblies -CompilerOptions /nowarn:CS1701 -Language CSharp @"
    using System;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Threading;
    using Microsoft.UI.Dispatching;
    using Microsoft.UI.Windowing;
    using Microsoft.UI.Xaml;
    using Microsoft.UI.Xaml.Controls;
    using Microsoft.UI.Xaml.Markup;
    using Microsoft.UI.Xaml.XamlTypeInfo;
    using Microsoft.Windows.ApplicationModel.DynamicDependency;
    using Windows.Graphics;
    using Windows.UI.Popups;
    using WinRT.Interop;
    
    namespace BasicWinUI
    {
        public class App : Application, IXamlMetadataProvider
        {
            private MyWindow m_window;
            private readonly XamlControlsXamlMetaDataProvider _provider = new();
    
            public bool Result => m_window?.Result ?? false;
    
            protected override void OnLaunched(LaunchActivatedEventArgs args)
            {
                if (m_window != null)
                    return;
    
                Resources.MergedDictionaries.Add(new XamlControlsResources());
                m_window = new MyWindow();
                m_window.Activate();
            }
    
            public IXamlType GetXamlType(Type type) => _provider.GetXamlType(type);
            public IXamlType GetXamlType(string fullName) => _provider.GetXamlType(fullName);
            public XmlnsDefinition[] GetXmlnsDefinitions() =>  _provider.GetXmlnsDefinitions();
    
            public static bool Run()
            {
                App app = null;
                Bootstrap.Initialize(0x0010005); // asks for WinAppSDK version 1.5, or gets "Package dependency criteria could not be resolved" error
                XamlCheckProcessRequirements();
                Application.Start((p) =>
                {
                    SynchronizationContext.SetSynchronizationContext(new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread()));
                    app = new App();
                });
                Bootstrap.Shutdown();
                return app?.Result ?? false;
            }
    
            [DllImport("microsoft.ui.xaml")]
            private static extern void XamlCheckProcessRequirements();
        }
    
        public class MyWindow : Window
        {
            public MyWindow()
            {
                Title = "Basic WinUI3";
    
                // set icon by path
                AppWindow.SetIcon("BasicWinUI.ico");
    
                // size & center
                var area = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest);
                var width = 300; var height = 150;
                var rc = new RectInt32((area.WorkArea.Width - width) / 2, (area.WorkArea.Height - height) / 2, width, height);
                AppWindow.MoveAndResize(rc);
    
                // give a "dialog" look
                if (AppWindow.Presenter is OverlappedPresenter p)
                {
                    p.IsMinimizable = false;
                    p.IsMaximizable = false;
                    p.IsResizable = false;
                }
    
                // create the content as a panel
                var panel = new StackPanel { Margin = new Thickness(10) };
                Content = panel;
                panel.Children.Add(new TextBlock { Text = "Are you sure you want to do this?", HorizontalAlignment = HorizontalAlignment.Center });
    
                // create a panel for buttons
                var buttons = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Center };
                panel.Children.Add(buttons);
    
                // add yes & no buttons
                var yes = new Button { Content = "Yes", Margin = new Thickness(10) };
                var no = new Button { Content = "No", Margin = new Thickness(10) };
                buttons.Children.Add(yes);
                buttons.Children.Add(no);
    
                no.Click += (s, e) => Close();
                yes.Click += async (s, e) =>
                {
                    // show some other form
                    var dlg = new MessageDialog("You did click yes", Title);
                    InitializeWithWindow.Initialize(dlg, WindowNative.GetWindowHandle(this));
                    await dlg.ShowAsync();
                    Result = true;
                    Close();
                };
    
                // focus on first button
                panel.Loaded += (s, e) => panel.Focus(FocusState.Keyboard);
            }
    
           public bool Result { get; set; }
         }
    }
    "@;
     
    $ret = [BasicWinUI.App]::Run() # get result (in this sample code it's a boolean)
    $ret
    

    I start it with a .bat like this in the BasicWinUI folder:

    C:myPowerShellPathPowerShell-7.4.2-win-x64pwsh.exe -File BasicWinUI.ps1 
    

    And here is what you should get (XAML free):

    enter image description here

    Now if you want simple XAML support, you can load a XAML file dynamically and bind to UI objects manually. For example, if you create a .XAML file like this and name it BasicWinUIWindow.xaml:

    <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <StackPanel
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Orientation="Horizontal">
            <Button x:Name="okButton">OK</Button>
            <Button x:Name="cancelButton">Cancel</Button>
        </StackPanel>
    </Window>
    

    Place it into the same folder and use a .ps1 like this for example:

    Add-Type -Path ".WinRT.Runtime.dll"
    Add-Type -Path ".Microsoft.Windows.SDK.NET.dll"
    Add-Type -Path ".Microsoft.WindowsAppRuntime.Bootstrap.Net.dll"
    Add-Type -Path ".Microsoft.InteractiveExperiences.Projection.dll"
    Add-Type -Path ".Microsoft.WinUI.dll"
    
    $referencedAssemblies = @(
        "System.IO" # for File
        "System.Threading" # for SynchronizationContext
        ".WinRT.Runtime.dll"
        ".Microsoft.Windows.SDK.NET.dll"
        ".Microsoft.WindowsAppRuntime.Bootstrap.Net.dll"
        ".Microsoft.InteractiveExperiences.Projection.dll"
        ".Microsoft.WinUI.dll"
    )
    
    Add-Type -ReferencedAssemblies $referencedAssemblies -CompilerOptions /nowarn:CS1701 -Language CSharp @"
    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Threading;
    using Microsoft.UI.Dispatching;
    using Microsoft.UI.Windowing;
    using Microsoft.UI.Xaml;
    using Microsoft.UI.Xaml.Controls;
    using Microsoft.UI.Xaml.Markup;
    using Microsoft.UI.Xaml.XamlTypeInfo;
    using Microsoft.Windows.ApplicationModel.DynamicDependency;
    
    namespace BasicWinUI
    {
        public class App : Application, IXamlMetadataProvider
        {
            private readonly XamlControlsXamlMetaDataProvider _provider = new();
            private Window m_window;
            private static bool _ok;
    
            protected override void OnLaunched(LaunchActivatedEventArgs args)
            {
                if (m_window != null)
                    return;
    
                Resources.MergedDictionaries.Add(new XamlControlsResources());
                var dir = Path.GetDirectoryName(typeof(Bootstrap).Assembly.Location);
    
                // load XAML file, should be a Window
                m_window = (Window)XamlReader.Load(File.ReadAllText(Path.Combine(dir, "BasicWinUIWindow.xaml")));
                var sp = (StackPanel)m_window.Content; // we know root is a stack panel, get buttons
                var ok = (Button)sp.FindName("okButton");
                var cancel = (Button)sp.FindName("cancelButton");
                ok.Click += (s, e) => { _ok = true; m_window.Close(); };
                cancel.Click += (s, e) => m_window.Close();
                m_window.Activate();
            }
    
            public IXamlType GetXamlType(Type type) => _provider.GetXamlType(type);
            public IXamlType GetXamlType(string fullName) => _provider.GetXamlType(fullName);
            public XmlnsDefinition[] GetXmlnsDefinitions() =>  _provider.GetXmlnsDefinitions();
    
            public static bool Run()
            {
                Bootstrap.Initialize(0x0010005); // asks for WinAppSDK version 1.5, or gets "Package dependency criteria could not be resolved" error
                XamlCheckProcessRequirements();
                Application.Start((p) =>
                {
                    SynchronizationContext.SetSynchronizationContext(new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread()));
                    new App();
                });
                Bootstrap.Shutdown();
                return _ok;
            }
    
            [DllImport("microsoft.ui.xaml")]
            private static extern void XamlCheckProcessRequirements();
        }
    }
    "@;
     
    $ret = [BasicWinUI.App]::Run() # get result (in this sample code it's a boolean)
    $ret
    

    Now this is what you’ll see:

    enter image description here

    PS: the .ps1 code will return true if you press OK and false if you press Cancel.

    Login or Signup to reply.
  2. Simon provided a fantastic answer. I tried to convert his answer to an all powershell solution. The only part I couldn’t figure out was why this line can’t be translated one for one. $this.Resources.MergedDictionaries.Add([Microsoft.UI.Xaml.Controls.XamlControlsResources]::new())

    This builds the application in another runspace while leaving room to add to the DataContext and to call Window.Activate() when needed by dispatcherqueue.

    # cd 'C:changethis'
    Add-Type -Path ".WinRT.Runtime.dll"
    Add-Type -Path ".Microsoft.Windows.SDK.NET.dll"
    Add-Type -Path ".Microsoft.WindowsAppRuntime.Bootstrap.Net.dll"
    Add-Type -Path ".Microsoft.InteractiveExperiences.Projection.dll"
    Add-Type -Path ".Microsoft.WinUI.dll"
    
    # //Setup runspacepool and shared variable
    $ConcurrentDict = [System.Collections.Concurrent.ConcurrentDictionary[string,object]]::new()
    $State = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
    $RunspaceVariable = [System.Management.Automation.Runspaces.SessionStateVariableEntry]::new('ConcurrentDict', $ConcurrentDict, $null)
    $State.Variables.Add($RunspaceVariable)
    $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, $([int]$env:NUMBER_OF_PROCESSORS + 1), $State, (Get-Host))
    $RunspacePool.Open()
    $Powershell = [PowerShell]::Create()
    $Powershell.RunspacePool = $RunspacePool
    
    $AppSetup = @'
    # cd 'C:changethis'
    Add-Type -Path ".WinRT.Runtime.dll"
    Add-Type -Path ".Microsoft.Windows.SDK.NET.dll"
    Add-Type -Path ".Microsoft.WindowsAppRuntime.Bootstrap.Net.dll"
    Add-Type -Path ".Microsoft.InteractiveExperiences.Projection.dll"
    Add-Type -Path ".Microsoft.WinUI.dll"
    
    class PwshWinUIApp : Microsoft.UI.Xaml.Application, Microsoft.UI.Xaml.Markup.IXamlMetadataProvider {
        # //App is able to load without Microsoft.UI.Xaml.Markup.IXamlMetadataProvider but interaction such as clicking a button will crash the terminal without it.
    
        $MainWindow
        $provider = [Microsoft.UI.Xaml.XamlTypeInfo.XamlControlsXamlMetaDataProvider]::new()
        static [bool]$OkWasClicked
        $SharedConcurrentDictionary
    
        [Microsoft.UI.Xaml.Markup.IXamlType]GetXamlType([type]$type) {
            return $this.provider.GetXamlType($type)
        }
        [Microsoft.UI.Xaml.Markup.IXamlType]GetXamlType([string]$fullname) {
            return $this.provider.GetXamlType($fullname)
        }
        [Microsoft.UI.Xaml.Markup.XmlnsDefinition[]]GetXmlnsDefinitions() {
            return $this.provider.GetXmlnsDefinitions()
        }
    
        PwshWinUIApp() {}
        PwshWinUIApp($SharedConcurrentDictionary) {
            $this.SharedConcurrentDictionary = $SharedConcurrentDictionary
        }
        OnLaunched([Microsoft.UI.Xaml.LaunchActivatedEventArgs]$a) {
            if ($null -ne $this.MainWindow) { return }
    
            # //Don't know why this line is problematic or how to get it to work in powershell. But the app works without it.
            # $this.Resources.MergedDictionaries.Add([Microsoft.UI.Xaml.Controls.XamlControlsResources]::new())
            
            $xaml = '<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
                    <StackPanel
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        Orientation="Horizontal">
                        <TextBlock Text="{Binding tbContent, Mode=TwoWay}" Margin="10" />
                        <Button x:Name="okButton" Margin="10">OK</Button>
                        <Button x:Name="cancelButton" Margin="10">Cancel</Button>
                    </StackPanel>
                </Window>'
    
            $this.MainWindow = [Microsoft.UI.Xaml.Markup.XamlReader]::Load($xaml)
    
            $ClassScope = $this
            $WindowScope = $this.MainWindow
            
            $this.SharedConcurrentDictionary.App = $ClassScope # Terminal will crash on most properties and the object itself when printing to terminal.
            $this.SharedConcurrentDictionary.Window = $WindowScope
            $this.SharedConcurrentDictionary.Dispatcher = $WindowScope.DispatcherQueue
    
            $this.SharedConcurrentDictionary.OnloadFinished = $true
            # $this.MainWindow.Activate()
        }
        static [bool] Run($SharedConcurrentDictionary) {
            [Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap]::Initialize(0x0010005)
    
            [Microsoft.UI.Xaml.Application]::Start({
                [PwshWinUIApp]::new($SharedConcurrentDictionary)
            })
            [Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap]::Shutdown()
            return [PwshWinUIApp]::OkWasClicked
        }
    }
    
    [PwshWinUIApp]::Run($ConcurrentDict)
    '@
    
    # //Start app without window
    $AppSetupScriptBlock = [scriptblock]::Create($AppSetup)
    $null = $Powershell.AddScript($AppSetupScriptBlock)
    $Handle = $Powershell.BeginInvoke()
    
    # //Optional binding to class
    [NoRunspaceAffinity()]
    class binder {
        # //Should inherit IPropertyNotifyChanged
        # //or a dependency object
        binder(){}
        $tbContent = 'Without IPropertyNotifyChanged, this will not update'
    }
    $ConcurrentDict.binder = [binder]::new()
    
    # //Wait for app to finish loading
    while ($ConcurrentDict.OnloadFinished -ne $true) {
        Start-Sleep -Milliseconds 50
    }
    
    # //Send actions to dispatcher such as setting up buttons (Could also bind buttons through a class like above)
    $null = $ConcurrentDict.Dispatcher.TryEnqueue([scriptblock]::create({
        # //This is inside the Window thread/runspace
        # //Because ConcurrentDict is a shared variable, the Window thread can also access it
        # //We have less access compared to wpf, where you could traverse the wpf object on any thread.
        # //If you call $ConcurrentDict.Window.Content outside of this thread, it will be empty.
    
        $sp = $ConcurrentDict.Window.Content
        $ConcurrentDict.Window.Content.DataContext = $ConcurrentDict.binder
    
        $ok = $sp.FindName("okButton")
        $cancel = $sp.FindName("cancelButton")
        
        $ok.add_Click([scriptblock]::create({
            param($s, $e)
            Write-Verbose "sender is: $($s.Name)" -Verbose
            
            [PwshWinUIApp]::OkWasClicked = $true
            
            $ConcurrentDict.ThreadId = "Set from Thread Id: $([System.Threading.Thread]::CurrentThread.ManagedThreadId)"
            $ConcurrentDict.Window.Close()
        }.ToString()))
        
        $cancel.add_Click([scriptblock]::create({
            param($s, $e)
            Write-Verbose "sender is: $($s.Name)" -Verbose
            
            $ConcurrentDict.ThreadId = "Set from Thread Id: $([System.Threading.Thread]::CurrentThread.ManagedThreadId)"
            $ConcurrentDict.Window.Close()
        }.ToString()))
    }.ToString()))
    
    # //Finally show the window via dispatcher
    $Action = {$ConcurrentDict.Window.Activate()}.ToString()
    $NoContextAction = [scriptblock]::create($Action)
    $null = $ConcurrentDict.Window.DispatcherQueue.TryEnqueue($NoContextAction)
    
    "Current Thread Id: $([System.Threading.Thread]::CurrentThread.ManagedThreadId)"
    $ConcurrentDict
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search