| VNCDOTOOL(1) | VNCDoTool | VNCDOTOOL(1) |
vncdotool - VNCDoTool Documentation
Actions StatusReadTheDocsCode style: black.SH VNCDOTOOL
vncdotool is a command line VNC client. It can be useful to automating interactions with virtual machines or hardware devices that are otherwise difficult to control.
It's under active development and seems to be working, but please report any problems you have.
To use vncdotool you will need a VNC server. Most virtualization products include one, or use RealVNC, TightVNC or clone your Desktop using x11vnc.
Once, you have a server running you can install vncdotool from pypi:
pip install vncdotool
and then send a message to the vncserver with:
vncdo -s vncserver type "hello world"
The vncserver argument needs to be in the format address[:display|::port]. For example:
# connect to 192.168.1.1 on default port 5900 vncdo -s 192.168.1.1 type "hello world" # connect to localhost on display :3 (port 5903) vncdo -s localhost:3 type "hello world" # connect to myvncserver.com on port 5902 (two colons needed) vncdo -s myvncserver.com::5902 type "hello world" # connect via IPv6 to localhost on display :3 (port 5903) vncdo -s '[::1]:3' type "hello IPv6" # ^ ^ mind those square brackets around the IPv6 address
You can also take a screen capture with:
vncdo -s vncserver capture screen.png
More documentation can be found on Read the Docs.
If you need help getting VNCDoTool working try the community at _Stackoverflow
Patches, and ideas for improvements are welcome and appreciated, via _GitHub issues. If you are reporting a bug or issue please include the version of both vncdotool and the VNC server you are using it with.
Thanks to Chris Liechti, techtonik and Todd Whiteman for developing the RFB and DES implementations used by vncdotool. Also, to the TigerVNC project for creating a community focus RFB specification document
vncdotool is available on PyPI, so in most cases you should be able to simply run:
pip install vncdotool
vncdotool relies on a number of libraries, the two major ones are PIL, the Python Imaging Library and Twisted, an asynchronous networking library. While vncdotool should work with any recent version of these libraries sometimes things break. If you are having issues getting things to work you can try using a stable set of libraries and if you aren't already using it, and you should be, use a virtualenv.:
pip install virtualenv virtualenv venv-vncdotool # XXX requirements.txt from vncdotool source tree pip install -r requirements.txt pip install -e .
If you are not familiar with Python, the most reliable way to install vncdotool is to use binary packages.
[Environment]::SetEnvironmentVariable("Path", "$env:Path;C:\Program Files\Python39\;C:\Program Files\Python39\Scripts\", "User")
python -m pip install --upgrade pip
pip install vncdotool
vncdo.exe --server som.eip.add.res type "Hello World"
Once installed you can use the vncdotool command to send key-presses. Alphanumerics are straightforward just specify the character. For other keys longer names are used:
> vncdo key a > vncdo key 5 > vncdo key . > vncdo key enter > vncdo key shift-a > vncdo key ctrl-C > vncdo key ctrl-alt-del
To type longer strings when entering data or commands you can use the type c command, which does not support special characters:
> vncdo type "hello world"
You can control the mouse pointer with move and click commands. NOTE, you should almost always issue a move before a click, as in:
> vncdo move 100 100 click 1
The following would seem to be equivalent but would actually click at (0, 0). This occurs due to how click events are encoded by VNC, meaning you need to initialise the position of the mouse.:
> vncdo move 100 100 > vncdo click 1
If you have the Python Imaging Library (Pillow) installed you can also make screen captures of the session:
> vncdo capture screenshot.png
With Pillow installed, you can wait for the screen to match a known image:
> vncdo expect somescreen.png 0
Putting it all together you can specify multiple actions on a single command line. You could automate a login with the following:
> vncdo type username key enter expect password_prompt.png > vncdo type password move 100 150 click 1 expect welcome_screen.png
Sometimes you only care about a portion of the screen, in which case you can use rcapture and rexpect. For instance, if your login window appears at x=100, y=200 and is 400 pixels wide by 250 high you could do:
> vncdo rcapture region.png 100 200 400 250 > vncdo rexpect region.png 100 200 0
For more complex automation you can read commands from stdin or a file. The file format is simply a collection of actions:
> echo "type hello" | vncdo -
Or if you had a file called login.vdo with the following content:
# select the name text box, enter your name and submit move 100 100 click 1 type "my name" key tab key enter # grab the result capture screenshot.png
You could run it with the following command:
> vncdo login.vdo
While you can create scripts by hand it can often be a time consuming process. To make the process easier vncdotool provides a log mode that allows a user to record a VNC session to a script which is playable by vncdo. vnclog act as a man-in-the-middle to record the VNC commands you issue with a client. So you will have your vnclog connect to your server and your viewer connect to vnclog
For best results be sure to set your vncviewer client to use the RAW encoding. Others encoding may work but are not fully supported at this time.
The quickest way to get started is to run:
> vnclog --viewer vncviewer keylog.vdo
For more control you can launch the viewer separately but be sure to connect to the correct ports:
> vnclog keylog.vdo > vncviewer localhost:2 # do something and then exit viewer > vncdo keylog.vdo
By running with --forever vnclog will create a new file for every client connection and record each clients activity. This can be useful for quickly recording a number of testcases.:
> vnclog --forever --listen 6000 /tmp > vncviewer localhost::6000 # do some stuff then exit and start new session > vncviewer localhost::6000 # do some other stuff > ls /tmp/*.vdo
vncdotool is built with the Twisted framework, as such it best intergrates with other Twisted Applications Rewriting your application to use Twisted may not be an option, so vncdotool provides a compatibility layer. It uses a separate thread to run the Twisted reactor and communicates with the main program using a threadsafe Queue.
To use the synchronous API you can do the following:
from vncdotool import api
client = api.connect('vncserver', password=None)
The first argument passed to the connect method is the VNC server to connect to, and it needs to be in the format address[:display|::port]. For example:
# connect to 192.168.1.1 on default port 5900
client = api.connect('192.168.1.1', password=None)
# connect to localhost on display :3 (port 5903)
client = api.connect('localhost:3', password=None)
# connect to myvncserver.com on port 5902 (two colons needed)
client = api.connect('myvncserver.com::5902', password=None)
You can then call any of the methods available on vncdotool.client.VNCDoToolClient and they will block until completion. For example:
client.captureScreen('screenshot.png')
client.keyPress('enter')
client.expectScreen('login_success.png', maxrms=10)
It is possible to set a per-client timeout in seconds to prevent calls from blocking indefinitely.
client.timeout = 10 try:
client.captureScreen('screenshot.png') except TimeoutError:
print('Timeout when capturing screen')
In case of too many timeout errors, it is recommended to reset the client connection via the disconnect and connect methods.
The vncdotool.client.VNCDoToolClient supports the context manager protocol.
with api.connect('vnchost:display') as client:
client.captureScreen('screenshot.png')
The synchronous API can be used to automate the starting of a Virtual Machine or other application:
vmtool.start('myvirtualmachine.img')
client.connect('vmaddress::5950')
client.expectScreen('booted.png')
for k in 'username':
client.keyPress(k)
client.keyPress('enter')
for k in 'password':
client.keyPress(k)
client.keyPress('enter')
client.expectScreen('loggedin.png')
client.disconnect()
# continue with your testing session or other work
Huge thanks to @pmhahn for single handedly driving conversion to modern Python3, as well as cleaning up a ton of outstanding issues.
Thanks to Jan Sedlák, Daniel Stelter-Gliese, Antti Kervinen, Anatoly Techtonik, Tyler Oderkirk and Aragats Amirkhanyan for helping make this release possible
Code and Issue tracking is provided by Github. There is also a mailing list setup via Google Groups.
Marc Sibson
2024, Marc Sibson
| May 24, 2024 | 0.9 |