-
-
Save kevinblumenfeld/19c5f606d0fda34346270f79a4e688eb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="800" Height="600" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,0" Background="#35333a" BorderThickness="0" BorderBrush="#666374" Foreground="#514e5d" OpacityMask="#5b586d" Name="LoginPageWPF" WindowStartupLocation="CenterScreen" ResizeMode="CanResizeWithGrip" Title="TEAMS MIGRATION TOOL" WindowChrome.IsHitTestVisibleInChrome="True"> | |
<Window.Resources> | |
<ResourceDictionary> | |
<Style TargetType="Button" x:Key="TabButton"> | |
<Setter Property="Background" Value="#E0E0E2"/> | |
<Setter Property="Foreground" Value="#000000"/> | |
<Setter Property="BorderThickness" Value="0"/> | |
<Setter Property="FontWeight" Value="Bold"/> | |
<Setter Property="FontSize" Value="13"/> | |
<Setter Property="TextBlock.TextAlignment" Value="Center"/> | |
<Style.Resources> | |
<Style TargetType="Border"> | |
<Setter Property="CornerRadius" Value="7"/> | |
</Style> | |
</Style.Resources> | |
</Style> | |
<Style TargetType="TextBox" x:Key="TBOX"> | |
<Setter Property="Background" Value="#ffffff"/> | |
<Setter Property="Foreground" Value="#000000"/> | |
<Setter Property="FontSize" Value="13"/> | |
<Setter Property="BorderThickness" Value=".7"/> | |
<Style.Resources> | |
<Style TargetType="Border"> | |
<Setter Property="CornerRadius" Value="7"/> | |
</Style> | |
</Style.Resources> | |
</Style> | |
<Style TargetType="PasswordBox" x:Key="PBOX"> | |
<Setter Property="Background" Value="#ffffff"/> | |
<Setter Property="Foreground" Value="#000000"/> | |
<Setter Property="BorderThickness" Value=".7"/> | |
<Style.Resources> | |
<Style TargetType="Border"> | |
<Setter Property="CornerRadius" Value="7"/> | |
</Style> | |
</Style.Resources> | |
</Style> | |
</ResourceDictionary> | |
</Window.Resources> | |
<Grid Background="#ffffff" ShowGridLines="False" Name="MainGrid" Margin="0,-1,0,1"> | |
<Grid.RowDefinitions> | |
<RowDefinition Height="25"/> | |
<RowDefinition Height="150*"/> | |
<RowDefinition Height="5"/> | |
<RowDefinition Height="300*"/> | |
</Grid.RowDefinitions> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="25"/> | |
<ColumnDefinition Width="*"/> | |
<ColumnDefinition Width="25"/> | |
</Grid.ColumnDefinitions> | |
<Button Name="ColorBT" Content="☀" Background="#ffffff" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" Width="20" Height="20" Margin="0" Grid.Row="0" Grid.Column="2"/> | |
<Button Name="LeftBT" Content="◀" Grid.Row="1" Grid.Column="0" Background="#ffffff" Foreground="#B78CDE" BorderThickness="0" HorizontalAlignment="Left" VerticalAlignment="Center" Width="20" Margin="0" Height="20"/> | |
<Button Name="RightBT" Content="▶" Grid.Row="1" Grid.Column="2" Background="#ffffff" Foreground="#B78CDE" BorderThickness="0" HorizontalAlignment="Right" VerticalAlignment="Center" Width="20" Margin="2" Height="20"/> | |
<TabControl Name="TabNav" Grid.Row="1" Grid.Column="1" SelectedIndex="1" Padding="-1"> | |
<TabItem Name="ConnectGraphTab" Header="Tab 1" Visibility="Collapsed"> | |
<Grid Name="ConnectGraphGrid" Background="#ffffff" Margin="0"> | |
<Grid.ColumnDefinitions> | |
<ColumnDefinition Width="50*"/> | |
<ColumnDefinition Width="50*"/> | |
</Grid.ColumnDefinitions> | |
<Button Name="SelectSourceTenantBT" Grid.Column="0" Style="{StaticResource TabButton}" Content="Select Source" Margin="0,0,0,40" Height="24" Width="200" IsDefault="True" VerticalAlignment="Top"/> | |
<TextBlock Name="OR1" Foreground="#000000" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Top" Text="-OR-" FontSize="12" Height="18" Margin="0,22,0,0"/> | |
<Button Name="AddSourceTenantBT" Grid.Column="0" Style="{StaticResource TabButton}" Content="Add Source" Margin="0,40,0,0" Height="24" Width="200" IsDefault="True" VerticalAlignment="Top"/> | |
<Button Name="SelectDestTenantBT" Grid.Column="1" Style="{StaticResource TabButton}" Content="Select Destination" Margin="0,0,0,40" Height="24" Width="200" IsDefault="True" VerticalAlignment="Top"/> | |
<TextBlock Name="OR2" Foreground="#000000" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Top" Text="-OR-" FontSize="12" Height="18" Margin="0,22,0,0"/> | |
<Button Name="AddDestTenantBT" Grid.Column="1" Style="{StaticResource TabButton}" Content="Add Destination" Margin="0,40,0,0" Height="24" Width="200" IsDefault="True" VerticalAlignment="Top"/> | |
<Button Name="ConnectGraphBT" Grid.Column="0" Grid.ColumnSpan="2" Style="{StaticResource TabButton}" Content="Connect Graph" Margin="0,80,0,0" Height="24" Width="200" IsDefault="True" VerticalAlignment="Top"/> | |
</Grid> | |
</TabItem> | |
<TabItem Name="SelectSourceTab" Grid.Row="1" Header="Tab 2" Visibility="Collapsed"> | |
<Grid Name="SelectSourceGrid" Background="#ffffff" Margin="0"> | |
<Button Name="SelectSourceBT" Style="{StaticResource TabButton}" Content="Select source teams" Height="25" Width="200" Margin="0,0,0,0"/> | |
<TextBlock Name="SelectSourceTB" FontStyle="Italic" Foreground="#3dfc03" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text=" " FontSize="14" Height="21"/> | |
</Grid> | |
</TabItem> | |
<TabItem Name="ViewTeamTab" Grid.Row="1" Header="Tab 3" Visibility="Collapsed"> | |
<Grid Name="ViewTeamGrid" Background="#ffffff" Margin="0"> | |
<Button Name="ViewTeamBT" Style="{StaticResource TabButton}" Content="View selected teams" Height="25" Width="200" Margin="0,0,0,0"/> | |
<TextBlock Name="ViewTeamTB" FontStyle="Italic" Foreground="#3dfc03" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text=" " FontSize="14" Height="21"/> | |
</Grid> | |
</TabItem> | |
<TabItem Name="CloneTeamTab" Grid.Row="1" Header="Tab 4" Visibility="Collapsed"> | |
<Grid Name="CloneTeamGrid" Background="#ffffff" Margin="0"> | |
<Button Name="CloneTeamBT" Style="{StaticResource TabButton}" Content="Clone teams" Height="25" Width="200" Margin="0,0,0,0"/> | |
<TextBlock Name="CloneTeamTB" FontStyle="Italic" Foreground="#3dfc03" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text=" " FontSize="14" Height="21"/> | |
</Grid> | |
</TabItem> | |
<TabItem Name="SnapFileTab" Grid.Row="1" Header="Tab 5" Visibility="Collapsed"> | |
<Grid Name="SnapFileGrid" Background="#ffffff" Margin="0"> | |
<Button Name="SnapFileBT" Style="{StaticResource TabButton}" Content="Backup team files" Height="25" Width="200" Margin="0,0,0,0"/> | |
<TextBlock Name="SnapFileTB" FontStyle="Italic" Foreground="#3dfc03" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text=" " FontSize="14" Height="21"/> | |
</Grid> | |
</TabItem> | |
<TabItem Name="CloneChatTab" Grid.Row="1" Header="Tab 6" Visibility="Collapsed"> | |
<Grid Name="CloneChatGrid" Background="#ffffff" Margin="0"> | |
<Button Name="CloneChatBT" Style="{StaticResource TabButton}" Content="Clone chat messages" Height="25" Width="200" Margin="0,0,0,0"/> | |
<TextBlock Name="CloneChatTB" FontStyle="Italic" Foreground="#3dfc03" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text=" " FontSize="14" Height="21"/> | |
</Grid> | |
</TabItem> | |
<TabItem Name="MigrateFileTab" Grid.Row="1" Header="Tab 7" Visibility="Collapsed"> | |
<Grid Name="MigrateFileGrid" Background="#ffffff" Margin="0"> | |
<Button Name="MigrateFileBT" Style="{StaticResource TabButton}" Content="Migrate files" Height="25" Width="200" Margin="0,0,0,0"/> | |
<TextBlock Name="MigrateFileTB" FontStyle="Italic" Foreground="#3dfc03" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text=" " FontSize="14" Height="21"/> | |
</Grid> | |
</TabItem> | |
</TabControl> | |
<Button Name="Circle1" Style="{StaticResource TabButton}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="10" Width="10" Margin="0,0,120,0"/> | |
<Button Name="Circle2" Style="{StaticResource TabButton}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="10" Width="10" Margin="0,0,80,0"/> | |
<Button Name="Circle3" Style="{StaticResource TabButton}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="10" Width="10" Margin="0,0,40,0"/> | |
<Button Name="Circle4" Style="{StaticResource TabButton}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="10" Width="10" Margin="0,0,0,0"/> | |
<Button Name="Circle5" Style="{StaticResource TabButton}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="10" Width="10" Margin="40,0,0,0"/> | |
<Button Name="Circle6" Style="{StaticResource TabButton}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="10" Width="10" Margin="80,0,0,0"/> | |
<Button Name="Circle7" Style="{StaticResource TabButton}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="10" Width="10" Margin="120,0,0,0"/> | |
<GridSplitter Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Height="5" Background="#ffffff" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> | |
<DataGrid Name="DataGrid" ScrollViewer.PanningMode="None" ItemsSource="{Binding gridData}" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" Background="#FFFFFF" Margin="0,0,0,0" AlternatingRowBackground="LightBlue" AlternationCount="2" HorizontalGridLinesBrush="#FFBBBBBB" VerticalGridLinesBrush="#FFBBBBBB" HorizontalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> | |
</Grid> | |
</Window> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Import-Module "$PSScriptRoot\..\Module\WindowsPresentationFramework" -Force | |
. "$PSScriptRoot\WindowsPresentationFramework.ps1" | |
#Region ThreadSafe | |
# Bind Variables | |
[WindowsPresentationFrameworkThreadSafe()] | |
[PSObject] $Variable = "Herro World from Proxy Scope" | |
[WindowsPresentationFrameworkThreadSafe()] | |
$Sync = [hashtable]::Synchronized(@{}) | |
[WindowsPresentationFrameworkThreadSafe()] | |
[PSCustomObject] $State = [PSCustomObject]@{} | |
# Fastest State | |
[WindowsPresentationFrameworkThreadSafe()] | |
[System.Collections.ObjectModel.ObservableCollection[Object]] $Log = [System.Collections.ObjectModel.ObservableCollection[Object]]::new() | |
function Write-Log | |
{ | |
[WindowsPresentationFrameworkThreadSafe()] | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory)] | |
[string] $Message | |
) | |
$guid = [Guid]::NewGuid() | |
$Message = $Message.Replace("""", """""") | |
# ------------------------- | |
# This works the fastest across all options | |
[void]$Window.Dispatcher.Invoke([action]( | |
[ScriptBlock]::Create( | |
"`$Log.Add(([PSCustomObject]@{ Id = '$Guid'; TimeStamp = [DateTime]::Now; Message=""$Message"";}));" | |
)), "DataBind" | |
) | |
} | |
#EndRegion ThreadSafe | |
$Script:PSTeamsMigratePath = Join-Path -Path $Env:USERPROFILE -ChildPath '.PSTeamsMigrate' | |
$Script:ConfigPath = Join-Path -Path $PSTeamsMigratePath -ChildPath 'Configurations' | |
$Script:TenantPath = Join-Path -Path $ConfigPath -ChildPath 'Tenants' | |
if (-not ($null = Test-Path $TenantPath)) { | |
$ItemSplat = @{ | |
Type = 'Directory' | |
Force = $true | |
ErrorAction = 'SilentlyContinue' | |
} | |
$null = New-Item $PSTeamsMigratePath @ItemSplat | |
$null = New-Item $ConfigPath @ItemSplat | |
$null = New-Item $TenantPath @ItemSplat | |
} | |
function Select-Tenant { | |
(Get-ChildItem $TenantPath -Directory | Where-Object { | |
$_.Name -ne 'Files' | |
} | Select-Object Name | Out-GridView -Title 'Select the tenant and click OK' -OutputMode Single).name | |
} | |
function Select-Source | |
{ | |
[WindowsPresentationFrameworkEventBinding("SelectSourceTenantBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
Write-Host "Click from", $sender.Name | |
#$Script:SourceConnect = Select-Tenant | |
#$Script:SourceConfig = Join-Path $TenantPath -ChildPath "$SourceConnect\Config.xml" | |
#$Script:SourceCred = Join-Path $TenantPath -ChildPath "$SourceConnect\Cred.xml" | |
#$State.AppHash['SourceConnect'] = $SourceConnect | |
#$State.AppHash['SourceConfig'] = $SourceConfig | |
#$State.AppHash['SourceCred'] = $SourceCred | |
async -Passthru { | |
$variable = [Guid]::NewGuid().Guid | |
$sync.Value = "Rubbish" | |
} | await | Out-Host | Write-Host | |
$variable | out-host | |
$sync | Out-Host | |
} | |
function Add-Source | |
{ | |
[WindowsPresentationFrameworkEventBinding("AddSourceTenantBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
Write-Host "Click from", $sender.Name | |
# This is fast | |
Async { | |
foreach ($item in (1..500)) { | |
Write-Log -Message "I am ""$item"" of 10000" | |
} | |
} | |
# Async -Passthru { Start-Sleep 300 } | Await | |
} | |
function Select-Destination | |
{ | |
[WindowsPresentationFrameworkEventBinding("SelectDestTenantBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
$Script:DestConnect = Select-Tenant | |
$Script:DestConfig = Join-Path $TenantPath -ChildPath "$DestConnect\Config.xml" | |
$Script:DestCred = Join-Path $TenantPath -ChildPath "$DestConnect\Cred.xml" | |
$State.AppHash['DestConnect'] = $DestConnect | |
$State.AppHash['DestConfig'] = $DestConfig | |
$State.AppHash['DestCred'] = $DestCred | |
} | |
function Add-Destination | |
{ | |
[WindowsPresentationFrameworkEventBinding("AddDestTenantBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
Register-TeamsGraphApplication | |
} | |
function Connect-SourceAndDestination | |
{ | |
[WindowsPresentationFrameworkEventBinding("ConnectGraphBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
Start-Async { | |
Connect-GTeams | |
}} | |
function Get-Source | |
{ | |
[WindowsPresentationFrameworkEventBinding("SelectSourceBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
$State.AppHash['PSTeamsMigratePath'] = $PSTeamsMigratePath | |
$State.AppHash['ConfigPath'] = $ConfigPath | |
$State.AppHash['TenantPath'] = $TenantPath | |
Get-SourceTeam | |
Get-SourceChannel | |
} | |
function Start-GetMap | |
{ | |
[WindowsPresentationFrameworkEventBinding("ViewTeamBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
Get-Map | Out-GridView -Title 'Current mapping between source and target' | |
} | |
function Start-Clone | |
{ | |
[WindowsPresentationFrameworkEventBinding("CloneTeamBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
Get-Dupe | |
Write-TargetTeamsAndChannels | |
Start-Sleep -Seconds 20 # this could probably be shorter now that we've identified the provisioning issue. Commenting for later | |
Get-DriveID | |
} | |
function Circle_Click { | |
#function Set-Circle { | |
[WindowsPresentationFrameworkEventBinding("Circle1", "Click")] | |
[WindowsPresentationFrameworkEventBinding("Circle2", "Click")] | |
[WindowsPresentationFrameworkEventBinding("Circle3", "Click")] | |
[WindowsPresentationFrameworkEventBinding("Circle4", "Click")] | |
[WindowsPresentationFrameworkEventBinding("Circle5", "Click")] | |
[WindowsPresentationFrameworkEventBinding("Circle6", "Click")] | |
[WindowsPresentationFrameworkEventBinding("Circle7", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
$controlList = $Circle1, $Circle2, $Circle3, $Circle4, $Circle5, $Circle6, $Circle7 | |
$tabNavList = $ConnectGraphTab, $SelectSourceTab, $ViewTeamTab, $CloneTeamTab, $SnapFileTab, $CloneChatTab, $MigrateFileTab | |
foreach ($control in $controlList) { | |
if ($control -eq $sender) { | |
$sender.Height = 15 | |
$sender.Width = 15 | |
$sender.Background = "#B78CDE" | |
continue | |
} | |
$control.Height = 10 | |
$control.Width = 10 | |
$control.Background = "#E0E0E2" | |
} | |
# Set Tab to be visible | |
$tabIndex = $controlList.IndexOf($sender) | |
$TabNav.SelectedItem = $tabNavList[$tabIndex] | |
} | |
function LeftRightBT_Click { | |
[WindowsPresentationFrameworkEventBinding("LeftBT", "Click")] | |
[WindowsPresentationFrameworkEventBinding("RightBT", "Click")] | |
[CmdletBinding()] | |
param($sender, $event) | |
$controlList = $Circle1, $Circle2, $Circle3, $Circle4, $Circle5, $Circle6, $Circle7 | |
$tabNavList = $ConnectGraphTab, $SelectSourceTab, $ViewTeamTab, $CloneTeamTab, $SnapFileTab, $CloneChatTab, $MigrateFileTab | |
$circle = $controlList.Where({ | |
$_.Height -eq 15 -and | |
$_.Width -eq 15 | |
}) | |
$pos = $controlList.IndexOf($circle[0]) | |
switch ($sender.Name) | |
{ | |
"LeftBT" { $pos = $pos - 1 } | |
"RightBT" { $pos = $pos + 1 } | |
} | |
if ($pos -lt 0) { | |
$pos = $controlList.Count - 1 | |
} | |
elseif ($pos -ge $controlList.Count) { | |
$pos = 0 | |
} | |
Circle_Click $controlList[$pos] | |
} | |
function DataGrid_ScrollEventChanged | |
{ | |
[WindowsPresentationFrameworkEventBinding("DataGrid", "System.Windows.Controls.ScrollViewer", "ScrollChangedEvent")] | |
[CmdletBinding()] | |
param($sender, $event) | |
if ($DataGrid.Items.Count -eq 0) { return } | |
$DataGrid.ScrollIntoView( | |
$DataGrid.Items[$DataGrid.Items.Count - 1] | |
); | |
} | |
function LoginPageWPF_Loaded { | |
[WindowsPresentationFrameworkEventBinding("LoginPageWPF", "Loaded")] | |
[CmdletBinding()] | |
param($sender, $event) | |
$sender.Activate() | |
$sender.Focus() | |
#$Window.DataContext = $State.DataContext | |
Circle_Click $Circle1 | |
# Set Binding | |
# This should Syncronize across different locations | |
$DataGrid.ItemsSource = $Log | |
# Do stuff intsantly before we do fun things | |
[void]$Window.Dispatcher.Invoke({ | |
foreach ($i in 1..20000) | |
{ | |
$log.Add([PSCustomObject]@{ | |
TimeStamp = "-----" | |
Message = "Value" | |
Id = "-----" | |
}) | |
} | |
}, "Render" | |
) | |
} | |
$State = [PSCustomObject]@{ | |
DataContext = [System.Collections.ObjectModel.ObservableCollection[Object]]::new() | |
} | |
Import-Window -Path $PSScriptRoot\KevWindow.xaml -ShowDialog |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add-Type -AssemblyName PresentationCore, PresentationFramework | |
function Import-Window { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory)] | |
[System.IO.FileInfo]$Path, | |
[Parameter()] | |
[switch] $ShowDialog, | |
[object] $Type | |
) | |
begin { | |
if (-not $Path.Exists) { | |
Write-Error -Message "Path to xml does not exist" -Category OpenError -ErrorAction Stop | |
} | |
$PathScript = [System.IO.FileInfo]("{0}.ps1" -f $Path.FullName) | |
if (-not $PathScript.Exists) { | |
Write-Error -Message "Path to ps1 does not exist" -Category OpenError -ErrorAction Stop | |
} | |
} | |
process { | |
$xamlRaw = Get-Content $Path -Raw | |
$xaml = [xml]$xamlRaw | |
# SetApp | |
# Build Parser Context for XMLNS | |
# Quick Notes: This allows you to specify a xmlnamespace like x:name="value" | |
$windowParserContext = New-Object System.Windows.Markup.ParserContext | |
$xmlNamespaceManager = [System.Xml.XmlNamespaceManager]::new($xaml.NameTable) | |
foreach ($attribute in $xaml.Window.Attributes) | |
{ | |
if ($attribute.Name.StartsWith("xmlns")) | |
{ | |
$contextName = $attribute.LocalName | |
if ($attribute.LocalName -eq "xmlns") { | |
$contextName = "" | |
} | |
[void]$windowParserContext.XmlnsDictionary.Add($contextName, $attribute.Value) | |
[void]$xmlNamespaceManager.AddNameSpace($contextName, $attribute.Value) | |
} | |
} | |
$windowParserContext.XamlTypeMapper = $xamlTypeMapper | |
[WindowsPresentationFrameworkThreadSafe()]$Window = [Windows.Markup.XamlReader]::Parse($xamlRaw, $windowParserContext) | |
Set-Variable -Name Window -Value $Window -Scope 1 | |
#& $PathScript | |
$resolvedNodes = @{} | |
foreach ($namespace in $xmlNamespaceManager.ForEach({$_})) | |
{ | |
$nodeQuery = "{0}:Name" -f $namespace | |
if ([string]::IsNullOrEmpty($namespace)) { $nodeQuery = "Name" } | |
foreach ($node in $xaml.SelectNodes("//*[@$nodeQuery]", $xmlNamespaceManager)) | |
{ | |
# Set the node in the Script Scope | |
$nodeName = $node.Name | |
$nodeValue = $Window.FindName($node.Name) | |
$resolvedNodes[$nodeName] = $nodeValue | |
$variable = Set-Variable -Passthru -Name $nodeName -Value $nodeValue # -Scope 2 | |
$variable.Attributes.Add( [WindowsPresentationFrameworkThreadSafeAttribute]::new()) | |
} | |
} | |
$commands = Get-Command -CommandType Function | |
foreach ($command in $commands) { | |
if ($null -eq $command.ScriptBlock.Attributes) { continue } | |
$isBinding = $command.ScriptBlock.Attributes.FindAll( | |
{ | |
$args[0].TypeId.Name -eq "WindowsPresentationFrameworkEventBindingAttribute" | |
} | |
) | |
if (-not $isBinding) { | |
continue | |
} | |
foreach ($binding in $isBinding) { | |
try { | |
if ($binding.isSimple) { | |
$control = $resolvedNodes.Item( $binding.Name ) | |
$null = $control."Add_$($binding.EventName)"( $command.ScriptBlock ) | |
} | |
else { | |
$control = $window.FindName($binding.Name) | |
$handlerEvent = ($binding.ControlName -as [Type])::$($binding.EventName) | |
$control.AddHandler( | |
$handlerEvent, | |
$command.ScriptBlock -as ($handlerEvent.Handlertype) | |
) | |
} | |
} | |
catch { | |
$exceptionMessage = "Canning bind {0} to control {1} with the event {2}" -f $command.Name, $binding.Name, $binding.EventName | |
throw $_ | |
#$exceptionMessage | |
} | |
} | |
} | |
# Bind SessionState Variables | |
[void]$Window.Focus() | |
if ($ShowDialog) { | |
return $Window.ShowDialog() | |
} | |
$Window | |
} | |
end { | |
} | |
} | |
function Start-Async { | |
[CmdletBinding()] | |
[Alias("Async")] | |
param( | |
[Parameter(Mandatory)] | |
[ScriptBlock] $ScriptBlock, | |
[Parameter()] | |
[PSObject] $InputObject, | |
[switch] $Passthru | |
) | |
if (-not $Script:Async) { | |
$Script:Async = @{} | |
$Script:Async.Runspaces = New-Object "System.Collections.Generic.List[PSObject]" | |
} | |
$initialSessionState = [initialsessionstate]::CreateDefault() | |
$commands = Get-Command -CommandType Function | |
foreach ($command in $commands) { | |
if ($null -eq $command.ScriptBlock.Attributes) { continue } | |
$isBinding = $command.ScriptBlock.Attributes.FindAll({ $args[0].TypeId.Name -eq "WindowsPresentationFrameworkThreadSafeAttribute" }) | |
if (-not $isBinding) { | |
continue | |
} | |
$initialSessionState.Commands.Add( | |
(New-Object -TypeName System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $command.Name, $command.ScriptBlock.ToString().Replace("[WindowsPresentationFrameworkThreadSafe()]", "")) | |
) | |
} | |
$runspace = [RunspaceFactory]::CreateRunspace($initialSessionState) | |
$runspace.ApartmentState = 'STA' | |
$runspace.ThreadOptions = 'ReuseThread' | |
$runspace.Open() | |
$runspace.Name = "AsyncOperation" | |
#Bind Variables to SessionState | |
Get-Variable | Where-Object { $_.Attributes.Where({$_.TypeId.Name -eq "WindowsPresentationFrameworkThreadSafeAttribute"}) } | ForEach-Object { $runspace.SessionStateProxy.SetVariable($_.Name, $_.Value) } | |
$pipeline = [PowerShell]::Create() | |
$pipeline.Runspace = $runspace | |
$null = $pipeline.AddScript($ScriptBlock) | |
$null = $pipeline.AddArgument($InputObject) | |
$PSCallStack = (Get-PSCallStack)[1] | |
$result = (New-Object PSCustomObject @{ | |
Command = $PSCallStack.Command | |
Pipeline = $pipeline | |
Status = $pipeline.BeginInvoke() | |
}) | |
$Script:Async.Runspaces.Add( | |
$result | |
) | |
if ($Passthru) { | |
return $result | |
} | |
} | |
function Wait-Async { | |
[CmdletBinding()] | |
[Alias("Await")] | |
param( | |
[Parameter(ValueFromPipeline)] | |
[PSCustomObject] | |
$InputObject | |
) | |
if (-not $InputObject) { return } | |
do { | |
if ($Window) { | |
# [void]$Window.Dispatcher.Invoke({ }, "Render") | |
# $Window.UpdateLayout() | |
} | |
Start-Sleep -Milliseconds 5 | |
} until ($InputObject.Status.IsCompleted -eq $true) | |
# Receive Jobs we waited for. | |
$InputObject.Pipeline.EndInvoke($InputObject.Status) | |
} | |
class WindowsPresentationFrameworkEventBindingAttribute : System.Attribute { | |
[string] $Name | |
[string] $EventName | |
[string] $ControlName | |
[bool] $isSimple = $false | |
WindowsPresentationFrameworkEventBindingAttribute([string]$Name, [string]$EventName) { | |
$this.isSimple = $true | |
$this.Name = $Name | |
$this.EventName = $EventName | |
} | |
WindowsPresentationFrameworkEventBindingAttribute([string]$Name, [string] $ControlName, [string] $EventName) { | |
$this.isSimple = $false | |
$this.Name = $Name | |
$this.ControlName = $ControlName | |
$this.EventName = $EventName | |
} | |
} | |
class WindowsPresentationFrameworkThreadSafeAttribute : System.Attribute { } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment