Last active
October 31, 2024 05:36
-
-
Save bdpdx/a43fc582f474c1e4e841af19ab9ba2ce to your computer and use it in GitHub Desktop.
PowerShell script to launch Chrome with multiple fullscreen windows onto different monitors.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# PowerShell script derived from code and examples of Oleksandr Tomin. | |
# | |
# https://github.com/alex-tomin/Tomin.Tools.KioskMode | |
# https://alextomin.wordpress.com/2015/04/10/kiosk-mode-in-windows-chrome-on-multiple-displays/ | |
# | |
# A comment was left by Garr G on the Wordpress site that suggested combining C# directly into | |
# the PowerShell script so the user doesn't have to load a dll. I've done that here. | |
# | |
# Note that in the default Windows setup scripts are disabled. You'll need to run PowerShell as an | |
# Administrator and execute the command "Set-ExecutionPolicy RemoteSigned" | |
# | |
# updated for Windows 11 Pro by Brian Doyle 2024.10.30 | |
$CSharpCode = @" | |
using System; | |
using System.Runtime.InteropServices; | |
using System.Windows.Forms; | |
namespace KioskMode | |
{ | |
public enum ShowWindowCommands | |
{ | |
Hide = 0, | |
ShowNormal = 1, | |
Maximize = 3, | |
Minimize = 6, | |
Restore = 9 | |
} | |
[Flags] | |
public enum SetWindowPosFlags : uint | |
{ | |
SWP_NOZORDER = 0x0004, | |
SWP_NOREDRAW = 0x0008, | |
SWP_NOSIZE = 0x0001 | |
} | |
public static class WinApi | |
{ | |
[DllImport("user32.dll", SetLastError = true)] | |
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, | |
int X, int Y, int cx, int cy, SetWindowPosFlags uFlags); | |
[DllImport("user32.dll")] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow); | |
[DllImport("user32.dll")] | |
public static extern bool SetForegroundWindow(IntPtr hWnd); | |
public static bool MoveToMonitor(IntPtr windowHandle, int monitor) | |
{ | |
monitor = monitor - 1; | |
return SetWindowPos(windowHandle, IntPtr.Zero, | |
Screen.AllScreens[monitor].WorkingArea.Left, | |
Screen.AllScreens[monitor].WorkingArea.Top, 1000, 800, | |
SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOREDRAW); | |
} | |
public static void SendKey(IntPtr windowHandle, string keys) | |
{ | |
SetForegroundWindow(windowHandle); | |
SendKeys.SendWait(keys); | |
SendKeys.Flush(); | |
} | |
} | |
} | |
"@ | |
Add-Type -TypeDefinition $CSharpCode -Language CSharp -ReferencedAssemblies "System.Windows.Forms", "System.Drawing" | |
# Example to show a window (replace with actual window handle) | |
#$windowHandle = [System.IntPtr]::Zero # Replace with the real handle | |
#[KioskMode.WinApi]::ShowWindow($windowHandle, [KioskMode.ShowWindowCommands]::Maximize) | |
# Move to monitor (assuming monitor 2) | |
#[KioskMode.WinApi]::MoveToMonitor($windowHandle, 2) | |
# Send F11 to make Chrome go full screen (assuming F11 triggers full-screen mode) | |
#[KioskMode.WinApi]::SendKey($windowHandle, "{F11}") | |
$WinAPI = [KioskMode.WinApi] | |
function Wait-ForProcess($procName, $procTitle) | |
{ | |
$sw = [Diagnostics.Stopwatch]::StartNew() | |
while ($true) | |
{ | |
$res = Get-Process -Name $procName | where {$_.MainWindowHandle -ne ([IntPtr]::Zero) -and (!$procTitle -or $_.MainWindowTitle -eq $procTitle)} | |
if ($res) | |
{ | |
return $res | |
} | |
Start-Sleep -Milliseconds 100 | |
if ($sw.Elapsed.TotalMinutes -gt 5) | |
{ | |
Write-Error TimeOut | |
return | |
} | |
} | |
} | |
function Chrome-Kiosk($Url, $MonitorNum) | |
{ | |
Write-Output "starting chrome $Url, monitor: $MonitorNum" | |
Start-Process $chromePath "$chromeArguments $Url" | |
Start-Sleep -Seconds $ChromeStartDelay | |
$window = (Get-Process -Name chrome | where MainWindowHandle -ne ([IntPtr]::Zero) | select -First 1).MainWindowHandle | |
$WinAPI::ShowWindow($window, [KioskMode.ShowWindowCommands]::Restore) | |
$WinAPI::MoveToMonitor($window, $MonitorNum) | |
$WinAPI::SendKey($window, '{F11}') | |
Start-Sleep -Seconds $ChromeStartDelay | |
} | |
function Cockpit-Start($MonitorNum) | |
{ | |
Start-Process $cockpitPath | |
#main window | |
$window = (Wait-ForProcess Ciklum.Cockpit.CommunicationSpace 'COCKPIT COMMUNICATION SPACE' | select -First 1).MainWindowHandle | |
$WinAPI::ShowWindow($window, [KioskMode.Enums.ShowWindowCommands]::Restore) | |
$WinAPI::MoveToMonitor($window, $MonitorNum) | |
$WinAPI::ShowWindow($window, [KioskMode.Enums.ShowWindowCommands]::Maximize) | |
} | |
###################################################### | |
########## Kiosk Mode ############ | |
###################################################### | |
# | |
# Runs chrome and other apps in full-screen mode | |
# on predefined screens | |
# ---------------------------------------------------- | |
$chromePath = 'C:\Program Files\Google\Chrome\Application\chrome.exe' | |
$chromeArguments = '--new-window' | |
# if Window not moved (especially on machine start) - try increasing the delay. | |
$ChromeStartDelay = 3 | |
Set-Location $PSScriptRoot | |
# Kill all running instances (optional) | |
# &taskkill /im chrome* /F | |
Chrome-Kiosk 'https://apple.com' -MonitorNum 1 | |
Chrome-Kiosk 'https://google.com' -MonitorNum 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment