If anyone is interested, replace the below from line 8129 (in AppDeployToolkitMain.ps1, v3.8.4) and update the MediaTimeline source with your GIF or video.
## Check if the progress thread is running before invoking methods on it
If ($script:ProgressSyncHash.Window.Dispatcher.Thread.ThreadState -ne 'Running') {
# Notify user that the software installation has started
$balloonText = "$deploymentTypeName $configBalloonTextStart"
Show-BalloonTip -BalloonTipIcon 'Info' -BalloonTipText $balloonText
# Create a synchronized hashtable to share objects between runspaces
$script:ProgressSyncHash = [hashtable]::Synchronized(@{ })
# Create a new runspace for the progress bar
$script:ProgressRunspace = [runspacefactory]::CreateRunspace()
$script:ProgressRunspace.ApartmentState = 'STA'
$script:ProgressRunspace.ThreadOptions = 'ReuseThread'
$script:ProgressRunspace.Open()
# Add the sync hash to the runspace
$script:ProgressRunspace.SessionStateProxy.SetVariable('progressSyncHash', $script:ProgressSyncHash)
# Add other variables from the parent thread required in the progress runspace
$script:ProgressRunspace.SessionStateProxy.SetVariable('installTitle', $installTitle)
$script:ProgressRunspace.SessionStateProxy.SetVariable('windowLocation', $windowLocation)
$script:ProgressRunspace.SessionStateProxy.SetVariable('topMost', $topMost.ToString())
$script:ProgressRunspace.SessionStateProxy.SetVariable('appDeployLogoBanner', $appDeployLogoBanner)
$script:ProgressRunspace.SessionStateProxy.SetVariable('ProgressStatusMessage', $statusMessage)
$script:ProgressRunspace.SessionStateProxy.SetVariable('AppDeployLogoIcon', $AppDeployLogoIcon)
# Add the script block to be executed in the progress runspace
$progressCmd = [PowerShell]::Create().AddScript({
[string]$xamlProgressString = @'
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window" Title="Microsoft Office 365" Height="720" Width="1280" MinHeight="750" MinWidth="1280" WindowStartupLocation = "Manual" Topmost="True" ResizeMode="NoResize" Icon="" ShowInTaskbar="True">
<Grid>
<MediaElement Name="picture">
<MediaElement.Triggers>
<EventTrigger RoutedEvent="MediaElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<MediaTimeline Source="file://c:\users\public\test2.mp4"
Storyboard.TargetName="picture"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</MediaElement.Triggers>
</MediaElement>
</Grid>
</Window>
'@
[Xml.XmlDocument]$xamlProgress = New-Object 'System.Xml.XmlDocument'
$xamlProgress.LoadXml($xamlProgressString)
## Set the configurable values using variables added to the runspace from the parent thread
$xamlProgress.Window.TopMost = $topMost
$xamlProgress.Window.Icon = $AppDeployLogoIcon
$xamlProgress.Window.Grid.Image.Source = $appDeployLogoBanner
$xamlProgress.Window.Title = $installTitle
# Parse the XAML
$progressReader = New-Object -TypeName 'System.Xml.XmlNodeReader' -ArgumentList $xamlProgress
$script:ProgressSyncHash.Window = [Windows.Markup.XamlReader]::Load($progressReader)
# Grey out the X button
$script:ProgressSyncHash.Window.add_Loaded({
# Calculate the position on the screen where the progress dialog should be placed
[int32]$screenWidth = [System.Windows.SystemParameters]::WorkArea.Width
[int32]$screenHeight = [System.Windows.SystemParameters]::WorkArea.Height
[int32]$screenCenterWidth = $screenWidth - $script:ProgressSyncHash.Window.ActualWidth
[int32]$screenCenterHeight = $screenHeight - $script:ProgressSyncHash.Window.ActualHeight
# Set the start position of the Window based on the screen size
If ($windowLocation -eq 'BottomRight') {
# Put the window in the corner
$script:ProgressSyncHash.Window.Left = [Double]($screenCenterWidth)
$script:ProgressSyncHash.Window.Top = [Double]($screenCenterHeight)
}
ElseIf($windowLocation -eq 'TopCenter'){
$script:ProgressSyncHash.Window.Left = [Double]($screenCenterWidth / 2)
$script:ProgressSyncHash.Window.Top = [Double]($screenCenterHeight / 6)
}
Else {
# Center the progress window by calculating the center of the workable screen based on the width of the screen minus half the width of the progress bar
$script:ProgressSyncHash.Window.Left = [Double]($screenCenterWidth / 2)
$script:ProgressSyncHash.Window.Top = [Double]($screenCenterHeight / 2)
}
# Grey out the X button
try {
$windowHandle = (New-Object -TypeName System.Windows.Interop.WindowInteropHelper -ArgumentList $this).Handle
If ($windowHandle -and ($windowHandle -ne [IntPtr]::Zero)) {
$menuHandle = [PSADT.UiAutomation]::GetSystemMenu($windowHandle, $false)
If ($menuHandle -and ($menuHandle -ne [IntPtr]::Zero)) {
[PSADT.UiAutomation]::EnableMenuItem($menuHandle, 0xF060, 0x00000001)
[PSADT.UiAutomation]::DestroyMenu($menuHandle)
}
}
}
catch {
# Not a terminating error if we can't grey out the button
Write-Log "Failed to grey out the Close button." -Severity 2 -Source ${CmdletName}
}
})
# Prepare the ProgressText variable so we can use it to change the text in the text area
# Add an action to the Window.Closing event handler to disable the close button
$script:ProgressSyncHash.Window.Add_Closing({ $_.Cancel = $true })
# Allow the window to be dragged by clicking on it anywhere
$script:ProgressSyncHash.Window.Add_MouseLeftButtonDown({ $script:ProgressSyncHash.Window.DragMove() })
# Add a tooltip
$script:ProgressSyncHash.Window.ToolTip = $installTitle
$null = $script:ProgressSyncHash.Window.ShowDialog()
$script:ProgressSyncHash.Error = $Error
})
$progressCmd.Runspace = $script:ProgressRunspace
# Invoke the progress runspace
$null = $progressCmd.BeginInvoke()
# Allow the thread to be spun up safely before invoking actions against it.
Start-Sleep -Seconds 1
If ($script:ProgressSyncHash.Error) {
Write-Log -Message "Failure while displaying progress dialog. `n$(Resolve-Error -ErrorRecord $script:ProgressSyncHash.Error)" -Severity 3 -Source ${CmdletName}
}
}
}
End {
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer
}
}
#endregion
#region Function Close-InstallationProgress
Function Close-InstallationProgress {
<#
.SYNOPSIS
Closes the dialog created by Show-InstallationProgress.
.DESCRIPTION
Closes the dialog created by Show-InstallationProgress.
This function is called by the Exit-Script function to close a running instance of the progress dialog if found.
.EXAMPLE
Close-InstallationProgress
.NOTES
This is an internal script function and should typically not be called directly.
.LINK
http://psappdeploytoolkit.com
#>
[CmdletBinding()]
Param (
)
Begin {
## Get the name of this function and write header
[string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -CmdletBoundParameters $PSBoundParameters -Header
}
Process {
If ($script:ProgressSyncHash.Window.Dispatcher.Thread.ThreadState -eq 'Running') {
## Close the progress thread
Write-Log -Message 'Close the installation progress dialog.' -Source ${CmdletName}
$script:ProgressSyncHash.Window.Dispatcher.InvokeShutdown()
$script:ProgressSyncHash.Clear()
$script:ProgressRunspace.Close()
}
}
End {
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer
}
}
#endregion
It could still use a bit of cleaning up but it works.