I'm trying to create a script to automatically scale up a VM display when on an HiDPI display (code below), and I'm having trouble creating an aggregate event source (in monitorUntilStateChanges function):
Code: Select all
Exception setting "CreateAggregator": Cannot convert the "System.Object[]" value of type "Object[]" to type "array".
At C:\Users\xxxxxx\autoScaleVm.ps1:42 char:2
+ $agg = $console.EventSource.CreateAggregator($eventSources)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : RuntimeException
Best regards,
Nicolas
Code: Select all
$VM_NAME="Work"
$WIDTH_THRESHOLD=2000
$HEIGHT_THRESHOLD=1500
$HIDPI_SCALE=2
$LOWDPI_SCALE=1
## Constants
$VBOX = New-Object -ComObject VirtualBox.VirtualBox
$STATE_RUNNING = 5
$EVENT_OnMachineStateChanged = 32
$EVENT_OnGuestMonitorInfoChanged = 102
$LOCK_SHARED = 1
function waitForRunningState($machine) {
Write-Host "Waiting for machine to be running..."
$eventSource = $VBOX.EventSource
$listener = $eventSource.CreateListener()
[int[]] $eventTypes = $EVENT_OnMachineStateChanged
$eventSource.RegisterListener($listener, $eventTypes, $false)
while($machine.State -ne $STATE_RUNNING) {
$event = $eventSource.getEvent($listener, -1)
}
$eventSource.UnregisterListener($listener)
Write-Host "OK"
}
function monitorUntilStateChanges($machine) {
Write-Host "Monitoring..."
$session = New-Object -ComObject VirtualBox.Session
$machine.LockMachine($session, $LOCK_SHARED)
$console = $session.Console
$eventSources = $VBOX.EventSource, $console.EventSource
$agg = $console.EventSource.CreateAggregator($eventSources)
$listener = $agg.CreateListener()
$eventTypes = $EVENT_OnGuestMonitorInfoChanged, $EVENT_OnMachineStateChanged
$agg.RegisterListener($listener, $eventTypes, $false)
adjustScale $session
while($true) {
$event = $agg.getEvent($listener, -1)
if($event.type -eq $EVENT_OnMachineStateChanged) {
Write-Host " Machine state changed, ending monitoring"
break
} else {
Write-Host " Monitor info changed"
Write-Host " Waiting for resolution to actually change..."
$didChange = waitResolutionForChange
if($didChange) {
adjustScale $session
} else {
Write-Host " Did not change"
}
}
}
agg.UnregisterListener($listener)
$session.unlockMachine()
Write-Host "End"
}
function adjustScale($session) {
$fb = getFrameBuffer $session
$currentScale = getScale $session
$width = $fb.Width*$currentScale
$height = $fb.Height*$currentScale
Write-Host(" FrameBuffer size is $($width)x$($height) host pixels")
if($width -gt $WIDTH_THRESHOLD -or $height -gt $HEIGHT_THRESHOLD) {
setScale $session $HIDPI_SCALE
} else {
setScale $session $LOWDPI_SCALE
}
}
function setScale($session, $scale) {
$currentScale = getScale
if($currentScale -ne $scale) {
Write-Host("Scaling x$($scale)")
$session.machine.SetExtraData("GUI/ScaleFactor", $scale)
}
}
function getScale($session) {
return $session.machine.GetExtraData("GUI/ScaleFactor")
}
function waitResolutionForChange($session) {
$fb = getFrameBuffer $session
$width = $fb.Width
$height = $fb.Height
Write-Host " Waiting for resolution to actually change..."
$i = 10
while($i-- -gt 0 -and $width -eq $fb.Width -and $height -eq $fb.Height) {
Start-Sleep -Seconds 1
}
return $width -ne $fb.Width -or $height -ne $fb.Height
}
function getFrameBuffer($session) {
return $session.Console.Display.QueryFramebuffer(0)
}
$machine = $VBOX.findMachine($VM_NAME)
while($true) {
waitForRunningState $machine
monitorUntilStateChanges $machine
}