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
Cleanup
Stopping VM
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Source code of the bash script for the remote control of Windows, which the result is displayed above :
#!/bin/bash
# Automating tasks in a virtualized OS
# directory to create in the guest OS to copy the app to compile
GUEST_PATH="c:/users/jeff/desktop"
# login in guest OK
GUEST_USER="jeff"
# password
GUEST_PASSWD="123456"
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
echo
# 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
echo
# 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
EOL
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
EOL
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
echo
# 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
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
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