Automating tasks in a virtualized OS

5 décembre 2019 · 4 min read

Or how to perform actions in a virtual machine without leaving the terminal…

From Linux, I was looking for a way to automate the compilation of a software on Windows, and without using Wine which is not an official Microsoft product.

VirtualBox is a multi-platform virtualization software. It comes with VBoxManage, a command line tool for managing virtual machines.

Let’s take a concrete case: here is the execution of a bash script on Linux that performs actions in a Windows 10 virtual machine, in order to compile a software, execute it, take a screenshot and copy it to the host.

Here is the result: we are in a Linux terminal that displays the output of DOS commands !

Compile on Windows with the 'Win10' VM

Starting VM
Waiting for VM "Win10" to power on...
VM "Win10" has been successfully started.

Creating directory c:/users/jeff/desktop/work
Copying main.js
Copying package.json
Copying du dossier app/

yarn install
yarn install v1.19.2
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 49.30s.

yarn run buildwin64
yarn run v1.19.2
$ electron-builder -w --x64
  • electron-builder version=20.44.4
  • loaded configuration file=package.json ("build" field)
  • no native production dependencies
  • packaging       platform=win32 arch=x64 electron=4.2.12 appOutDir=c:\Users\jeff\Desktop\dist\win-unpacked
  • building        target=portable file=c:\Users\jeff\Desktop\dist\app.exe archs=x64
Done in 67.88s.

Starting app in GUI
Screenshot for fun
Copying the app to host OS
Stopping VM

Source code of the bash script for the remote control of Windows, which the result is displayed above :


# Automating tasks in a virtualized OS

# directory to create in the guest OS to copy the app to compile

# login in guest OK

# password

echo "Compile on Windows with the 'Win10' VM"
echo # carriage return in the terminal

# Starting VM without graphical user interface
# INFO: to list available VM from your host, type the command: VBoxManage list vms
echo "Starting VM"
VBoxManage startvm "Win10" --type headless

# Creating directory in the VM
echo "Creating directory ${GUEST_PATH}/work"
VBoxManage guestcontrol "Win10" mkdir "${GUEST_PATH}/work" --username $GUEST_USER --password $GUEST_PASSWD

echo "Copying main.js"
VBoxManage guestcontrol "Win10" copyto main.js --target-directory "${GUEST_PATH}/work" --username $GUEST_USER --password $GUEST_PASSWD

echo "Copying package.json"
VBoxManage guestcontrol "Win10" copyto package.json --target-directory "${GUEST_PATH}/work" --username $GUEST_USER --password $GUEST_PASSWD

echo "Copying the host directory app/"
VBoxManage guestcontrol "Win10" mkdir "${GUEST_PATH}/work/app" --username $GUEST_USER --password $GUEST_PASSWD
VBoxManage guestcontrol "Win10" copyto -R app/ --target-directory "${GUEST_PATH}/work/app" --username $GUEST_USER --password $GUEST_PASSWD

# Creating a DOS script that will be executed in the guest OS to install the project dependencies
cat > install.bat <<EOL
@echo off
chdir /d c:\\Users\\jeff\\desktop\\work
yarn install
VBoxManage guestcontrol "Win10" copyto install.bat --target-directory "${GUEST_PATH}/work" --username $GUEST_USER --password $GUEST_PASSWD

# Creating a DOS script that will be executed in the guest OS to build the project
cat > build.bat <<EOL
@echo off
chdir /d c:\\Users\\jeff\\desktop\\work
yarn run buildwin64
VBoxManage guestcontrol "Win10" copyto build.bat --target-directory "${GUEST_PATH}/work" --username $GUEST_USER --password $GUEST_PASSWD

# Executing the 1st DOS script
echo "yarn install"
VBoxManage guestcontrol "Win10" run --exe "${GUEST_PATH}/work/install.bat" --username $GUEST_USER --password $GUEST_PASSWD --wait-stdout --wait-stderr

# Executing the 2nd DOS script
echo "yarn run buildwin64"
VBoxManage guestcontrol "Win10" run --exe "${GUEST_PATH}/work/build.bat" --username $GUEST_USER --password $GUEST_PASSWD --wait-stdout --wait-stderr

echo "Starting app in GUI in the VM"
VBoxManage guestcontrol "Win10" start --exe "${GUEST_PATH}/dist/app.exe" --username $GUEST_USER --password $GUEST_PASSWD

# Screenshot (video recording is also available)
echo "Screenshot for fun"
VBoxManage controlvm "Win10" screenshotpng 01.png

echo "Copying the app to host OS"
VBoxManage guestcontrol "Win10" copyfrom -R "${GUEST_PATH}/dist/" ../dist --username $GUEST_USER --password $GUEST_PASSWD

# INFO: to close an app in the guest OS, you must get its process ID and the session ID with the command :
# VBoxManage guestcontrol "Win10" list processes
# To quit the app :
# VBoxManage guestcontrol "Win10" closeprocess --session-id 1 2484

# Cleaning up the directories on host and guest
echo "Cleanup"
rm install.bat
rm build.bat
VBoxManage guestcontrol "Win10" rmdir -R "${GUEST_PATH}/work" --username $GUEST_USER --password $GUEST_PASSWD
VBoxManage guestcontrol "Win10" rmdir -R "${GUEST_PATH}/dist" --username $GUEST_USER --password $GUEST_PASSWD

# Shutting down the VM
echo "Stopping VM"
VBoxManage controlvm "Win10" savestate