View/1-Xaml.ps1

#
# Xaml
#

Function Global:Get-ViewClass{
    $MenuCommandVb = Get-Content -Raw -Path "TypeDefinition\MenuCommand.vb"
    Add-Type -TypeDefinition $MenuCommandVb -Language VisualBasic -ReferencedAssemblies System,System.Core,System.Windows.Forms,PresentationFramework,PresentationCore,System.Linq,System.ObjectModel | Out-Null

    $WindowsProductLifecycleItemVb = Get-Content -Raw -Path "TypeDefinition\WindowsProductLifecycleItem.vb"
    Add-Type -TypeDefinition $WindowsProductLifecycleItemVb -Language VisualBasic -ReferencedAssemblies WindowsBase,System,System.Core,System.Linq,System.ObjectModel | Out-Null

    $SchedukeTaskTriggerItemVb = Get-Content -Raw -Path "TypeDefinition\SchedukeTaskTriggerItem.vb"
    Add-Type -TypeDefinition $SchedukeTaskTriggerItemVb -Language VisualBasic -ReferencedAssemblies WindowsBase,System,System.Core,System.Linq,System.ObjectModel | Out-Null

    $Script:ShlwapiStrFormatByteSize = Add-Type -PassThru -Name "ShlwapiStrFormatByteSize" -MemberDefinition "[DllImport(""Shlwapi.dll"", CharSet = CharSet.Auto)]
    public static extern long StrFormatByteSize(long fileSize, System.Text.StringBuilder buffer, int bufferSize);"

    Function Global:Convert-DisplayByteSize{
        Param ([Parameter(Mandatory,ValueFromPipeline)][Uint64]$ByteSize)
        $Buffer = New-Object Text.StringBuilder 100
        $ShlwapiStrFormatByteSize::StrFormatByteSize($ByteSize, $Buffer, $Buffer.Capacity) | Out-Null
        $Buffer.ToString()
    }

    Write-Verbose "読み込まれたアセンブリ:"
    $GetAssemblies = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object Location -eq "" | Select-Object FullName,@{Name="DefinedTypes";Expression={$a="";$_.DefinedTypes.SyncRoot.Name|%{$a+="$_, "};$a.Substring(0,$a.Length-2)}},@{Name="ExportedTypes";Expression={$a="";$_.ExportedTypes|%{$a+="$_,"};$a.Substring(0,$a.Length-2)}}
    $GetAssemblies | ForEach-Object{
        Write-Verbose "FullName: $($_.FullName)`nDefinedTypes: $($_.DefinedTypes)`nExportedTypes: $($_.ExportedTypes)"
    }
}

