0

I am trying to modify the remote windows host's screen resolution via SSH. Firstly, i use python to write a little script to change local desktop's resolution.

import win32api
dm = win32api.EnumDisplaySettings(None, 0)
dm.PelsHeight = 1024    
dm.PelsWidth = 1280

win32api.ChangeDisplaySettings(dm, 0)

And then, use pyinstaller to build it as standalone .exe file, put the outputted file to remote host, and execute the tool via SSH.

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(remote_win_host_ip, username= host_user, password=host_pswd)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('/cygdrive/e/test/change_screen_res.exe')

Meanwhile, i write a script to show the current resolution, and use it on remote host in the same way.

from win32api import GetSystemMetrics

print "width =", GetSystemMetrics (0)
print "height =",GetSystemMetrics (1)

However, I find that the resolution of remote host is always 1024*768.

How can I modify the resolution?

Thanks

SUT
  • 384
  • 1
  • 7
  • 23
  • Does running the executable manually on the remote host change the screen resolution? – Blender Dec 17 '13 at 07:46
  • No, use paramiko or plink to execute the file remotely via SSH. – SUT Dec 17 '13 at 07:49
  • And what does your SSH code look like? (SSH does not provide any tools for changing resolution, nor does it "exist" for windows). What command are you trying to run in order to change the resolution on the remote host? – Torxed Dec 17 '13 at 07:49
  • @SUT: I mean, does the executable actually work? Does it run on a computer that doesn't have Python installed? I remember either Py2EXE or PyInstaller had some dependency on the .NET framework. – Blender Dec 17 '13 at 07:50
  • Yes, i try to execute the tools on the remote host directly, and they work fine. – SUT Dec 17 '13 at 07:52
  • Is the remote machine a windows machine as well? – Torxed Dec 17 '13 at 07:54
  • @Torxed: I wrote a tool which could be used to change local resolution successfully. So I try to put the tool to remote server, and call it from local desktop via SSH. For example, 'plink -SSH -C -l user -pw pwd hostip /cygdrive/test/tool.exe'. – SUT Dec 17 '13 at 07:58
  • @Torxed All hosts are running windows. – SUT Dec 17 '13 at 07:58
  • @SUT And you're running a SSH server on windows? First of all, is the SSH service running as System you're screwed because you'll need to run the script in usermode in order to change your current resolution. – Torxed Dec 17 '13 at 08:29

2 Answers2

0
from os import fork, waitpid, execv, read, write
import pty, sys

class ssh():
    def __init__(self, host, execute='echo "done" > /root/testing.txt', askpass=False, user='root', password='UberPassword'):
        self.exec = execute
        self.host = host
        self.user = user
        self.password = password
        self.askpass = askpass
        self.run()

    def run(self):
        command = [
                '/usr/bin/ssh',
                self.user+'@'+self.host,
                '-o', 'NumberOfPasswordPrompts=1',
                self.exec,
        ]

        pid, child_fd = pty.fork()

        if not pid: # Child process
            # Replace child process with our SSH process
            execv(command[0], command)

        ## if we havn't setup pub-key authentication
        ## we can loop for a password promt and "insert" the password.
        while self.askpass:
            try:
                output = read(child_fd, 1024).strip()
            except:
                break
            lower = output.lower()
            # Write the password
            if b'password:' in lower:
                write(child_fd, self.password + b'\n')
                break
            elif b'are you sure you want to continue connecting' in lower:
                # Adding key to known_hosts
                write(child_fd, b'yes\n')
            elif b'MOTD and Leagal warning' in lower:
                pass # This is an understood message
            else:
                print('Error:',output)

        waitpid(pid, 0)

Will only work on linux tho thanks to pty. Another short solution is (but you need public keys):

from subprocess import Popen, PIPE, STDOUT

x = Popen("ssh -t -t root@hostname.com 'echo \"done\" > /root/testing.txt'", shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
while x.poll() == None:
    pass
x.stdout.close()
x.stdin.close()
Torxed
  • 22,866
  • 14
  • 82
  • 131
0

It seems that Windows does not support such operation at all. I tried many different ssh clients and screen resolution modification tools, none worked.

However, thanks to Jenkins slave agent and refer to jenkins-on-windows-and-gui-tests-without-rdc, there is a workaround for it.

Community
  • 1
  • 1
SUT
  • 384
  • 1
  • 7
  • 23