1645 lines
78 KiB
PowerShell
1645 lines
78 KiB
PowerShell
function Set-DeployCenterButtonStyle {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.Button]$Button,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[ValidateSet('Button','PrimaryButton','DangerButton')][string]$Role = 'Button'
|
||
)
|
||
$style = $Theme[$Role]
|
||
$Button.BackColor = $style.Background
|
||
$Button.ForeColor = $style.Foreground
|
||
$Button.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
|
||
$Button.UseVisualStyleBackColor = $false
|
||
$Button.FlatAppearance.BorderSize = 1
|
||
$Button.FlatAppearance.BorderColor = $style.Border
|
||
$Button.FlatAppearance.MouseOverBackColor = $style.HoverBackground
|
||
$Button.FlatAppearance.MouseDownBackColor = $style.PressedBackground
|
||
if (-not $Button.Enabled) {
|
||
$Button.BackColor = $style.DisabledBackground
|
||
$Button.ForeColor = $style.DisabledForeground
|
||
}
|
||
}
|
||
|
||
function New-DeployCenterComboBox {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$Name,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font,
|
||
[Parameter(Mandatory=$true)][AllowEmptyCollection()][string[]]$Items
|
||
)
|
||
|
||
$comboBox = New-Object System.Windows.Forms.ComboBox
|
||
$comboBox.Name = $Name
|
||
$comboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
|
||
$comboBox.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
|
||
$comboBox.BackColor = $Theme.PanelAlt
|
||
$comboBox.ForeColor = $Theme.Text
|
||
$comboBox.Font = $Font
|
||
$comboBox.IntegralHeight = $false
|
||
$comboBox.MaxDropDownItems = 12
|
||
foreach ($item in $Items) { [void]$comboBox.Items.Add($item) }
|
||
return $comboBox
|
||
}
|
||
|
||
function Set-DeployCenterComboBoxTheme {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.ComboBox]$ComboBox,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme
|
||
)
|
||
$ComboBox.BackColor = $Theme.PanelAlt
|
||
$ComboBox.ForeColor = $Theme.Text
|
||
}
|
||
|
||
function New-DeployCenterPartitionProfileSelector {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.GroupBox]$Parent,
|
||
[Parameter(Mandatory=$true)][string[]]$ProfileNames,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font
|
||
)
|
||
|
||
$label = New-Object System.Windows.Forms.Label
|
||
$label.Text = 'Profil de partitionnement'
|
||
$label.Size = New-Object System.Drawing.Size(240, 17)
|
||
$label.ForeColor = $Theme.Text
|
||
$label.BackColor = [System.Drawing.Color]::Transparent
|
||
$label.Font = $Font
|
||
|
||
$comboBox = New-DeployCenterComboBox -Name 'cmbPartitionProfile' -Theme $Theme -Font $Font -Items $ProfileNames
|
||
$Parent.Controls.Add($label)
|
||
$Parent.Controls.Add($comboBox)
|
||
Set-DeployCenterPartitionProfileSelectorLayout -Label $label -ComboBox $comboBox -Width ($Parent.ClientSize.Width - 24)
|
||
|
||
return [pscustomobject]@{ Label = $label; ComboBox = $comboBox }
|
||
}
|
||
|
||
function Set-DeployCenterPartitionProfileSelectorLayout {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.Label]$Label,
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.ComboBox]$ComboBox,
|
||
[Parameter(Mandatory=$true)][int]$Width
|
||
)
|
||
$Label.Location = New-Object System.Drawing.Point(12, 139)
|
||
$ComboBox.Location = New-Object System.Drawing.Point(12, 157)
|
||
$ComboBox.Size = New-Object System.Drawing.Size([Math]::Max(250, $Width), 26)
|
||
}
|
||
|
||
function New-DeployCenterDeploymentControls {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.GroupBox]$Parent,
|
||
[Parameter(Mandatory=$true)][string[]]$ProfileNames,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font
|
||
)
|
||
|
||
$diskLabel = New-Object System.Windows.Forms.Label
|
||
$diskLabel.Text = 'Disque physique'
|
||
$diskLabel.Location = New-Object System.Drawing.Point(12, 20)
|
||
$diskLabel.Size = New-Object System.Drawing.Size(220, 18)
|
||
$diskLabel.Font = $Font
|
||
$diskLabel.ForeColor = $Theme.Text
|
||
$diskLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
|
||
$diskCombo = New-DeployCenterComboBox -Name 'cmbDisk' -Theme $Theme -Font $Font -Items @()
|
||
$diskCombo.Location = New-Object System.Drawing.Point(12, 39)
|
||
$diskCombo.Size = New-Object System.Drawing.Size([Math]::Max(250, $Parent.ClientSize.Width - 24), 26)
|
||
$diskCombo.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right
|
||
|
||
$systemLabel = New-Object System.Windows.Forms.Label
|
||
$systemLabel.Text = 'Système à installer'
|
||
$systemLabel.Location = New-Object System.Drawing.Point(12, 71)
|
||
$systemLabel.Size = New-Object System.Drawing.Size(240, 18)
|
||
$systemLabel.Font = $Font
|
||
$systemLabel.ForeColor = $Theme.Text
|
||
$systemLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
|
||
$chooseSystemButton = New-Object System.Windows.Forms.Button
|
||
$chooseSystemButton.Name = 'btnChooseWindows'
|
||
$chooseSystemButton.Text = 'Choisir…'
|
||
$chooseSystemButton.Size = New-Object System.Drawing.Size(132, 28)
|
||
$chooseSystemButton.Location = New-Object System.Drawing.Point([Math]::Max(12, $Parent.ClientSize.Width - 144), 67)
|
||
$chooseSystemButton.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right
|
||
Set-DeployCenterButtonStyle -Button $chooseSystemButton -Theme $Theme -Role 'Button'
|
||
|
||
$selectedSystemLabel = New-Object System.Windows.Forms.Label
|
||
$selectedSystemLabel.Name = 'lblSelectedWindows'
|
||
$selectedSystemLabel.Text = 'Aucun système sélectionné'
|
||
$selectedSystemLabel.Location = New-Object System.Drawing.Point(12, 98)
|
||
$selectedSystemLabel.Size = New-Object System.Drawing.Size([Math]::Max(250, $Parent.ClientSize.Width - 24), 22)
|
||
$selectedSystemLabel.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right
|
||
$selectedSystemLabel.Font = $Font
|
||
$selectedSystemLabel.AutoEllipsis = $true
|
||
$selectedSystemLabel.ForeColor = $Theme.Secondary
|
||
$selectedSystemLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
|
||
$profileSelector = New-DeployCenterPartitionProfileSelector -Parent $Parent -ProfileNames $ProfileNames -Theme $Theme -Font $Font
|
||
$profileSelector.ComboBox.Enabled = $false
|
||
|
||
$unattendLabel = New-Object System.Windows.Forms.Label
|
||
$unattendLabel.Name = 'lblUnattendProfile'
|
||
$unattendLabel.Text = 'Configuration de première ouverture'
|
||
$unattendLabel.Location = New-Object System.Drawing.Point(12, 190)
|
||
$unattendLabel.Size = New-Object System.Drawing.Size(320, 18)
|
||
$unattendLabel.Font = $Font
|
||
$unattendLabel.ForeColor = $Theme.Text
|
||
$unattendLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
|
||
$unattendCombo = New-DeployCenterComboBox -Name 'cmbUnattendProfile' -Theme $Theme -Font $Font `
|
||
-Items @('Avec OOBE')
|
||
$unattendCombo.Location = New-Object System.Drawing.Point(12, 207)
|
||
$unattendCombo.Size = New-Object System.Drawing.Size([Math]::Max(250, $Parent.ClientSize.Width - 24), 26)
|
||
$unattendCombo.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right
|
||
$unattendCombo.SelectedIndex = 0
|
||
|
||
$hostLabel = New-Object System.Windows.Forms.Label
|
||
$hostLabel.Name = 'lblHostName'
|
||
$hostLabel.Text = "Nom d’hôte"
|
||
$hostLabel.Location = New-Object System.Drawing.Point(12, 240)
|
||
$hostLabel.Size = New-Object System.Drawing.Size(220, 24)
|
||
$hostLabel.Font = $Font
|
||
$hostLabel.ForeColor = $Theme.Text
|
||
$hostLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
|
||
$hostTextBox = New-Object System.Windows.Forms.TextBox
|
||
$hostTextBox.Name = 'txtHostName'
|
||
$hostTextBox.Location = New-Object System.Drawing.Point([Math]::Max(244, $Parent.ClientSize.Width - 202), 237)
|
||
$hostTextBox.Size = New-Object System.Drawing.Size(190, 26)
|
||
$hostTextBox.MaxLength = 15
|
||
$hostTextBox.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right
|
||
$hostTextBox.BackColor = $Theme.PanelAlt
|
||
$hostTextBox.ForeColor = $Theme.Text
|
||
$hostTextBox.Font = $Font
|
||
|
||
$hostLabel.Visible = $false
|
||
$hostTextBox.Visible = $false
|
||
$Parent.Controls.AddRange(@($diskLabel, $diskCombo, $systemLabel, $chooseSystemButton, $selectedSystemLabel, $unattendLabel, $unattendCombo, $hostLabel, $hostTextBox))
|
||
return [pscustomobject]@{
|
||
DiskComboBox = $diskCombo
|
||
ChooseSystemButton = $chooseSystemButton
|
||
SelectedSystemLabel = $selectedSystemLabel
|
||
PartitionProfileLabel = $profileSelector.Label
|
||
PartitionProfileComboBox = $profileSelector.ComboBox
|
||
UnattendProfileLabel = $unattendLabel
|
||
UnattendProfileComboBox = $unattendCombo
|
||
HostNameLabel = $hostLabel
|
||
HostNameTextBox = $hostTextBox
|
||
}
|
||
}
|
||
|
||
function Set-DeployCenterUnattendHostNameVisibility {
|
||
param([Parameter(Mandatory=$true)]$Controls, [Parameter(Mandatory=$true)][bool]$ShowHostName)
|
||
$Controls.HostNameLabel.Visible = $ShowHostName
|
||
$Controls.HostNameTextBox.Visible = $ShowHostName
|
||
}
|
||
|
||
function Set-DeployCenterUnattendProfileChoices {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.ComboBox]$ComboBox,
|
||
[Parameter(Mandatory=$true)][AllowEmptyCollection()][object[]]$Profiles,
|
||
[AllowNull()][string]$EditionName,
|
||
[Parameter(Mandatory=$true)][string]$OobeChoice
|
||
)
|
||
|
||
$isServerEdition = -not [string]::IsNullOrWhiteSpace($EditionName) -and
|
||
$EditionName.IndexOf('server', [StringComparison]::OrdinalIgnoreCase) -ge 0
|
||
$target = if ($isServerEdition) { 'Server' } else { 'Workstation' }
|
||
$choices = @($OobeChoice)
|
||
if (-not [string]::IsNullOrWhiteSpace($EditionName)) {
|
||
$choices += @($Profiles | Where-Object { [string]$_.Target -eq $target } | ForEach-Object { [string]$_.Name })
|
||
}
|
||
|
||
$previousChoice = [string]$ComboBox.SelectedItem
|
||
$ComboBox.BeginUpdate()
|
||
try {
|
||
$ComboBox.Items.Clear()
|
||
foreach ($choice in $choices) { [void]$ComboBox.Items.Add($choice) }
|
||
$selectionIndex = $ComboBox.Items.IndexOf($previousChoice)
|
||
if ($selectionIndex -lt 0) { $selectionIndex = 0 }
|
||
$ComboBox.SelectedIndex = $selectionIndex
|
||
} finally {
|
||
$ComboBox.EndUpdate()
|
||
}
|
||
}
|
||
|
||
function Set-DeployCenterDeploymentControlsLayout {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.GroupBox]$Parent,
|
||
[Parameter(Mandatory=$true)]$Controls
|
||
)
|
||
$width = [Math]::Max(250, $Parent.ClientSize.Width - 24)
|
||
$Controls.DiskComboBox.Size = New-Object System.Drawing.Size($width, 26)
|
||
$Controls.ChooseSystemButton.Location = New-Object System.Drawing.Point([Math]::Max(12, $Parent.ClientSize.Width - 144), 67)
|
||
$Controls.SelectedSystemLabel.Size = New-Object System.Drawing.Size($width, 22)
|
||
Set-DeployCenterPartitionProfileSelectorLayout -Label $Controls.PartitionProfileLabel -ComboBox $Controls.PartitionProfileComboBox -Width $width
|
||
$Controls.UnattendProfileComboBox.Size = New-Object System.Drawing.Size($width, 26)
|
||
$Controls.HostNameTextBox.Location = New-Object System.Drawing.Point([Math]::Max(244, $Parent.ClientSize.Width - 202), 237)
|
||
$Controls.HostNameTextBox.Size = New-Object System.Drawing.Size(190, 26)
|
||
}
|
||
|
||
function New-DeployCenterLogWindow {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font
|
||
)
|
||
$form = New-Object System.Windows.Forms.Form
|
||
$form.Text = 'Journal DeployCenter'
|
||
$form.StartPosition = 'CenterParent'
|
||
$form.Size = New-Object System.Drawing.Size(900, 500)
|
||
$form.MinimumSize = New-Object System.Drawing.Size(560, 300)
|
||
$form.ShowInTaskbar = $false
|
||
$form.BackColor = $Theme.Background
|
||
$form.ForeColor = $Theme.Text
|
||
$form.Font = $Font
|
||
|
||
$textBox = New-Object System.Windows.Forms.TextBox
|
||
$textBox.Name = 'txtLog'
|
||
$textBox.Location = New-Object System.Drawing.Point(12, 12)
|
||
$textBox.Size = New-Object System.Drawing.Size(860, 440)
|
||
$textBox.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right
|
||
$textBox.Multiline = $true
|
||
$textBox.ReadOnly = $true
|
||
$textBox.WordWrap = $false
|
||
$textBox.ScrollBars = [System.Windows.Forms.ScrollBars]::Both
|
||
$textBox.BackColor = $Theme.PanelAlt
|
||
$textBox.ForeColor = $Theme.Text
|
||
$textBox.BorderStyle = [System.Windows.Forms.BorderStyle]::FixedSingle
|
||
$textBox.Font = [System.Drawing.Font]::new('Consolas', [single]9, [System.Drawing.FontStyle]::Regular)
|
||
$form.Controls.Add($textBox)
|
||
|
||
$form.Add_FormClosing({ if ($_.CloseReason -eq [System.Windows.Forms.CloseReason]::UserClosing) { $_.Cancel = $true; $form.Hide() } }.GetNewClosure())
|
||
return [pscustomobject]@{ Form = $form; TextBox = $textBox }
|
||
}
|
||
|
||
function Show-DeployCenterPartitionSizingDialog {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Profile,
|
||
[Parameter(Mandatory=$true)][double]$AvailableGB,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font,
|
||
[System.Windows.Forms.Form]$Owner = $null,
|
||
[System.Collections.IDictionary]$InitialValues = @{}
|
||
)
|
||
|
||
$inputs = @($Profile.Partitions | Where-Object { [string]$_.Size.Policy -eq 'UserInputGB' })
|
||
$remainder = @($Profile.Partitions | Where-Object { [string]$_.Size.Policy -eq 'RemainderAfterInputs' })[0]
|
||
if ($inputs.Count -eq 0 -or $null -eq $remainder) { return $null }
|
||
|
||
$minimumRemainder = [double]$remainder.Size.MinimumGB
|
||
$minimumInputs = 0.0
|
||
foreach ($inputDefinition in $inputs) { $minimumInputs += [double]$inputDefinition.Size.MinimumGB }
|
||
if ($AvailableGB -lt ($minimumInputs + $minimumRemainder)) {
|
||
Show-DeployCenterMessage `
|
||
-Message "L'espace disponible sur ce disque est insuffisant pour le profil '$($Profile.Name)'." `
|
||
-Title 'Partitionnement impossible' -Icon Warning -Owner $Owner -Theme $Theme -Font $Font
|
||
return $null
|
||
}
|
||
|
||
$dialog = New-Object System.Windows.Forms.Form
|
||
$dialog.Text = 'Tailles des partitions'
|
||
$dialog.StartPosition = if ($Owner) { 'CenterParent' } else { 'CenterScreen' }
|
||
$dialog.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
|
||
$dialog.ShowInTaskbar = $false
|
||
$dialog.MinimizeBox = $false
|
||
$dialog.MaximizeBox = $false
|
||
$dialog.BackColor = $Theme.Background
|
||
$dialog.ForeColor = $Theme.Text
|
||
$dialog.Font = $Font
|
||
$dialog.ClientSize = New-Object System.Drawing.Size(470, (152 + ($inputs.Count * 42)))
|
||
|
||
$capacityLabel = New-Object System.Windows.Forms.Label
|
||
$capacityLabel.Location = New-Object System.Drawing.Point(18, 16)
|
||
$capacityLabel.Size = New-Object System.Drawing.Size(430, 34)
|
||
$recoveryPartition = @($Profile.Partitions | Where-Object { [string]$_.Role -eq 'Recovery' }) | Select-Object -First 1
|
||
$winreSizeMB = if ($recoveryPartition) { [int]$recoveryPartition.Size.Value } else { 1024 }
|
||
$capacityLabel.Text = "Capacité estimée après réservation EFI, MSR et WinRE : {0:N1} Go.`r`nTaille WinRE configurée : {1} Mo." -f $AvailableGB, $winreSizeMB
|
||
$capacityLabel.ForeColor = $Theme.Text
|
||
$capacityLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
$capacityLabel.Font = $Font
|
||
$dialog.Controls.Add($capacityLabel)
|
||
|
||
$inputControls = [System.Collections.Generic.List[object]]::new()
|
||
for ($i = 0; $i -lt $inputs.Count; $i++) {
|
||
$definition = $inputs[$i]
|
||
$rowY = 60 + ($i * 42)
|
||
|
||
$label = New-Object System.Windows.Forms.Label
|
||
$label.Location = New-Object System.Drawing.Point(18, ($rowY + 4))
|
||
$label.Size = New-Object System.Drawing.Size(250, 26)
|
||
$label.Text = [string]$definition.Size.Label
|
||
$label.ForeColor = $Theme.Text
|
||
$label.BackColor = [System.Drawing.Color]::Transparent
|
||
$label.Font = $Font
|
||
$dialog.Controls.Add($label)
|
||
|
||
$otherMinimums = 0.0
|
||
for ($j = 0; $j -lt $inputs.Count; $j++) {
|
||
if ($j -ne $i) { $otherMinimums += [double]$inputs[$j].Size.MinimumGB }
|
||
}
|
||
$maximum = [math]::Floor($AvailableGB - $minimumRemainder - $otherMinimums)
|
||
$minimum = [double]$definition.Size.MinimumGB
|
||
$numeric = New-Object System.Windows.Forms.NumericUpDown
|
||
$numeric.Location = New-Object System.Drawing.Point(292, $rowY)
|
||
$numeric.Size = New-Object System.Drawing.Size(150, 28)
|
||
$numeric.Minimum = [decimal]$minimum
|
||
$numeric.Maximum = [decimal]$maximum
|
||
$numeric.DecimalPlaces = 0
|
||
$numeric.Increment = 1
|
||
$numeric.BackColor = $Theme.PanelAlt
|
||
$numeric.ForeColor = $Theme.Text
|
||
$numeric.Font = $Font
|
||
|
||
$initialValue = $null
|
||
if ($InitialValues.Contains([string]$definition.Role)) { $initialValue = [double]$InitialValues[[string]$definition.Role] }
|
||
if ($null -eq $initialValue) {
|
||
$initialValue = [math]::Floor($AvailableGB * ([double]$definition.Size.DefaultPercent / 100))
|
||
}
|
||
$initialValue = [math]::Max($minimum, [math]::Min($maximum, $initialValue))
|
||
$numeric.Value = [decimal]$initialValue
|
||
$inputControls.Add([pscustomobject]@{ Role = [string]$definition.Role; Control = $numeric })
|
||
$dialog.Controls.Add($numeric)
|
||
}
|
||
|
||
$remainderLabel = New-Object System.Windows.Forms.Label
|
||
$remainderLabel.Location = New-Object System.Drawing.Point(18, (62 + ($inputs.Count * 42)))
|
||
$remainderLabel.Size = New-Object System.Drawing.Size(430, 26)
|
||
$remainderLabel.ForeColor = $Theme.Secondary
|
||
$remainderLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
$remainderLabel.Font = $Font
|
||
$dialog.Controls.Add($remainderLabel)
|
||
|
||
$buttonPanel = New-Object System.Windows.Forms.Panel
|
||
$buttonPanel.Dock = [System.Windows.Forms.DockStyle]::Bottom
|
||
$buttonPanel.Height = 58
|
||
$buttonPanel.BackColor = $Theme.PanelAlt
|
||
$dialog.Controls.Add($buttonPanel)
|
||
|
||
$cancelButton = New-Object System.Windows.Forms.Button
|
||
$cancelButton.Text = 'Annuler'
|
||
$cancelButton.Location = New-Object System.Drawing.Point(258, 10)
|
||
$cancelButton.Size = New-Object System.Drawing.Size(92, 36)
|
||
$cancelButton.Font = $Font
|
||
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
|
||
Set-DeployCenterButtonStyle -Button $cancelButton -Theme $Theme -Role 'Button'
|
||
$buttonPanel.Controls.Add($cancelButton)
|
||
|
||
$validateButton = New-Object System.Windows.Forms.Button
|
||
$validateButton.Text = 'Valider'
|
||
$validateButton.Location = New-Object System.Drawing.Point(358, 10)
|
||
$validateButton.Size = New-Object System.Drawing.Size(92, 36)
|
||
$validateButton.Font = $Font
|
||
Set-DeployCenterButtonStyle -Button $validateButton -Theme $Theme -Role 'PrimaryButton'
|
||
$buttonPanel.Controls.Add($validateButton)
|
||
|
||
$dialog.Tag = [pscustomobject]@{ InputControls = $inputControls; AvailableGB = $AvailableGB }
|
||
$updateRemainder = {
|
||
$sum = 0.0
|
||
foreach ($inputControl in $dialog.Tag.InputControls) {
|
||
$inputValue = [double]$inputControl.Control.Value
|
||
$typedValue = 0.0
|
||
if ([double]::TryParse([string]$inputControl.Control.Text, [ref]$typedValue)) { $inputValue = $typedValue }
|
||
$sum += $inputValue
|
||
}
|
||
$remainingGB = $dialog.Tag.AvailableGB - $sum
|
||
$remainderDrive = [string]$remainder.DriveLetter
|
||
$remainderName = if ($remainderDrive) { "$remainderDrive`:" } else { [string]$remainder.Name }
|
||
$remainderLabel.Text = "{0} : {1:N1} Go (espace restant)" -f $remainderName, $remainingGB
|
||
$remainderLabel.ForeColor = if ($remainingGB -lt $minimumRemainder) { $Theme.Danger } else { $Theme.Secondary }
|
||
$validateButton.Enabled = ($remainingGB -ge $minimumRemainder)
|
||
}.GetNewClosure()
|
||
foreach ($inputControl in $inputControls) {
|
||
$inputControl.Control.Add_ValueChanged($updateRemainder)
|
||
$inputControl.Control.Add_TextChanged($updateRemainder)
|
||
}
|
||
& $updateRemainder
|
||
|
||
$validateButton.Add_Click({
|
||
$inputValues = @{}
|
||
foreach ($inputControl in $dialog.Tag.InputControls) { $inputValues[$inputControl.Role] = [double]$inputControl.Control.Value }
|
||
$sum = 0.0
|
||
foreach ($value in $inputValues.Values) { $sum += [double]$value }
|
||
$dialog.Tag = [pscustomobject]@{
|
||
Inputs = $inputValues
|
||
RemainderRole = [string]$remainder.Role
|
||
RemainderGB = [math]::Round(($dialog.Tag.AvailableGB - $sum), 1)
|
||
AvailableGB = $dialog.Tag.AvailableGB
|
||
}
|
||
$dialog.DialogResult = [System.Windows.Forms.DialogResult]::OK
|
||
$dialog.Close()
|
||
})
|
||
$dialog.AcceptButton = $validateButton
|
||
$dialog.CancelButton = $cancelButton
|
||
|
||
if ($Owner) { $result = $dialog.ShowDialog($Owner) } else { $result = $dialog.ShowDialog() }
|
||
$selection = if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $dialog.Tag } else { $null }
|
||
$dialog.Dispose()
|
||
return $selection
|
||
}
|
||
|
||
function Show-DeployCenterMessage {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$Message,
|
||
[Parameter(Mandatory=$true)][string]$Title,
|
||
[ValidateSet('Information','Warning','Error')][string]$Icon = 'Information',
|
||
[System.Windows.Forms.Form]$Owner = $null,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font
|
||
)
|
||
|
||
$messageForm = New-Object System.Windows.Forms.Form
|
||
$messageForm.Text = $Title
|
||
$messageForm.StartPosition = if ($Owner) { 'CenterParent' } else { 'CenterScreen' }
|
||
$messageForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
|
||
$messageForm.ShowInTaskbar = $false
|
||
$messageForm.MinimizeBox = $false
|
||
$messageForm.MaximizeBox = $false
|
||
$messageForm.BackColor = $Theme.Background
|
||
$messageForm.ForeColor = $Theme.Text
|
||
$messageForm.Font = $Font
|
||
|
||
$messageWidth = 390
|
||
$textSize = [System.Windows.Forms.TextRenderer]::MeasureText(
|
||
$Message,
|
||
$Font,
|
||
(New-Object System.Drawing.Size($messageWidth, 0)),
|
||
[System.Windows.Forms.TextFormatFlags]::WordBreak
|
||
)
|
||
$messageHeight = [Math]::Max(42, $textSize.Height + 8)
|
||
$messageForm.ClientSize = New-Object System.Drawing.Size(470, ($messageHeight + 94))
|
||
|
||
$iconLabel = New-Object System.Windows.Forms.Label
|
||
$iconLabel.Location = New-Object System.Drawing.Point(18, 24)
|
||
$iconLabel.Size = New-Object System.Drawing.Size(34, 34)
|
||
$iconLabel.Text = if ($Icon -eq 'Information') { 'i' } else { '!' }
|
||
$iconLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
|
||
$iconLabel.Font = New-Object System.Drawing.Font('Segoe UI', [single]16, [System.Drawing.FontStyle]::Bold)
|
||
$iconLabel.ForeColor = if ($Icon -eq 'Error') { $Theme.Danger } else { $Theme.Accent }
|
||
$iconLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
$messageForm.Controls.Add($iconLabel)
|
||
|
||
$messageLabel = New-Object System.Windows.Forms.Label
|
||
$messageLabel.Location = New-Object System.Drawing.Point(64, 20)
|
||
$messageLabel.Size = New-Object System.Drawing.Size($messageWidth, $messageHeight)
|
||
$messageLabel.Text = $Message
|
||
$messageLabel.ForeColor = $Theme.Text
|
||
$messageLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
$messageLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
|
||
$messageLabel.Font = $Font
|
||
$messageForm.Controls.Add($messageLabel)
|
||
|
||
$buttonPanel = New-Object System.Windows.Forms.Panel
|
||
$buttonPanel.Dock = [System.Windows.Forms.DockStyle]::Bottom
|
||
$buttonPanel.Height = 58
|
||
$buttonPanel.BackColor = $Theme.PanelAlt
|
||
$messageForm.Controls.Add($buttonPanel)
|
||
|
||
$okButton = New-Object System.Windows.Forms.Button
|
||
$okButton.Text = 'OK'
|
||
$okButton.Location = New-Object System.Drawing.Point(362, 10)
|
||
$okButton.Size = New-Object System.Drawing.Size(92, 36)
|
||
$okButton.Font = $Font
|
||
$okButton.Cursor = [System.Windows.Forms.Cursors]::Hand
|
||
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
|
||
Set-DeployCenterButtonStyle -Button $okButton -Theme $Theme -Role 'PrimaryButton'
|
||
$buttonPanel.Controls.Add($okButton)
|
||
$messageForm.AcceptButton = $okButton
|
||
$messageForm.CancelButton = $okButton
|
||
|
||
if ($Owner) {
|
||
[void]$messageForm.ShowDialog($Owner)
|
||
} else {
|
||
[void]$messageForm.ShowDialog()
|
||
}
|
||
$messageForm.Dispose()
|
||
}
|
||
|
||
function Show-DeployCenterDeploymentComplete {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$Message,
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.Form]$Owner,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font
|
||
)
|
||
|
||
$dialog = New-Object System.Windows.Forms.Form
|
||
$dialog.Text = 'Déploiement terminé'
|
||
$dialog.StartPosition = 'CenterParent'
|
||
$dialog.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
|
||
$dialog.ShowInTaskbar = $false
|
||
$dialog.MinimizeBox = $false
|
||
$dialog.MaximizeBox = $false
|
||
$dialog.BackColor = $Theme.Background
|
||
$dialog.ForeColor = $Theme.Text
|
||
$dialog.Font = $Font
|
||
|
||
$messageWidth = 390
|
||
$textSize = [System.Windows.Forms.TextRenderer]::MeasureText(
|
||
$Message, $Font, (New-Object System.Drawing.Size($messageWidth, 0)),
|
||
[System.Windows.Forms.TextFormatFlags]::WordBreak
|
||
)
|
||
$messageHeight = [Math]::Max(42, $textSize.Height + 8)
|
||
$dialog.ClientSize = New-Object System.Drawing.Size(470, ($messageHeight + 126))
|
||
|
||
$iconLabel = New-Object System.Windows.Forms.Label
|
||
$iconLabel.Location = New-Object System.Drawing.Point(18, 24)
|
||
$iconLabel.Size = New-Object System.Drawing.Size(34, 34)
|
||
$iconLabel.Text = 'i'
|
||
$iconLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
|
||
$iconLabel.Font = New-Object System.Drawing.Font('Segoe UI', [single]16, [System.Drawing.FontStyle]::Bold)
|
||
$iconLabel.ForeColor = $Theme.Accent
|
||
$iconLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
$dialog.Controls.Add($iconLabel)
|
||
|
||
$messageLabel = New-Object System.Windows.Forms.Label
|
||
$messageLabel.Location = New-Object System.Drawing.Point(64, 20)
|
||
$messageLabel.Size = New-Object System.Drawing.Size($messageWidth, $messageHeight)
|
||
$messageLabel.Text = $Message
|
||
$messageLabel.ForeColor = $Theme.Text
|
||
$messageLabel.BackColor = [System.Drawing.Color]::Transparent
|
||
$messageLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
|
||
$messageLabel.Font = $Font
|
||
$dialog.Controls.Add($messageLabel)
|
||
|
||
$restartCheckBox = New-Object System.Windows.Forms.CheckBox
|
||
$restartCheckBox.Text = 'Redémarrer cet ordinateur après fermeture'
|
||
$restartCheckBox.Location = New-Object System.Drawing.Point(64, ($messageHeight + 34))
|
||
$restartCheckBox.Size = New-Object System.Drawing.Size(380, 26)
|
||
$restartCheckBox.Checked = $true
|
||
$restartCheckBox.ForeColor = $Theme.Text
|
||
$restartCheckBox.BackColor = [System.Drawing.Color]::Transparent
|
||
$restartCheckBox.Font = $Font
|
||
$dialog.Controls.Add($restartCheckBox)
|
||
|
||
$buttonPanel = New-Object System.Windows.Forms.Panel
|
||
$buttonPanel.Dock = [System.Windows.Forms.DockStyle]::Bottom
|
||
$buttonPanel.Height = 58
|
||
$buttonPanel.BackColor = $Theme.PanelAlt
|
||
$dialog.Controls.Add($buttonPanel)
|
||
|
||
$okButton = New-Object System.Windows.Forms.Button
|
||
$okButton.Text = 'OK'
|
||
$okButton.Location = New-Object System.Drawing.Point(362, 10)
|
||
$okButton.Size = New-Object System.Drawing.Size(92, 36)
|
||
$okButton.Font = $Font
|
||
$okButton.Cursor = [System.Windows.Forms.Cursors]::Hand
|
||
$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
|
||
Set-DeployCenterButtonStyle -Button $okButton -Theme $Theme -Role 'PrimaryButton'
|
||
$buttonPanel.Controls.Add($okButton)
|
||
$dialog.AcceptButton = $okButton
|
||
$dialog.CancelButton = $okButton
|
||
|
||
try {
|
||
$result = $dialog.ShowDialog($Owner)
|
||
return ($result -eq [System.Windows.Forms.DialogResult]::OK -and $restartCheckBox.Checked)
|
||
} finally {
|
||
$dialog.Dispose()
|
||
}
|
||
}
|
||
|
||
function Show-DeployCenterConfirmation {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$Title,
|
||
[Parameter(Mandatory=$true)][string]$Message,
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.Form]$Owner,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font
|
||
)
|
||
|
||
$dialog = New-Object System.Windows.Forms.Form
|
||
$dialog.Text = $Title
|
||
$dialog.StartPosition = 'CenterParent'
|
||
$dialog.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
|
||
$dialog.ShowInTaskbar = $false
|
||
$dialog.MinimizeBox = $false
|
||
$dialog.MaximizeBox = $false
|
||
$dialog.ClientSize = New-Object System.Drawing.Size(540, 210)
|
||
$dialog.BackColor = $Theme.Background
|
||
$dialog.ForeColor = $Theme.Text
|
||
$dialog.Font = $Font
|
||
|
||
$label = New-Object System.Windows.Forms.Label
|
||
$label.Location = New-Object System.Drawing.Point(18, 18)
|
||
$label.Size = New-Object System.Drawing.Size(504, 120)
|
||
$label.Text = $Message
|
||
$label.ForeColor = $Theme.Text
|
||
$label.BackColor = [System.Drawing.Color]::Transparent
|
||
$label.Font = $Font
|
||
$dialog.Controls.Add($label)
|
||
|
||
$cancel = New-Object System.Windows.Forms.Button
|
||
$cancel.Text = 'Annuler'
|
||
$cancel.Location = New-Object System.Drawing.Point(310, 158)
|
||
$cancel.Size = New-Object System.Drawing.Size(100, 36)
|
||
$cancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
|
||
Set-DeployCenterButtonStyle -Button $cancel -Theme $Theme -Role 'Button'
|
||
$dialog.Controls.Add($cancel)
|
||
|
||
$confirm = New-Object System.Windows.Forms.Button
|
||
$confirm.Text = 'Effacer et installer'
|
||
$confirm.Location = New-Object System.Drawing.Point(420, 158)
|
||
$confirm.Size = New-Object System.Drawing.Size(102, 36)
|
||
$confirm.DialogResult = [System.Windows.Forms.DialogResult]::Yes
|
||
Set-DeployCenterButtonStyle -Button $confirm -Theme $Theme -Role 'DangerButton'
|
||
$dialog.Controls.Add($confirm)
|
||
$dialog.CancelButton = $cancel
|
||
$dialog.AcceptButton = $confirm
|
||
|
||
return ($dialog.ShowDialog($Owner) -eq [System.Windows.Forms.DialogResult]::Yes)
|
||
}
|
||
|
||
function New-DeployCenterDeploymentProgress {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font
|
||
)
|
||
|
||
$form = New-Object System.Windows.Forms.Form
|
||
$form.Text = 'Déploiement Windows'
|
||
$form.StartPosition = 'CenterParent'
|
||
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
|
||
$form.ControlBox = $false
|
||
$form.ShowInTaskbar = $false
|
||
$form.ClientSize = New-Object System.Drawing.Size(520, 116)
|
||
$form.BackColor = $Theme.Background
|
||
$form.ForeColor = $Theme.Text
|
||
$form.Font = $Font
|
||
|
||
$status = New-Object System.Windows.Forms.Label
|
||
$status.Location = New-Object System.Drawing.Point(16, 16)
|
||
$status.Size = New-Object System.Drawing.Size(488, 28)
|
||
$status.Text = 'Préparation du déploiement…'
|
||
$status.AutoEllipsis = $true
|
||
$status.ForeColor = $Theme.Text
|
||
$status.BackColor = [System.Drawing.Color]::Transparent
|
||
$status.Font = $Font
|
||
$form.Controls.Add($status)
|
||
|
||
$bar = New-Object System.Windows.Forms.ProgressBar
|
||
$bar.Location = New-Object System.Drawing.Point(16, 56)
|
||
$bar.Size = New-Object System.Drawing.Size(488, 24)
|
||
$bar.Style = [System.Windows.Forms.ProgressBarStyle]::Marquee
|
||
$bar.MarqueeAnimationSpeed = 25
|
||
$form.Controls.Add($bar)
|
||
|
||
return [pscustomobject]@{ Form = $form; StatusLabel = $status; ProgressBar = $bar; Action = $null }
|
||
}
|
||
|
||
function Set-DeployCenterFormSizing {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.Form]$Form,
|
||
[switch]$Resizable
|
||
)
|
||
if ($Resizable) {
|
||
$Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Sizable
|
||
$Form.MaximizeBox = $true
|
||
} else {
|
||
$Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
|
||
$Form.MaximizeBox = $false
|
||
}
|
||
}
|
||
|
||
function Add-SessionFooter {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Windows.Forms.Form]$TargetForm,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font,
|
||
[AllowNull()][string]$IPv4,
|
||
[AllowNull()][string]$VncPassword,
|
||
[bool]$ShowFooter = $true,
|
||
[bool]$ShowPassword = $true
|
||
)
|
||
if (-not $ShowFooter) { return }
|
||
|
||
$footer = New-Object System.Windows.Forms.Label
|
||
$footer.Name = 'DeployCenterSessionFooter'
|
||
$footer.Text = if ($IPv4) { "IP de déploiement : $IPv4" } else { 'IP de déploiement indisponible' }
|
||
if ($ShowPassword -and -not [string]::IsNullOrWhiteSpace($VncPassword)) {
|
||
$footer.Text += " | Mot de passe VNC : $VncPassword"
|
||
}
|
||
$footer.Height = 26
|
||
$footer.Dock = [System.Windows.Forms.DockStyle]::Bottom
|
||
$footer.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
|
||
$footer.Padding = New-Object System.Windows.Forms.Padding(12, 0, 0, 0)
|
||
$footer.BackColor = $Theme.PanelAlt
|
||
$footer.ForeColor = $Theme.Text
|
||
$footer.Font = $Font
|
||
$TargetForm.Controls.Add($footer)
|
||
$footer.BringToFront()
|
||
}
|
||
|
||
function New-Label {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$Text,
|
||
[Parameter(Mandatory=$true)][int]$X,
|
||
[Parameter(Mandatory=$true)][int]$Y,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font,
|
||
[int]$Width = 180,
|
||
[int]$Height = 24,
|
||
[AllowNull()]$Color = $null
|
||
)
|
||
|
||
$label = New-Object System.Windows.Forms.Label
|
||
$label.Text = $Text
|
||
$label.Location = New-Object System.Drawing.Point($X, $Y)
|
||
$label.Size = New-Object System.Drawing.Size($Width, $Height)
|
||
$label.AutoEllipsis = $true
|
||
$label.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
|
||
$label.BackColor = [System.Drawing.Color]::Transparent
|
||
$label.ForeColor = if ($null -eq $Color) { $Theme.Text } else { $Color }
|
||
$label.Font = $Font
|
||
return $label
|
||
}
|
||
|
||
function New-GroupBox {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$Text,
|
||
[Parameter(Mandatory=$true)][int]$X,
|
||
[Parameter(Mandatory=$true)][int]$Y,
|
||
[Parameter(Mandatory=$true)][int]$Width,
|
||
[Parameter(Mandatory=$true)][int]$Height,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font
|
||
)
|
||
$group = New-Object DeployCenter.ThemedGroupBox
|
||
$group.Text = $Text
|
||
$group.Location = New-Object System.Drawing.Point($X, $Y)
|
||
$group.Size = New-Object System.Drawing.Size($Width, $Height)
|
||
$group.ForeColor = $Theme.Text
|
||
$group.BackColor = $Theme.Panel
|
||
$group.PanelColor = $Theme.Panel
|
||
$group.BorderColor = $Theme.Border
|
||
$group.TextColor = $Theme.Text
|
||
$group.Font = $Font
|
||
return $group
|
||
}
|
||
|
||
function New-Button {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$Text,
|
||
[Parameter(Mandatory=$true)][int]$X,
|
||
[Parameter(Mandatory=$true)][int]$Y,
|
||
[Parameter(Mandatory=$true)][int]$Width,
|
||
[Parameter(Mandatory=$true)][int]$Height,
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Theme,
|
||
[Parameter(Mandatory=$true)][System.Drawing.Font]$Font,
|
||
[ValidateSet('Button','PrimaryButton','DangerButton')][string]$Role = 'Button'
|
||
)
|
||
$button = New-Object System.Windows.Forms.Button
|
||
$button.Text = $Text
|
||
$button.Location = New-Object System.Drawing.Point($X, $Y)
|
||
$button.Size = New-Object System.Drawing.Size($Width, $Height)
|
||
$button.Tag = $Role
|
||
Set-DeployCenterButtonStyle -Button $button -Theme $Theme -Role $Role
|
||
$button.Font = $Font
|
||
$button.Cursor = [System.Windows.Forms.Cursors]::Hand
|
||
$button.AutoSize = $false
|
||
$button.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
|
||
return $button
|
||
}
|
||
|
||
function Get-DeployCenterLogoPathForTheme {
|
||
param(
|
||
[Parameter(Mandatory=$true)][string]$ThemeName,
|
||
[Parameter(Mandatory=$true)][string]$LogoPath,
|
||
[Parameter(Mandatory=$true)][string]$LogoDarkPath
|
||
)
|
||
if ($ThemeName -eq 'Dark' -and (Test-Path -LiteralPath $LogoDarkPath -PathType Leaf)) { return $LogoDarkPath }
|
||
if (Test-Path -LiteralPath $LogoPath -PathType Leaf) { return $LogoPath }
|
||
if (Test-Path -LiteralPath $LogoDarkPath -PathType Leaf) { return $LogoDarkPath }
|
||
return $null
|
||
}
|
||
|
||
function Update-DeployCenterLogo {
|
||
param(
|
||
[Parameter(Mandatory=$true)][AllowNull()][System.Windows.Forms.PictureBox]$PictureBox,
|
||
[Parameter(Mandatory=$true)][string]$ThemeName,
|
||
[Parameter(Mandatory=$true)][string]$LogoPath,
|
||
[Parameter(Mandatory=$true)][string]$LogoDarkPath
|
||
)
|
||
if ($null -eq $PictureBox) { return }
|
||
$selectedLogoPath = Get-DeployCenterLogoPathForTheme -ThemeName $ThemeName -LogoPath $LogoPath -LogoDarkPath $LogoDarkPath
|
||
if ([string]::IsNullOrWhiteSpace($selectedLogoPath)) { return }
|
||
|
||
try {
|
||
$newImage = [System.Drawing.Image]::FromFile($selectedLogoPath)
|
||
$oldImage = $PictureBox.Image
|
||
$PictureBox.Image = $newImage
|
||
if ($null -ne $oldImage) { $oldImage.Dispose() }
|
||
$PictureBox.Visible = $true
|
||
} catch {
|
||
# Conserver le logo déjà affiché si le nouveau fichier est absent ou invalide.
|
||
}
|
||
}
|
||
|
||
|
||
|
||
# Workflows de l'interface principale ; dot-sourcés pour partager explicitement l'état de session DeployCenter.
|
||
function Set-DiskSelectorWidth {
|
||
if ($null -eq $script:cmbDisk -or $null -eq $script:groupDisks) { return }
|
||
Set-DeployCenterDeploymentControlsLayout -Parent $script:groupDisks -Controls $deploymentControls
|
||
}
|
||
|
||
function Set-ControlTheme {
|
||
param([System.Windows.Forms.Control]$Control)
|
||
|
||
# Le formulaire principal doit lui aussi changer de fond.
|
||
if ($Control -is [System.Windows.Forms.Form]) {
|
||
$Control.BackColor = $script:Theme.Background
|
||
$Control.ForeColor = $script:Theme.Text
|
||
}
|
||
elseif ($Control -is [DeployCenter.ThemedGroupBox]) {
|
||
$Control.BackColor = $script:Theme.Panel
|
||
$Control.PanelColor = $script:Theme.Panel
|
||
$Control.BorderColor = $script:Theme.Border
|
||
$Control.TextColor = $script:Theme.Text
|
||
$Control.ForeColor = $script:Theme.Text
|
||
$Control.Invalidate()
|
||
}
|
||
elseif ($Control -is [System.Windows.Forms.Label]) {
|
||
$Control.ForeColor = $script:Theme.Text
|
||
if ($Control.Name -eq 'lblSelectedWindows') {
|
||
$Control.ForeColor = if ($script:SelectedWindowsEdition) { $script:Theme.Success } else { $script:Theme.Secondary }
|
||
}
|
||
# Le pied de page VNC suit lui aussi la palette du thème actif.
|
||
if ($Control.Name -eq 'DeployCenterSessionFooter') {
|
||
$Control.BackColor = $script:Theme.PanelAlt
|
||
$Control.ForeColor = $script:Theme.Secondary
|
||
$Control.Invalidate()
|
||
}
|
||
}
|
||
elseif ($Control -is [System.Windows.Forms.ListView]) {
|
||
$Control.BackColor = $script:Theme.PanelAlt
|
||
$Control.ForeColor = $script:Theme.Text
|
||
}
|
||
elseif ($Control -is [System.Windows.Forms.ComboBox]) {
|
||
Set-DeployCenterComboBoxTheme -ComboBox $Control -Theme $script:Theme
|
||
}
|
||
elseif ($Control -is [System.Windows.Forms.TextBox]) {
|
||
$Control.BackColor = $script:Theme.PanelAlt
|
||
$Control.ForeColor = $script:Theme.Text
|
||
}
|
||
|
||
foreach ($child in $Control.Controls) {
|
||
Set-ControlTheme -Control $child
|
||
}
|
||
}
|
||
|
||
function Set-DeployCenterTheme {
|
||
param([Parameter(Mandatory=$true)][string]$ThemeName)
|
||
|
||
$availableThemes = @(Get-DeployCenterThemeNames -ThemesRoot $script:ThemesRoot)
|
||
if ($availableThemes -notcontains $ThemeName) { return }
|
||
try {
|
||
$script:Theme = Import-DeployCenterTheme -ThemesRoot $script:ThemesRoot -ThemeName $ThemeName
|
||
} catch {
|
||
& $script:SourceLogAction ("Impossible de charger le theme '$ThemeName' : " + $_.Exception.Message) "ERROR"
|
||
return
|
||
}
|
||
$script:CurrentTheme = $ThemeName
|
||
$script:cmbTheme.BackColor = $script:Theme.Panel
|
||
$script:cmbTheme.ForeColor = $script:Theme.Text
|
||
$script:cmbTheme.Invalidate()
|
||
$script:cmbTheme.Refresh()
|
||
|
||
Set-ControlTheme -Control $script:form
|
||
Set-ControlTheme -Control $script:logForm
|
||
|
||
# Met a jour le logo si une variante propre au theme existe.
|
||
Update-DeployCenterLogo -PictureBox $script:pictureLogo -ThemeName $script:CurrentTheme `
|
||
-LogoPath $script:LogoPath -LogoDarkPath $script:LogoDarkPath
|
||
|
||
$script:lblTitle.ForeColor = $script:Theme.Text
|
||
$script:lblSubtitle.ForeColor = $script:Theme.Secondary
|
||
|
||
Set-DeployCenterButtonStyle -Button $script:btnChooseWindows -Theme $script:Theme -Role 'Button'
|
||
Set-DeployCenterButtonStyle -Button $script:btnLog -Theme $script:Theme -Role 'Button'
|
||
Set-DeployCenterButtonStyle -Button $script:btnRefresh -Theme $script:Theme -Role 'PrimaryButton'
|
||
Set-DeployCenterButtonStyle -Button $script:btnDeploy -Theme $script:Theme -Role 'PrimaryButton'
|
||
Set-DeployCenterButtonStyle -Button $script:btnClose -Theme $script:Theme -Role 'DangerButton'
|
||
# Actualise explicitement le pied de page principal lors du changement de thème.
|
||
foreach ($footer in $script:form.Controls.Find('DeployCenterSessionFooter', $true)) {
|
||
$footer.BackColor = $script:Theme.PanelAlt
|
||
$footer.ForeColor = $script:Theme.Secondary
|
||
$footer.Invalidate()
|
||
}
|
||
$script:cmbTheme.BackColor = $script:Theme.Panel
|
||
$script:cmbTheme.ForeColor = $script:Theme.Text
|
||
$script:cmbTheme.Invalidate()
|
||
$script:groupPC.Invalidate()
|
||
$script:groupDisks.Invalidate()
|
||
$script:cmbDisk.BackColor = $script:Theme.PanelAlt
|
||
$script:cmbDisk.ForeColor = $script:Theme.Text
|
||
$script:cmbDisk.Invalidate()
|
||
# Le bouton reste au-dessus des autres controles de l'en-tete.
|
||
$script:cmbTheme.BringToFront()
|
||
|
||
# Forcer le rafraichissement apres le changement de palette.
|
||
$script:form.SuspendLayout()
|
||
try {
|
||
foreach ($control in $script:form.Controls) {
|
||
$control.Invalidate($true)
|
||
}
|
||
$script:form.Invalidate($true)
|
||
$script:form.Refresh()
|
||
}
|
||
finally {
|
||
$script:form.ResumeLayout($true)
|
||
}
|
||
}
|
||
|
||
function Show-WindowsSourcesDialog {
|
||
$dlg = New-Object System.Windows.Forms.Form
|
||
$dlg.Text = 'Sources Windows - lecteur DeployCenter et partage SMB'
|
||
$dlg.StartPosition = 'CenterParent'
|
||
$dlg.Size = New-Object System.Drawing.Size(1100, 700)
|
||
$dlg.MinimumSize = New-Object System.Drawing.Size(700, 450)
|
||
Set-DeployCenterFormSizing -Form $dlg -Resizable
|
||
# Ouvrir directement en plein écran pour exploiter toute la surface disponible.
|
||
$dlg.WindowState = [System.Windows.Forms.FormWindowState]::Maximized
|
||
$dlg.ShowInTaskbar = $false
|
||
$dlg.BackColor = $script:Theme.Background
|
||
$dlg.ForeColor = $script:Theme.Text
|
||
$dlg.Font = $script:FontRegular
|
||
|
||
$lblPath = New-Object System.Windows.Forms.Label
|
||
$lblPath.Text = 'Chemins à analyser (séparés par ;) :'
|
||
$lblPath.Location = New-Object System.Drawing.Point(16, 16)
|
||
$lblPath.Size = New-Object System.Drawing.Size(260, 24)
|
||
$lblPath.ForeColor = $script:Theme.Text
|
||
$dlg.Controls.Add($lblPath)
|
||
|
||
$txtPath = New-Object System.Windows.Forms.TextBox
|
||
$txtPath.Location = New-Object System.Drawing.Point(16, 42)
|
||
$txtPath.Size = New-Object System.Drawing.Size(560, 26)
|
||
$txtPath.Anchor = 'Top,Left,Right'
|
||
$defaultSourceRoot = $script:DeployVolumeRoot
|
||
if ([string]::IsNullOrWhiteSpace($defaultSourceRoot)) { $defaultSourceRoot = $script:DeployRoot }
|
||
$configuredPaths = [string]$script:Config.SourcePaths
|
||
if ([string]::IsNullOrWhiteSpace($configuredPaths)) {
|
||
$txtPath.Text = $defaultSourceRoot
|
||
} else {
|
||
$txtPath.Text = $configuredPaths.Replace("%DEPLOY_VOLUME%", $defaultSourceRoot)
|
||
}
|
||
$txtPath.BackColor = $script:Theme.PanelAlt
|
||
$txtPath.ForeColor = $script:Theme.Text
|
||
$dlg.Controls.Add($txtPath)
|
||
|
||
$btnScan = New-Object System.Windows.Forms.Button
|
||
$btnScan.Text = 'Rechercher'
|
||
$btnScan.Location = New-Object System.Drawing.Point(650, 40)
|
||
$btnScan.Size = New-Object System.Drawing.Size(100, 30)
|
||
$btnScan.Anchor = 'Top,Right'
|
||
$btnScan.UseVisualStyleBackColor = $false
|
||
$btnScan.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
|
||
$btnScan.FlatAppearance.BorderColor = $script:Theme.Border
|
||
$btnScan.BackColor = $script:Theme.Accent
|
||
$btnScan.ForeColor = [System.Drawing.Color]::White
|
||
$dlg.Controls.Add($btnScan)
|
||
|
||
$btnEditions = New-Object System.Windows.Forms.Button
|
||
$btnEditions.Text = 'Afficher les éditions'
|
||
$btnEditions.Location = New-Object System.Drawing.Point(760, 40)
|
||
$btnEditions.Size = New-Object System.Drawing.Size(150, 30)
|
||
$btnEditions.Anchor = 'Top,Right'
|
||
$btnEditions.UseVisualStyleBackColor = $false
|
||
$btnEditions.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
|
||
$btnEditions.FlatAppearance.BorderColor = $script:Theme.Border
|
||
$btnEditions.BackColor = $script:Theme.Panel
|
||
$btnEditions.ForeColor = $script:Theme.Text
|
||
$dlg.Controls.Add($btnEditions)
|
||
|
||
$list = New-Object System.Windows.Forms.ListView
|
||
$list.Location = New-Object System.Drawing.Point(16, 84)
|
||
$list.Size = New-Object System.Drawing.Size(770, 420)
|
||
$list.Anchor = 'Top,Bottom,Left,Right'
|
||
$list.View = 'Details'; $list.FullRowSelect = $true; $list.GridLines = $true
|
||
$list.MultiSelect = $false
|
||
$list.HideSelection = $true
|
||
$list.BackColor = $script:Theme.PanelAlt
|
||
$list.ForeColor = $script:Theme.Text
|
||
$list.OwnerDraw = $true
|
||
[void]$list.Columns.Add('Type', 135)
|
||
[void]$list.Columns.Add('Nom', 260)
|
||
[void]$list.Columns.Add('Taille', 80)
|
||
[void]$list.Columns.Add('Chemin', 250)
|
||
|
||
# La colonne Nom est prioritaire : elle absorbe l'espace libre.
|
||
$resizeSourceColumns = {
|
||
if ($list.Columns.Count -ge 4) {
|
||
$availableWidth = $list.ClientSize.Width - $list.Columns[0].Width - $list.Columns[2].Width - $list.Columns[3].Width - 4
|
||
if ($list.Items.Count -gt 0 -and $list.Items.Count -gt [math]::Floor($list.ClientSize.Height / 20)) {
|
||
$availableWidth -= [System.Windows.Forms.SystemInformation]::VerticalScrollBarWidth
|
||
}
|
||
$list.Columns[1].Width = [Math]::Max(180, $availableWidth)
|
||
}
|
||
}
|
||
$list.Add_SizeChanged($resizeSourceColumns)
|
||
$list.Add_HandleCreated($resizeSourceColumns)
|
||
|
||
# Dessin personnalise des en-tetes et des lignes pour que le ListView
|
||
# respecte le theme actif au lieu d'utiliser les en-tetes natifs blancs.
|
||
$list.Add_DrawColumnHeader({
|
||
param($sender, $e)
|
||
$headerColor = if ($script:Theme.Contains('TableHeader')) { $script:Theme.TableHeader } else { $script:Theme.PanelAlt }
|
||
$headerBrush = New-Object System.Drawing.SolidBrush($headerColor)
|
||
$textBrush = New-Object System.Drawing.SolidBrush($script:Theme.Text)
|
||
$borderPen = New-Object System.Drawing.Pen($script:Theme.Border)
|
||
try {
|
||
$e.Graphics.FillRectangle($headerBrush, $e.Bounds)
|
||
$e.Graphics.DrawRectangle($borderPen, $e.Bounds.X, $e.Bounds.Y, $e.Bounds.Width - 1, $e.Bounds.Height - 1)
|
||
$flags = [System.Windows.Forms.TextFormatFlags]::Left -bor [System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor [System.Windows.Forms.TextFormatFlags]::EndEllipsis
|
||
[System.Windows.Forms.TextRenderer]::DrawText($e.Graphics, $e.Header.Text, $list.Font, $e.Bounds, $script:Theme.Text, $flags)
|
||
} finally {
|
||
$headerBrush.Dispose(); $textBrush.Dispose(); $borderPen.Dispose()
|
||
}
|
||
})
|
||
$list.Add_DrawItem({
|
||
param($sender, $e)
|
||
if ($list.View -ne [System.Windows.Forms.View]::Details) {
|
||
$e.DrawDefault = $true
|
||
}
|
||
})
|
||
$list.Add_DrawSubItem({
|
||
param($sender, $e)
|
||
$rowBack = if (($e.Item.Index % 2) -eq 0) { $script:Theme.TableRowEven } else { $script:Theme.TableRowOdd }
|
||
$rowFore = $script:Theme.Text
|
||
# Ne surligner que l'element réellement sélectionné, jamais toutes les lignes.
|
||
if ($e.Item.Selected -and $list.Focused) {
|
||
$rowBack = $script:Theme.Accent
|
||
$rowFore = [System.Drawing.Color]::White
|
||
}
|
||
$rowBrush = New-Object System.Drawing.SolidBrush($rowBack)
|
||
$textBrush = New-Object System.Drawing.SolidBrush($rowFore)
|
||
$borderPen = New-Object System.Drawing.Pen($script:Theme.Border)
|
||
try {
|
||
$e.Graphics.FillRectangle($rowBrush, $e.Bounds)
|
||
$e.Graphics.DrawRectangle($borderPen, $e.Bounds.X, $e.Bounds.Y, $e.Bounds.Width - 1, $e.Bounds.Height - 1)
|
||
$flags = [System.Windows.Forms.TextFormatFlags]::Left -bor [System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor [System.Windows.Forms.TextFormatFlags]::EndEllipsis -bor [System.Windows.Forms.TextFormatFlags]::NoPrefix
|
||
[System.Windows.Forms.TextRenderer]::DrawText($e.Graphics, $e.SubItem.Text, $list.Font, $e.Bounds, $rowFore, $flags)
|
||
} finally {
|
||
$rowBrush.Dispose(); $textBrush.Dispose(); $borderPen.Dispose()
|
||
}
|
||
})
|
||
# Filtre local : il ne relance jamais l'analyse des lecteurs ou partages.
|
||
$lblFilter = New-Object System.Windows.Forms.Label
|
||
$lblFilter.Text = 'Filtrer la liste :'
|
||
$lblFilter.Location = New-Object System.Drawing.Point(16, 80)
|
||
$lblFilter.Size = New-Object System.Drawing.Size(100, 24)
|
||
$lblFilter.ForeColor = $script:Theme.Text
|
||
$dlg.Controls.Add($lblFilter)
|
||
|
||
$txtFilter = New-Object System.Windows.Forms.TextBox
|
||
$txtFilter.Location = New-Object System.Drawing.Point(120, 78)
|
||
$txtFilter.Size = New-Object System.Drawing.Size(500, 26)
|
||
$txtFilter.Anchor = 'Top,Left,Right'
|
||
$txtFilter.BackColor = $script:Theme.PanelAlt
|
||
$txtFilter.ForeColor = $script:Theme.Text
|
||
$dlg.Controls.Add($txtFilter)
|
||
|
||
$list.Location = New-Object System.Drawing.Point(16, 112)
|
||
$dlg.Controls.Add($list)
|
||
|
||
# Etat partage explicite entre les gestionnaires d'evenements WinForms.
|
||
# En PowerShell, les callbacks peuvent s'executer dans une portee differente :
|
||
# une variable locale $allFound peut alors rester vide dans le filtre.
|
||
$sourceState = [hashtable]::Synchronized(@{ AllFound = @() })
|
||
$renderSourceList = {
|
||
param([string]$Query)
|
||
$previousSelection = $null
|
||
if ($list.SelectedItems.Count -gt 0) {
|
||
$previousSelection = [string]$list.SelectedItems[0].SubItems[3].Text
|
||
}
|
||
|
||
$needle = ([string]$Query).Trim()
|
||
$visibleEntries = New-Object System.Collections.Generic.List[object]
|
||
$entries = @($sourceState.AllFound)
|
||
|
||
foreach ($entry in $entries) {
|
||
if ([string]::IsNullOrWhiteSpace($needle)) {
|
||
[void]$visibleEntries.Add($entry)
|
||
continue
|
||
}
|
||
|
||
$searchable = '{0} {1} {2} {3} {4}' -f `
|
||
[string]$entry.Type, [string]$entry.Nom, [string]$entry.Chemin, `
|
||
[string]$entry.Taille, [string]$entry.Detail
|
||
|
||
if ($searchable.IndexOf($needle, [System.StringComparison]::OrdinalIgnoreCase) -ge 0) {
|
||
[void]$visibleEntries.Add($entry)
|
||
}
|
||
}
|
||
|
||
$list.BeginUpdate()
|
||
try {
|
||
$list.Items.Clear()
|
||
foreach ($entry in $visibleEntries) {
|
||
$item = New-Object System.Windows.Forms.ListViewItem([string]$entry.Type)
|
||
[void]$item.SubItems.Add([string]$entry.Nom)
|
||
[void]$item.SubItems.Add([string]$entry.Taille)
|
||
[void]$item.SubItems.Add([string]$entry.Chemin)
|
||
if ($previousSelection -and ([string]$entry.Chemin -eq $previousSelection)) {
|
||
$item.Selected = $true
|
||
}
|
||
[void]$list.Items.Add($item)
|
||
}
|
||
} finally {
|
||
$list.EndUpdate()
|
||
}
|
||
|
||
if ($entries.Count -gt 0) {
|
||
$lblStatus.Text = ('{0} résultat(s) affiché(s) sur {1}. Filtre instantané ; aucun fichier modifié.' -f $list.Items.Count, $entries.Count)
|
||
} elseif ([string]::IsNullOrWhiteSpace($needle)) {
|
||
$lblStatus.Text = 'Aucune source ISO/WIM/ESD ou installation extraite detectee dans les chemins accessibles.'
|
||
} else {
|
||
$lblStatus.Text = ('Aucun resultat pour « {0} ». Efface le filtre pour revoir la liste.' -f $needle)
|
||
}
|
||
}
|
||
$txtFilter.Add_TextChanged({ & $renderSourceList $txtFilter.Text })
|
||
|
||
$lblStatus = New-Object System.Windows.Forms.Label
|
||
$lblStatus.Text = 'Analyse en lecture seule du lecteur de DeployCenter et/ou du partage SMB. Plusieurs chemins peuvent etre separes par un point-virgule.'
|
||
$lblStatus.Location = New-Object System.Drawing.Point(16, 515)
|
||
$lblStatus.Size = New-Object System.Drawing.Size(770, 36)
|
||
$lblStatus.Anchor = 'Bottom,Left,Right'
|
||
$lblStatus.AutoSize = $false
|
||
$lblStatus.ForeColor = $script:Theme.Secondary
|
||
$dlg.Controls.Add($lblStatus)
|
||
|
||
$progressAnalysis = New-Object System.Windows.Forms.ProgressBar
|
||
$progressAnalysis.Name = 'progressWindowsSourceAnalysis'
|
||
$progressAnalysis.Style = [System.Windows.Forms.ProgressBarStyle]::Marquee
|
||
$progressAnalysis.MarqueeAnimationSpeed = 30
|
||
$progressAnalysis.Visible = $false
|
||
$progressAnalysis.Anchor = 'Bottom,Right'
|
||
$dlg.Controls.Add($progressAnalysis)
|
||
|
||
# Recalculer les positions depuis la taille réelle de la fenêtre :
|
||
# le tableau occupe l'espace restant et le statut reste toujours visible en bas.
|
||
$resizeLayout = {
|
||
$clientWidth = $dlg.ClientSize.Width
|
||
$clientHeight = $dlg.ClientSize.Height
|
||
$rightMargin = 16
|
||
$gap = 12
|
||
$btnWidth = 88
|
||
$editionsWidth = 148
|
||
$left = 12
|
||
$right = [Math]::Max($left + $btnWidth, $clientWidth - $rightMargin)
|
||
$btnEditionsLeft = [Math]::Max($left, $right - $editionsWidth)
|
||
$btnScanLeft = [Math]::Max($left, $btnEditionsLeft - $gap - $btnWidth)
|
||
$txtPath.Width = [Math]::Max(100, $btnScanLeft - $left - $gap)
|
||
$btnEditions.Location = New-Object System.Drawing.Point($btnEditionsLeft, 40)
|
||
$btnEditions.Width = [Math]::Max(120, $right - $btnEditionsLeft)
|
||
$btnScan.Location = New-Object System.Drawing.Point($btnScanLeft, 40)
|
||
$btnScan.Width = [Math]::Max(80, $btnEditionsLeft - $gap - $btnScanLeft)
|
||
$btnScan.Anchor = 'Top,Right'
|
||
$btnEditions.Anchor = 'Top,Right'
|
||
$txtPath.Anchor = 'Top,Left,Right'
|
||
$lblFilter.Location = New-Object System.Drawing.Point(16, 80)
|
||
$txtFilter.Location = New-Object System.Drawing.Point(120, 78)
|
||
$txtFilter.Size = New-Object System.Drawing.Size([Math]::Max(180, $clientWidth - 152), 26)
|
||
$list.Location = New-Object System.Drawing.Point(16, 112)
|
||
$list.Size = New-Object System.Drawing.Size([Math]::Max(300, $clientWidth - 32), [Math]::Max(120, $clientHeight - 205))
|
||
$list.Anchor = 'Top,Bottom,Left,Right'
|
||
$lblStatus.Location = New-Object System.Drawing.Point(16, ($clientHeight - 52))
|
||
$lblStatus.Size = New-Object System.Drawing.Size([Math]::Max(150, $clientWidth - 164), 24)
|
||
$lblStatus.Anchor = 'Bottom,Left,Right'
|
||
$progressAnalysis.Location = New-Object System.Drawing.Point(($clientWidth - 136), ($clientHeight - 52))
|
||
$progressAnalysis.Size = New-Object System.Drawing.Size(120, 20)
|
||
}
|
||
$dlg.Add_Shown({
|
||
& $resizeLayout
|
||
# Lancer automatiquement la première analyse à l'ouverture.
|
||
# Le bouton Rechercher reste disponible si l'utilisateur change les chemins.
|
||
$btnScan.PerformClick()
|
||
})
|
||
$dlg.Add_SizeChanged({ & $resizeLayout })
|
||
|
||
$btnEditions.Add_Click({
|
||
if ($list.SelectedItems.Count -eq 0) {
|
||
Show-DeployCenterMessage -Message 'Sélectionne d''abord une source dans la liste.' -Title 'Éditions Windows' -Icon Information -Owner $dlg -Theme $script:Theme -Font $script:FontRegular
|
||
return
|
||
}
|
||
|
||
$selectedPath = [string]$list.SelectedItems[0].SubItems[3].Text
|
||
$selectedName = [string]$list.SelectedItems[0].SubItems[1].Text
|
||
$resolvedImage = $null
|
||
$mountTransferred = $false
|
||
$btnEditions.Enabled = $false
|
||
$btnScan.Enabled = $false
|
||
$dlg.Cursor = [System.Windows.Forms.Cursors]::WaitCursor
|
||
$lblStatus.Text = "Analyse des editions de $selectedName en cours..."
|
||
$progressAnalysis.Visible = $true
|
||
$progressAnalysis.BringToFront()
|
||
$dlg.Refresh()
|
||
try {
|
||
$resolvedImage = Resolve-InstallImagePath -SelectedPath $selectedPath -ExistingImage $script:SelectedWindowsEdition
|
||
$imagePath = [string]$resolvedImage.ImagePath
|
||
$editionResult = Get-WindowsImageEditions -ImagePath $imagePath -LogAction $script:SourceLogAction
|
||
$editions = @($editionResult.Editions)
|
||
$globalImageVersion = [string]$editionResult.GlobalVersion
|
||
$lines = foreach ($edition in $editions) {
|
||
$index = if ($edition.ImageIndex) { $edition.ImageIndex } elseif ($edition.Index) { $edition.Index } else { '?' }
|
||
$name = if ($edition.ImageName) { $edition.ImageName } elseif ($edition.Name) { $edition.Name } else { 'Nom non disponible' }
|
||
$arch = if ($edition.Architecture) { [string]$edition.Architecture } else { 'Architecture non disponible' }
|
||
$version = if ($edition.Version) { [string]$edition.Version } else { 'Version non disponible' }
|
||
"Index : $index`r`nNom : $name`r`nArchitecture : $arch`r`nVersion : $version"
|
||
}
|
||
# Le formulaire enfant est modal : actualiser le statut avant son affichage,
|
||
# sinon le formulaire parent reste visuellement sur « analyse en cours ».
|
||
$lblStatus.Text = "$($editions.Count) édition(s) détectée(s) dans $selectedName. Sélectionne une édition."
|
||
$dlg.Refresh()
|
||
|
||
# Tableau des editions ; l'index DISM selectionne est conserve pour la suite.
|
||
$resultForm = New-Object System.Windows.Forms.Form
|
||
$resultForm.Text = 'Éditions Windows disponibles'
|
||
$resultForm.StartPosition = 'CenterParent'
|
||
$resultForm.Size = New-Object System.Drawing.Size(700, 480)
|
||
$resultForm.MinimumSize = New-Object System.Drawing.Size(520, 320)
|
||
Set-DeployCenterFormSizing -Form $resultForm
|
||
$resultForm.ShowInTaskbar = $false
|
||
$resultForm.BackColor = $script:Theme.Background
|
||
$resultForm.ForeColor = $script:Theme.Text
|
||
|
||
$sourceLabel = New-Object System.Windows.Forms.Label
|
||
$sourceLabel.Text = "Source : $selectedPath"
|
||
$sourceLabel.Dock = [System.Windows.Forms.DockStyle]::Top
|
||
$sourceLabel.Height = 38
|
||
$sourceLabel.Padding = New-Object System.Windows.Forms.Padding(10, 8, 10, 4)
|
||
$sourceLabel.AutoEllipsis = $true
|
||
$sourceLabel.BackColor = $script:Theme.Background
|
||
$sourceLabel.ForeColor = $script:Theme.Text
|
||
|
||
$editionList = New-Object System.Windows.Forms.ListView
|
||
$editionList.View = [System.Windows.Forms.View]::Details
|
||
$editionList.FullRowSelect = $true
|
||
$editionList.GridLines = $true
|
||
$editionList.MultiSelect = $false
|
||
$editionList.HideSelection = $false
|
||
# Une seule édition peut être sélectionnée à la fois.
|
||
$editionList.Sorting = [System.Windows.Forms.SortOrder]::None
|
||
$editionList.Dock = [System.Windows.Forms.DockStyle]::Fill
|
||
$editionList.BackColor = $script:Theme.Panel
|
||
$editionList.ForeColor = $script:Theme.Text
|
||
[void]$editionList.Columns.Add('Index', 65)
|
||
[void]$editionList.Columns.Add('Édition', 260)
|
||
[void]$editionList.Columns.Add('Architecture', 100)
|
||
[void]$editionList.Columns.Add('Version', 105)
|
||
|
||
# Édition est la colonne prioritaire : Version conserve une largeur fixe.
|
||
$resizeEditionColumns = {
|
||
if ($editionList.Columns.Count -ge 4) {
|
||
$availableWidth = $editionList.ClientSize.Width - $editionList.Columns[0].Width - $editionList.Columns[2].Width - $editionList.Columns[3].Width - 4
|
||
if ($editionList.Items.Count -gt 0 -and $editionList.Items.Count -gt [Math]::Floor($editionList.ClientSize.Height / 20)) {
|
||
$availableWidth -= [System.Windows.Forms.SystemInformation]::VerticalScrollBarWidth
|
||
}
|
||
$editionList.Columns[1].Width = [Math]::Max(220, $availableWidth)
|
||
}
|
||
}
|
||
$editionList.Add_SizeChanged($resizeEditionColumns)
|
||
$resultForm.Add_Shown($resizeEditionColumns)
|
||
|
||
# Dessin personnalise des en-tetes et cellules pour que ListView
|
||
# respecte le theme Light/Dark au lieu de garder un en-tete blanc.
|
||
$editionList.OwnerDraw = $true
|
||
$editionList.Add_DrawColumnHeader({
|
||
param($sender, $e)
|
||
$headerColor = if ($script:Theme.Contains('TableHeader')) { $script:Theme.TableHeader } else { $script:Theme.PanelAlt }
|
||
$headerBrush = New-Object System.Drawing.SolidBrush($headerColor)
|
||
$headerPen = New-Object System.Drawing.Pen($script:Theme.Border)
|
||
try {
|
||
$e.Graphics.FillRectangle($headerBrush, $e.Bounds)
|
||
$e.Graphics.DrawRectangle($headerPen, $e.Bounds.X, $e.Bounds.Y, $e.Bounds.Width - 1, $e.Bounds.Height - 1)
|
||
[System.Windows.Forms.TextRenderer]::DrawText(
|
||
$e.Graphics, $e.Header.Text, $sender.Font, $e.Bounds,
|
||
$script:Theme.Text,
|
||
([System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor
|
||
[System.Windows.Forms.TextFormatFlags]::Left -bor
|
||
[System.Windows.Forms.TextFormatFlags]::EndEllipsis)
|
||
)
|
||
} finally {
|
||
$headerBrush.Dispose()
|
||
$headerPen.Dispose()
|
||
}
|
||
})
|
||
$editionList.Add_DrawItem({ param($sender, $e) })
|
||
$editionList.Add_DrawSubItem({
|
||
param($sender, $e)
|
||
$cellBack = if (($e.Item.Index % 2) -eq 0) { $script:Theme.TableRowEven } else { $script:Theme.TableRowOdd }
|
||
$cellFore = $script:Theme.Text
|
||
if ($e.Item.Selected) {
|
||
$cellBack = $script:Theme.Accent
|
||
$cellFore = [System.Drawing.Color]::White
|
||
}
|
||
$cellBrush = New-Object System.Drawing.SolidBrush($cellBack)
|
||
$cellPen = New-Object System.Drawing.Pen($script:Theme.Border)
|
||
try {
|
||
$e.Graphics.FillRectangle($cellBrush, $e.Bounds)
|
||
if ($sender.GridLines) {
|
||
$e.Graphics.DrawRectangle($cellPen, $e.Bounds.X, $e.Bounds.Y, $e.Bounds.Width - 1, $e.Bounds.Height - 1)
|
||
}
|
||
[System.Windows.Forms.TextRenderer]::DrawText(
|
||
$e.Graphics, $e.SubItem.Text, $sender.Font, $e.Bounds,
|
||
$cellFore,
|
||
([System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor
|
||
[System.Windows.Forms.TextFormatFlags]::Left -bor
|
||
[System.Windows.Forms.TextFormatFlags]::EndEllipsis)
|
||
)
|
||
} finally {
|
||
$cellBrush.Dispose()
|
||
$cellPen.Dispose()
|
||
}
|
||
})
|
||
|
||
foreach ($edition in $editions) {
|
||
$index = if ($edition.ImageIndex) { [string]$edition.ImageIndex } elseif ($edition.Index) { [string]$edition.Index } else { '?' }
|
||
$name = if ($edition.ImageName) { [string]$edition.ImageName } elseif ($edition.Name) { [string]$edition.Name } elseif ($edition.ImageDescription) { [string]$edition.ImageDescription } else { 'Nom non disponible' }
|
||
$archValue = $null
|
||
foreach ($propertyName in @('Architecture', 'ImageArchitecture')) {
|
||
if ($edition.PSObject.Properties[$propertyName] -and $edition.$propertyName) {
|
||
$archValue = $edition.$propertyName
|
||
break
|
||
}
|
||
}
|
||
$arch = if ($null -ne $archValue) {
|
||
switch ([string]$archValue) {
|
||
'0' { 'x86' }
|
||
'5' { 'ARM' }
|
||
'9' { 'x64' }
|
||
'12' { 'ARM64' }
|
||
default { [string]$archValue }
|
||
}
|
||
} else { 'Non disponible' }
|
||
$version = if ($edition.Version) { [string]$edition.Version } else { 'Non disponible' }
|
||
|
||
$row = New-Object System.Windows.Forms.ListViewItem($index)
|
||
[void]$row.SubItems.Add($name)
|
||
[void]$row.SubItems.Add($arch)
|
||
[void]$row.SubItems.Add($version)
|
||
$row.Tag = $edition
|
||
[void]$editionList.Items.Add($row)
|
||
}
|
||
|
||
$buttonPanel = New-Object System.Windows.Forms.Panel
|
||
$buttonPanel.Dock = [System.Windows.Forms.DockStyle]::Bottom
|
||
$buttonPanel.Height = 52
|
||
$buttonPanel.BackColor = $script:Theme.Background
|
||
|
||
$cancelButton = New-Object System.Windows.Forms.Button
|
||
$cancelButton.Text = 'Annuler'
|
||
$cancelButton.Size = New-Object System.Drawing.Size(100, 30)
|
||
$cancelButton.Anchor = 'Right,Top'
|
||
$cancelButton.Location = New-Object System.Drawing.Point(0, 10)
|
||
$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
|
||
|
||
$validateButton = New-Object System.Windows.Forms.Button
|
||
$validateButton.Text = 'Valider l''édition'
|
||
$validateButton.Size = New-Object System.Drawing.Size(140, 30)
|
||
$validateButton.Anchor = 'Right,Top'
|
||
$validateButton.Location = New-Object System.Drawing.Point(0, 10)
|
||
$validateButton.Enabled = $false
|
||
|
||
$editionList.Add_SelectedIndexChanged({
|
||
$validateButton.Enabled = ($editionList.SelectedItems.Count -gt 0 -and $editionList.SelectedItems[0].SubItems[0].Text -ne '?')
|
||
})
|
||
$validateButton.Add_Click({
|
||
if ($editionList.SelectedItems.Count -gt 0) {
|
||
$resultForm.Tag = [pscustomobject]@{
|
||
SourcePath = $selectedPath
|
||
ImagePath = $imagePath
|
||
MountedImage = $resolvedImage.MountedImage
|
||
Edition = $editionList.SelectedItems[0].Tag
|
||
Index = [int]$editionList.SelectedItems[0].SubItems[0].Text
|
||
Name = $editionList.SelectedItems[0].SubItems[1].Text
|
||
}
|
||
$resultForm.DialogResult = [System.Windows.Forms.DialogResult]::OK
|
||
$resultForm.Close()
|
||
}
|
||
})
|
||
$editionList.Add_DoubleClick({
|
||
if ($editionList.SelectedItems.Count -gt 0 -and $validateButton.Enabled) {
|
||
$validateButton.PerformClick()
|
||
}
|
||
})
|
||
$buttonPanel.Controls.Add($cancelButton)
|
||
$buttonPanel.Controls.Add($validateButton)
|
||
$buttonPanel.Add_Resize({
|
||
$validateButton.Location = New-Object System.Drawing.Point(($buttonPanel.ClientSize.Width - $validateButton.Width - 12), 10)
|
||
$cancelButton.Location = New-Object System.Drawing.Point(($validateButton.Left - $cancelButton.Width - 8), 10)
|
||
})
|
||
|
||
$resultForm.Controls.Add($editionList)
|
||
$resultForm.Controls.Add($buttonPanel)
|
||
$resultForm.Controls.Add($sourceLabel)
|
||
$resultForm.AcceptButton = $validateButton
|
||
$resultForm.CancelButton = $cancelButton
|
||
Add-SessionFooter -TargetForm $resultForm -Theme $script:Theme -Font $script:FontSmall `
|
||
-IPv4 $script:DeployIPv4 -VncPassword $script:VncPassword -ShowFooter $false
|
||
$dialogResult = $resultForm.ShowDialog($dlg)
|
||
$chosenEdition = $resultForm.Tag
|
||
$resultForm.Dispose()
|
||
|
||
if ($dialogResult -eq [System.Windows.Forms.DialogResult]::OK -and $chosenEdition) {
|
||
if ($script:SelectedWindowsEdition -and
|
||
-not [string]::Equals([string]$script:SelectedWindowsEdition.SourcePath, [string]$chosenEdition.SourcePath, [StringComparison]::OrdinalIgnoreCase)) {
|
||
[void](Dismount-DeployCenterInstallImage -Image $script:SelectedWindowsEdition)
|
||
}
|
||
$script:SelectedWindowsEdition = $chosenEdition
|
||
$mountTransferred = $true
|
||
$lblStatus.Text = "Édition sélectionnée : $($chosenEdition.Name) (index $($chosenEdition.Index))."
|
||
& $script:SourceLogAction "Edition selectionnee : $($chosenEdition.Name), index $($chosenEdition.Index), image $imagePath" 'SUCCESS'
|
||
$dlg.DialogResult = [System.Windows.Forms.DialogResult]::OK
|
||
$dlg.Close()
|
||
} else {
|
||
$lblStatus.Text = "$($editions.Count) édition(s) trouvée(s) dans $selectedName. Aucune nouvelle édition sélectionnée."
|
||
}
|
||
& $script:SourceLogAction "Analyse des editions terminee : $imagePath ($($editions.Count) edition(s))." 'SUCCESS'
|
||
} catch {
|
||
$lblStatus.Text = "Echec de l'analyse des editions de $selectedName."
|
||
& $script:SourceLogAction "Erreur analyse editions $selectedPath : $($_.Exception.Message)" 'ERROR'
|
||
Show-DeployCenterMessage -Message $_.Exception.Message -Title 'Analyse des éditions' -Icon Warning -Owner $dlg -Theme $script:Theme -Font $script:FontRegular
|
||
} finally {
|
||
if ($resolvedImage -and $resolvedImage.MountedImage -and -not $mountTransferred -and
|
||
(-not $script:SelectedWindowsEdition -or $resolvedImage.MountedImage -ne $script:SelectedWindowsEdition.MountedImage)) {
|
||
try { [void](Dismount-DeployCenterInstallImage -Image $resolvedImage) } catch {
|
||
& $script:SourceLogAction "Impossible de démonter l'ISO après l'analyse : $($_.Exception.Message)" 'WARNING'
|
||
}
|
||
}
|
||
$dlg.Cursor = [System.Windows.Forms.Cursors]::Default
|
||
$progressAnalysis.Visible = $false
|
||
$btnEditions.Enabled = $true
|
||
$btnScan.Enabled = $true
|
||
}
|
||
})
|
||
|
||
$list.Add_DoubleClick({
|
||
if ($list.SelectedItems.Count -gt 0 -and $btnEditions.Enabled) {
|
||
$btnEditions.PerformClick()
|
||
}
|
||
})
|
||
|
||
$btnScan.Add_Click({
|
||
$btnScan.Enabled = $false
|
||
$dlg.Cursor = [System.Windows.Forms.Cursors]::WaitCursor
|
||
$lblStatus.Text = 'Recherche en cours sur les chemins indiques...'
|
||
$sourceState.AllFound = @()
|
||
$list.Items.Clear()
|
||
try {
|
||
# La recherche ne modifie jamais DeployCenter.ini.
|
||
$sourceState.AllFound = @(Find-WindowsSources -RootPath $txtPath.Text -LogAction $script:SourceLogAction)
|
||
& $renderSourceList $txtFilter.Text
|
||
if (@($sourceState.AllFound).Count -eq 0) {
|
||
$lblStatus.Text = 'Aucune source ISO/WIM/ESD ou installation extraite detectee dans les chemins accessibles.'
|
||
& $script:SourceLogAction 'Aucune source Windows detectee dans les chemins accessibles.' 'WARNING'
|
||
}
|
||
} catch {
|
||
$lblStatus.Text = 'Echec de la recherche. Consulte le message.'
|
||
& $script:SourceLogAction "Erreur detection sources : $($_.Exception.Message)" 'ERROR'
|
||
Show-DeployCenterMessage -Message $_.Exception.Message -Title 'Détection des sources' -Icon Warning -Owner $dlg -Theme $script:Theme -Font $script:FontRegular
|
||
} finally {
|
||
$dlg.Cursor = [System.Windows.Forms.Cursors]::Default
|
||
$btnScan.Enabled = $true
|
||
}
|
||
})
|
||
|
||
Add-SessionFooter -TargetForm $dlg -Theme $script:Theme -Font $script:FontSmall `
|
||
-IPv4 $script:DeployIPv4 -VncPassword $script:VncPassword
|
||
[void]$dlg.ShowDialog($script:form)
|
||
$dlg.Dispose()
|
||
}
|
||
|
||
function Update-HardwareView {
|
||
$script:btnRefresh.Enabled = $false
|
||
$script:form.Cursor = [System.Windows.Forms.Cursors]::WaitCursor
|
||
|
||
try {
|
||
if (-not (Get-Command Get-HardwareInfo -ErrorAction SilentlyContinue)) {
|
||
throw 'Le module HardwareInventory ne fournit pas Get-HardwareInfo.'
|
||
}
|
||
$info = Get-HardwareInfo
|
||
|
||
$script:lblManufacturer.Text = "Fabricant : $($info.Manufacturer)"
|
||
$script:lblModel.Text = "Modèle : $($info.Model)"
|
||
$script:lblSerial.Text = "Numéro de série : $($info.SerialNumber)"
|
||
$script:lblFirmware.Text = "Firmware : $($info.Firmware)"
|
||
$script:lblArchitecture.Text = "Architecture : $($info.Architecture)"
|
||
|
||
$script:HardwareInventory = $info
|
||
$previousDiskIndex = $null
|
||
if ($null -ne $script:cmbDisk.SelectedItem -and $null -ne $script:cmbDisk.SelectedItem.Tag) {
|
||
$previousDiskIndex = [string]$script:cmbDisk.SelectedItem.Tag
|
||
}
|
||
$script:RefreshingDiskList = $true
|
||
$script:cmbDisk.BeginUpdate()
|
||
try {
|
||
$script:cmbDisk.Items.Clear()
|
||
foreach ($disk in $info.Disks) {
|
||
$diskLabel = "Disque {0} - {1} - {2:N1} Go - {3} - {4}" -f $disk.Index, $disk.Model, $disk.SizeGB, $disk.BusType, $disk.Status
|
||
$diskChoice = [pscustomobject]@{ Text = $diskLabel; Tag = [string]$disk.Index }
|
||
[void]$script:cmbDisk.Items.Add($diskChoice)
|
||
}
|
||
$script:cmbDisk.DisplayMember = 'Text'
|
||
if ($script:cmbDisk.Items.Count -gt 0) {
|
||
$selectedIndex = -1
|
||
if ($null -ne $previousDiskIndex) {
|
||
for ($i = 0; $i -lt $script:cmbDisk.Items.Count; $i++) {
|
||
if ([string]$script:cmbDisk.Items[$i].Tag -eq $previousDiskIndex) { $selectedIndex = $i; break }
|
||
}
|
||
}
|
||
if ($selectedIndex -lt 0 -and $script:cmbDisk.Items.Count -eq 1) { $selectedIndex = 0 }
|
||
$script:cmbDisk.SelectedIndex = $selectedIndex
|
||
}
|
||
}
|
||
finally {
|
||
$script:cmbDisk.EndUpdate()
|
||
$script:RefreshingDiskList = $false
|
||
}
|
||
$script:SelectedDiskIndex = if ($script:cmbDisk.SelectedIndex -ge 0) { [string]$script:cmbDisk.SelectedItem.Tag } else { $null }
|
||
|
||
Write-DeployInventory -InventoryDir $script:InventoryDir -InventoryFile $script:InventoryFile -HardwareInfo $info -DeploymentIPv4 $script:DeployIPv4 -VncPassword $script:VncPassword -LogAction $script:SourceLogAction
|
||
|
||
& $script:SourceLogAction "Inventaire materiel actualise." "SUCCESS"
|
||
|
||
foreach ($errorMessage in $info.Errors) {
|
||
& $script:SourceLogAction $errorMessage "WARNING"
|
||
}
|
||
|
||
if ($info.Disks.Count -eq 0) {
|
||
& $script:SourceLogAction "Aucun disque physique detecte." "WARNING"
|
||
}
|
||
}
|
||
catch {
|
||
& $script:SourceLogAction "Erreur inventaire : $($_.Exception.Message)" "ERROR"
|
||
|
||
Show-DeployCenterMessage -Message $_.Exception.Message -Title 'Erreur DeployCenter' -Icon Error -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
}
|
||
finally {
|
||
$script:btnRefresh.Enabled = $true
|
||
$script:form.Cursor = [System.Windows.Forms.Cursors]::Default
|
||
}
|
||
}
|
||
|
||
function Get-PartitionProfileSizingSelection {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Profile,
|
||
[Parameter(Mandatory=$true)]$DiskInfo,
|
||
[System.Collections.IDictionary]$InitialValues = @{}
|
||
)
|
||
|
||
$capacity = Get-DeployCenterPartitionSizingCapacity -Profile $Profile -DiskSizeBytes ([long]$DiskInfo.SizeBytes)
|
||
return Show-DeployCenterPartitionSizingDialog `
|
||
-Profile $Profile `
|
||
-AvailableGB $capacity.UsableGB `
|
||
-Theme $script:Theme `
|
||
-Font $script:FontRegular `
|
||
-Owner $script:form `
|
||
-InitialValues $InitialValues
|
||
}
|
||
|
||
function Set-PartitionProfileSizingSelection {
|
||
param(
|
||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Profile,
|
||
[Parameter(Mandatory=$true)]$DiskInfo,
|
||
[System.Collections.IDictionary]$InitialValues = @{}
|
||
)
|
||
|
||
$selection = Get-PartitionProfileSizingSelection -Profile $Profile -DiskInfo $DiskInfo -InitialValues $InitialValues
|
||
if ($null -eq $selection) { return $false }
|
||
$script:SelectedPartitionSizing = New-DeployCenterPartitionSizingState -Profile $Profile -DiskInfo $DiskInfo -Selection $selection
|
||
return $true
|
||
}
|
||
|
||
function Update-DeployCenterLayout {
|
||
if ($null -eq $script:form -or $script:form.IsDisposed) { return }
|
||
$w = $script:form.ClientSize.Width
|
||
$h = $script:form.ClientSize.Height
|
||
$m = 24
|
||
$contentWidth = [Math]::Max(300, $w - (2 * $m))
|
||
|
||
# En-tete : le selecteur de theme reste accroche au bord droit.
|
||
if ($null -ne $script:cmbTheme) {
|
||
$script:cmbTheme.Location = New-Object System.Drawing.Point([Math]::Max($m, $w - $m - $script:cmbTheme.Width), 25)
|
||
}
|
||
|
||
# Les deux panneaux superieurs conservent leur hauteur, mais s'etirent en largeur.
|
||
$script:groupPC.Location = New-Object System.Drawing.Point($m, 100)
|
||
$script:groupPC.Size = New-Object System.Drawing.Size($contentWidth, 90)
|
||
$script:groupDisks.Location = New-Object System.Drawing.Point($m, 205)
|
||
$script:groupDisks.Size = New-Object System.Drawing.Size($contentWidth, 270)
|
||
Set-DiskSelectorWidth
|
||
|
||
$footerHeight = 26
|
||
$buttonHeightLocal = 38
|
||
$buttonYLocal = $h - $footerHeight - 14 - $buttonHeightLocal
|
||
|
||
$buttonWidthLocal = 140
|
||
$buttonGapLocal = 12
|
||
$script:btnClose.Size = New-Object System.Drawing.Size($buttonWidthLocal, $buttonHeightLocal)
|
||
$script:btnRefresh.Size = New-Object System.Drawing.Size($buttonWidthLocal, $buttonHeightLocal)
|
||
$script:btnDeploy.Size = New-Object System.Drawing.Size($buttonWidthLocal, $buttonHeightLocal)
|
||
$script:btnLog.Size = New-Object System.Drawing.Size($buttonWidthLocal, $buttonHeightLocal)
|
||
$script:btnClose.Location = New-Object System.Drawing.Point([Math]::Max($m, $w - $m - $buttonWidthLocal), $buttonYLocal)
|
||
$script:btnDeploy.Location = New-Object System.Drawing.Point([Math]::Max($m, $script:btnClose.Left - $buttonGapLocal - $buttonWidthLocal), $buttonYLocal)
|
||
$script:btnRefresh.Location = New-Object System.Drawing.Point([Math]::Max($m, $script:btnDeploy.Left - $buttonGapLocal - $buttonWidthLocal), $buttonYLocal)
|
||
$script:btnLog.Location = New-Object System.Drawing.Point($m, $buttonYLocal)
|
||
Set-DiskSelectorWidth
|
||
}
|