168 lines
7.3 KiB
PowerShell
168 lines
7.3 KiB
PowerShell
#Requires -Version 5.1
|
|
<#
|
|
.SYNOPSIS
|
|
Shows a WPF notification popup for the OBS Replay Buffer tool.
|
|
Must be launched via Start-Process with powershell.exe -STA.
|
|
|
|
.PARAMETER Type
|
|
'BufferStarted' — shown at logon when the replay buffer is active.
|
|
'ReplaySaved' — shown after a successful replay save.
|
|
#>
|
|
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[ValidateSet('BufferStarted', 'ReplaySaved')]
|
|
[string]$Type,
|
|
|
|
[string]$ContactNumber = '',
|
|
[int]$BufferMinutes = 0,
|
|
[string]$FileName = '',
|
|
[double]$FileSizeMB = 0
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
Add-Type -AssemblyName PresentationFramework
|
|
Add-Type -AssemblyName WindowsBase
|
|
Add-Type -AssemblyName System.Drawing
|
|
|
|
Add-Type -TypeDefinition @"
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
public class GdiHelper {
|
|
[DllImport("gdi32.dll")]
|
|
public static extern bool DeleteObject(IntPtr hObject);
|
|
}
|
|
"@
|
|
|
|
$hBitmap = [System.Drawing.SystemIcons]::Shield.ToBitmap().GetHbitmap()
|
|
$wpfShield = [System.Windows.Interop.Imaging]::CreateBitmapSourceFromHBitmap(
|
|
$hBitmap, [IntPtr]::Zero, [System.Windows.Int32Rect]::Empty,
|
|
[System.Windows.Media.Imaging.BitmapSizeOptions]::FromEmptyOptions()
|
|
)
|
|
[GdiHelper]::DeleteObject($hBitmap) | Out-Null
|
|
|
|
$hBitmap = [System.Drawing.SystemIcons]::Warning.ToBitmap().GetHbitmap()
|
|
$wpfWarning = [System.Windows.Interop.Imaging]::CreateBitmapSourceFromHBitmap(
|
|
$hBitmap, [IntPtr]::Zero, [System.Windows.Int32Rect]::Empty,
|
|
[System.Windows.Media.Imaging.BitmapSizeOptions]::FromEmptyOptions()
|
|
)
|
|
[GdiHelper]::DeleteObject($hBitmap) | Out-Null
|
|
|
|
if ($Type -eq 'BufferStarted') {
|
|
[xml]$xaml = @"
|
|
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
Title="IT Screen Recorder" SizeToContent="Height" Width="440"
|
|
WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
|
|
Topmost="True" ShowInTaskbar="False">
|
|
<Grid Margin="20">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="*"/>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="Auto"/>
|
|
</Grid.RowDefinitions>
|
|
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,14">
|
|
<Image x:Name="ImgHeader" Width="32" Height="32" Margin="0,0,10,0" VerticalAlignment="Center"/>
|
|
<TextBlock Text="Screen Recording is Active" FontSize="16" FontWeight="SemiBold" FontFamily="Segoe UI" VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
<TextBlock x:Name="TxtBody" Grid.Row="1" TextWrapping="Wrap" FontSize="12" FontFamily="Segoe UI" LineHeight="22"/>
|
|
<Border Grid.Row="2" Background="#F0F0F0" CornerRadius="4" Padding="10,8" Margin="0,12,0,12">
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
|
<Image x:Name="ImgTray" Width="22" Height="22" Margin="0,0,8,0"/>
|
|
<TextBlock Text="Look for this icon in your system tray" FontSize="11" FontFamily="Segoe UI" VerticalAlignment="Center" Foreground="#555"/>
|
|
</StackPanel>
|
|
</Border>
|
|
<TextBlock x:Name="TxtContact" Grid.Row="3" FontSize="11" FontFamily="Segoe UI" Foreground="#555" HorizontalAlignment="Center" Margin="0,0,0,16"/>
|
|
<Button x:Name="BtnOK" Grid.Row="4" Width="100" HorizontalAlignment="Center" IsDefault="True"/>
|
|
</Grid>
|
|
</Window>
|
|
"@
|
|
|
|
$window = [System.Windows.Markup.XamlReader]::Load([System.Xml.XmlNodeReader]::new($xaml))
|
|
$imgHeader = $window.FindName('ImgHeader')
|
|
$imgTray = $window.FindName('ImgTray')
|
|
$txtBody = $window.FindName('TxtBody')
|
|
$txtContact = $window.FindName('TxtContact')
|
|
$btnOK = $window.FindName('BtnOK')
|
|
|
|
$imgHeader.Source = $wpfWarning
|
|
$imgTray.Source = $wpfShield
|
|
$txtContact.Text = "Questions? Contact IT at $ContactNumber"
|
|
|
|
$txtBody.Inlines.Add("Your screen is being recorded into a rolling $BufferMinutes-minute replay buffer. Nothing is saved until you request it.`n`nTo save a clip, ")
|
|
$bold1 = New-Object System.Windows.Documents.Run('right-click the shield icon')
|
|
$bold1.FontWeight = [System.Windows.FontWeights]::Bold
|
|
$txtBody.Inlines.Add($bold1)
|
|
$txtBody.Inlines.Add(' in your system tray (bottom-right of your screen) and select ')
|
|
$bold2 = New-Object System.Windows.Documents.Run('Save Replay')
|
|
$bold2.FontWeight = [System.Windows.FontWeights]::Bold
|
|
$txtBody.Inlines.Add($bold2)
|
|
$txtBody.Inlines.Add('.')
|
|
|
|
} else {
|
|
[xml]$xaml = @"
|
|
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
Title="IT Screen Recorder" SizeToContent="Height" Width="440"
|
|
WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
|
|
Topmost="True" ShowInTaskbar="False">
|
|
<Grid Margin="20">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="*"/>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="Auto"/>
|
|
</Grid.RowDefinitions>
|
|
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,14">
|
|
<Image x:Name="ImgHeader" Width="32" Height="32" Margin="0,0,10,0" VerticalAlignment="Center"/>
|
|
<TextBlock Text="Replay Saved Successfully" FontSize="16" FontWeight="SemiBold" FontFamily="Segoe UI" VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
<TextBlock x:Name="TxtBody" Grid.Row="1" TextWrapping="Wrap" FontSize="12" FontFamily="Segoe UI" LineHeight="22"/>
|
|
<TextBlock x:Name="TxtContact" Grid.Row="2" FontSize="11" FontFamily="Segoe UI" Foreground="#555" HorizontalAlignment="Center" Margin="0,12,0,16"/>
|
|
<Button x:Name="BtnOK" Grid.Row="3" Width="100" HorizontalAlignment="Center" IsDefault="True"/>
|
|
</Grid>
|
|
</Window>
|
|
"@
|
|
|
|
$window = [System.Windows.Markup.XamlReader]::Load([System.Xml.XmlNodeReader]::new($xaml))
|
|
$imgHeader = $window.FindName('ImgHeader')
|
|
$txtBody = $window.FindName('TxtBody')
|
|
$txtContact = $window.FindName('TxtContact')
|
|
$btnOK = $window.FindName('BtnOK')
|
|
|
|
$imgHeader.Source = $wpfShield
|
|
$txtContact.Text = "Questions? Contact IT at $ContactNumber"
|
|
|
|
$txtBody.Inlines.Add("Your replay has been saved ($FileSizeMB MB):`n")
|
|
$bold1 = New-Object System.Windows.Documents.Run($FileName)
|
|
$bold1.FontWeight = [System.Windows.FontWeights]::Bold
|
|
$txtBody.Inlines.Add($bold1)
|
|
$txtBody.Inlines.Add("`n`nIT can retrieve this file if needed for a support case.")
|
|
}
|
|
|
|
if ($Type -eq 'ReplaySaved') {
|
|
# Countdown timer — auto-dismisses after 30 seconds
|
|
# Use a hashtable for shared state so the closure captures it by reference correctly
|
|
$state = @{ Tick = 30 }
|
|
$btnOK.Content = 'OK (30)'
|
|
$timer = New-Object System.Windows.Threading.DispatcherTimer
|
|
$timer.Interval = [TimeSpan]::FromSeconds(1)
|
|
$timer.Add_Tick({
|
|
$state.Tick--
|
|
$btnOK.Content = "OK ($($state.Tick))"
|
|
if ($state.Tick -le 0) {
|
|
$timer.Stop()
|
|
$window.Close()
|
|
}
|
|
}.GetNewClosure())
|
|
$timer.Start()
|
|
$btnOK.Add_Click({ $timer.Stop(); $window.Close() }.GetNewClosure())
|
|
} else {
|
|
$btnOK.Content = 'OK'
|
|
$btnOK.Add_Click({ $window.Close() }.GetNewClosure())
|
|
}
|
|
$window.ShowDialog() | Out-Null
|