Skip to content

Instantly share code, notes, and snippets.

@bdpdx
Last active October 31, 2024 05:36
Show Gist options
  • Save bdpdx/a43fc582f474c1e4e841af19ab9ba2ce to your computer and use it in GitHub Desktop.
Save bdpdx/a43fc582f474c1e4e841af19ab9ba2ce to your computer and use it in GitHub Desktop.
PowerShell script to launch Chrome with multiple fullscreen windows onto different monitors.
# 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