In this section, we will write a simple program that can be used to automatically install a hypothetical operating system inside a brand new virtual machine.
Step 1 - Preparation
First, we have to capture all screens that the OS installation procedure displays to the user.
Step 2 - Writing the automated OS installation program
Now that we have the screenshots and interaction instructions, we can write the program that will automatically install the OS on any blank virtual machine.
VmDisplayDev.connect_to_vm
method invocation and end with VmDisplayDev.disconnect_from_vm
. These step are necessary to properly initialize/deinitialize the remote desktop access library and protocol.Bit-by-bit comparison notes
In theory, the screen comparison procedure described above (comparing two full screens) should work. In reality, however, it is virtually impossible to achieve a state when an individual screen remains absolutely static. Such things as blinking cursor, messages from the program vendor, and other animations will make each capture different from another. Therefore, instead of comparing an entire screen, the following approach can be used:
The following sample program illustrates the implementation of the steps above. The program does not include the implementation of the algorithm described in the Bit-by-bit comparison subsection (above). An implementation of the algorithm depends on the image format used and in any case should be simple and straightforward.
import sys
import prlsdkapi
if len(sys.argv) != 3:
print "Usage: install_os <VM_name> <path_to_iso>"
exit()
# Initialize the Parallels API library.
prlsdkapi.prlsdk.InitializeSDK(prlsdkapi.consts.PAM_DESKTOP)
# Obtain a server object identifying the
# Parallels Service.
server = prlsdkapi.Server()
# Log in.
login_job = server.login_local()
login_job.wait()
# Get a list of virtual machines.
# Find the specified virtual machine and
# obtain an object identifying it.
vm_list = server.get_vm_list()
for item in vm_list:
if item.name == sys.argv[1]:
VM = item
# Obtain an object identifying the
# CD/DVD drive
cdrom = VM.get_optical(0)
# Begin the virtual machine editing operation.
VM.begin_edit()
# Mount the OS installation ISO image.
cdrom.emulated_type = prlsdkapi.consts.PDT_USE_IMAGE_FILE
cdrom.sys_name = sys.argv[2]
cdrom.image_path = sys.argv[2]
# Commit the changes to the virtual machine.
VM.commit()
# Start the virtual machine.
VM.start().wait()
# Instantiate the prlsdkapi.VmDisplayDev class.
# This class provides methods for Remote Desktop Access.
display = VM.display_dev
# Begin a Remote Desktop Access session.
display.connect_to_vm().wait()
# Define the name of the file to save the
# captured screen data to.
current_screen = "current.bmp"
# Set the reference screenshot count to 0.
ref_count = 0
# Define the names of files containing
# reference screenshots.
ref_files = ['1.bmp', '2.bmp', '3.bmp']
# Define the keyboard keys that will be used
# to interact with the remote desktop.
keys = ['enter', 'f1', 'enter']
# Capture the virtual machine screen, find the matching
# screen in the list of reference files and send the
# appropriate keyboard command to the virtual machine.
# Repeat for all screens.
while True:
# Get a reference file name.
ref_screen = ref_files[ref_count]
# Capture the current virtual machine desktop screen and save it
# into a file as a BMP image.
# The parameters are:
# Target file name
# X coordinate
# Y coordinate
# Width (-1 for full screen)
# Height (-1 for full screen)
# Image format
display.capture_screen_to_file(current_screen, 0, 0, -1, -1, prlsdkapi.prlsdk.consts.PIF_BMP)
# Do a bit-by-bit comparison of the captured screen and
# the reference screen for this iteration.
# The actual comparison procedure depends on the data format used.
# The bb_cmp function is only an example, you will have to implement the
# comparison procedure yourself.
if bb_cmp(current_screen, ref_screen):
print "%d screen valid" % ref_count
# Press the appropriate key.
press = prlsdkapi.prlsdk.consts.PKE_PRESS
release = prlsdkapi.prlsdk.consts.PKE_RELEASE
key = keys[ref_count]
key = key.upper()
# Determine the key scan code based on its name.
# The codes are defined in the ScanCodesList constant.
# For the complete list of codes, start Python from the command line,
# import the prlsdkapi module, and issue the
# "print prlsdkapi.prlsdk.consts.ScanCodesList" statement.
scan_code = prlsdkapi.prlsdk.consts.ScanCodesList[key]
# Send the key command to the virtual machine.
display.send_keys_event([(press, scan_code), (release, scan_code)])
# If still have reference files to process, continue, otherwise, exit.
if ref_count < (len(ref_files) - 1):
ref_count = ref_count + 1
else:
print "Os is installed."
break
# End the Remote Desktop Access session.
display.disconnect_from_vm()
# Stop the virtual machine.
VM.stop().wait()
# Deinitialize the Parallels API library.
prlsdkapi.prlsdk.DeinitializeSDK()