Function Global:Request-Job($Script, $DependentPs1File, $Arguments) {
    $Hash = [hashtable]::Synchronized(@{})
    $Hash.Host = $Host
    $Hash.Location = (Get-Location)
    $Hash.MainWindow = $MainWindow
    $Hash.ScheduledTaskName = $ScheduledTaskName
    $Hash.DetectiveInstalledComponents = $DetectiveInstalledComponents
    $Hash.CurrentConfig = $CurrentConfig
    $Hash.DependentPs1File = (Convert-Path $DependentPs1File)
    $Hash.Arguments = $Arguments

    $Runspace = [RunspaceFactory]::CreateRunspace()
    $Runspace.ApartmentState = [System.Threading.ApartmentState]::STA
    $Runspace.ThreadOptions = [System.Management.Automation.Runspaces.PSThreadOptions]::ReuseThread
    $Runspace.Open()
    $Runspace.SessionStateProxy.SetVariable('Hash',$Hash)
    $Runspace.SessionStateProxy.SetVariable('Script',$Script)
    $Global:PowerShell = [PowerShell]::Create()

    $PowerShell.Runspace = $Runspace
    $PowerShell.AddScript({
        $Global:MainWindow = $Hash.MainWindow
        $Global:HostUi = $Hash.Host.Ui
        Set-Location $Hash.Location
        $Global:CurrentConfig = $Hash.CurrentConfig
        $Global:DependentPs1File = $Hash.DependentPs1File
        $Global:Arguments = $Hash.Arguments

        Invoke-Expression -Command 'Function Global:Write-Host($Text){$HostUi.WriteLine($Text)}' | Out-Null
        Invoke-Expression -Command 'Function Global:Write-Verbose($Text){$HostUi.WriteVerboseLine($Text)}' | Out-Null
        Invoke-Expression -Command 'Function Global:Write-Warning($Text){$HostUi.WriteWarningLine($Text)}' | Out-Null
        Invoke-Expression -Command 'Function Global:Write-Error($Text){$HostUi.WriteErrorLine($Text)}' | Out-Null

        Try{
            & "Scripts\Config.ps1" | Out-Null
            & $DependentPs1File | Out-Null
        }
        Catch{
            $HostUi.WriteErrorLine($PSItem.ToString())
            $HostUi.WriteErrorLine($PSItem.ScriptStackTrace)
        }

        Try{
            Invoke-Expression -Command "$Script" | Out-Null
        }
        Catch{
            $HostUi.WriteErrorLine($PSItem.ToString())
            $HostUi.WriteErrorLine($PSItem.ScriptStackTrace)
        }

    }) | Out-Null
    $PowerShell.BeginInvoke() | Out-Null
}

Function Global:Get-Xaml($Path){
    $XamlDocument = [System.Xml.Linq.XDocument]::Load($Path)
    # ResourceDictionaryのパスを指定
    $XamlDocument.Root.Descendants("{http://schemas.microsoft.com/winfx/2006/xaml/presentation}ResourceDictionary") | Where-Object HasAttributes | ForEach-Object{ If (Test-Path $_.Attribute("Source").Value){$_.Attribute("Source").SetValue((Convert-Path $_.Attribute("Source").Value))} } 
    # 余分なAttributesの削除
    $XamlDocument.Root.Attributes() | Where-Object Name -like "{http://www.w3.org/2000/xmlns/}local" | ForEach-Object{ $_.Remove() }
    $XamlDocument.Root.Attributes() | Where-Object Name -like "{http://schemas.microsoft.com/winfx/2006/xaml}Class" | ForEach-Object{ $_.Remove() }
    $XamlDocument.Root.Attributes() | Where-Object Name -like "{http://schemas.openxmlformats.org/markup-compatibility/2006}Ignorable" | ForEach-Object{ $_.Remove() }
    $XamlDocument.Root.Attributes() | Where-Object Name -like "{http://schemas.microsoft.com/expression/blend/2008}*" | ForEach-Object{ $_.Remove() }
    ($XamlDocument.Root.DescendantNodes() | Where-Object HasAttributes).Attributes() | Where-Object Name -like "{http://schemas.microsoft.com/expression/blend/2008}*" | ForEach-Object{ $_.Remove() }

    Return [Windows.Markup.XamlReader]::Load($XamlDocument.CreateReader())
}

Function Global:Get-MainWindow(){
    $Global:MainWindow = Get-Xaml ".\View\MainWindow.xaml" "SelectedItemTemplateSelector;assembly=$SelectedItemTemplateSelectorAssemblyName"

    Initialize-MainWindowUI
    Initialize-OptionTab
    Initialize-ServerTab
    Initialize-ServerConfigTab
    Initialize-SyncWindowsProductsTab
    Initialize-DeclineRuleTab
    Initialize-ApproveRuleOptionsTab
    Initialize-ScheduleTab
    Initialize-AboutTab

    $MainWindow.FindName("IndicatorRoot").Visibility = [System.Windows.Visibility]::Visible
    Request-Job -Script {Initialize-MainWindowUIJob} -DependentPs1File (Join-Path $PSScriptRoot "Initialize-MainWindowUIJob.Task.ps1") | Out-Null
}