Posso lançar um programa ou link da web no sistema operacional host a partir de uma VM VMware Guest?

1

Eu tenho alguns softwares que não são executados em minha máquina (Windows Vista), então eu os executo em uma VM VMware (Windows XP) usando unidade, para me proporcionar uma experiência de usuário perfeita. TM * 8 ')

Isso geralmente funciona muito bem, mas o software me permite lançar links em um navegador da web, que obviamente lança o link em um novo navegador da VM, enquanto eu gostaria que os links fossem lançados de tal forma que a página finalizasse no navegador da web no meu host.

Alguém sabe se isso é possível e, em caso afirmativo, como?

Eu posso configurar o comando que é executado para iniciar um link no aplicativo, portanto, se for necessário que um comando específico seja executado no convidado, isso não será problema.

Obrigado.

    
por Mark Booth 24.05.2011 / 22:13

2 respostas

3

Estou procurando uma maneira de iniciar aplicativos do Windows (o host) em uma máquina virtual do Ubuntu (no VMWare Player). Fiquei um pouco empolgado e escrevi os scripts de cliente e servidor listados abaixo. O sistema operacional convidado não é o Windows, portanto, algumas alterações precisarão funcionar para um convidado do Windows. Eu usei esta configuração para que o Git (que roda no guest do Ubuntu) chame o KDiff3 no host ao mesclar.

O seguinte script Python (host_run_server.py) atua como um servidor aceitando comandos do convidado. Ele espera que o convidado forneça um compartilhamento do Samba com o nome GUEST_ROOT_SHARE (configure isso na parte superior do script) que expõe a raiz do sistema de arquivos. Esse compartilhamento é mapeado para uma unidade GUEST_DRIVE . Isso é necessário para que o host e o convidado possam acessar os mesmos arquivos. No meu caso, eu já tinha também montado 'Meus Documentos' para uma pasta no convidado para poder usar o git nos arquivos do meu host.

import asyncore, asynchat
import os
import socket
import shlex, subprocess
import threading

# make the root / of the guest accessible as a samba share and map
# this share in the host to GUEST_DRIVE

HOST_IP = '192.168.126.1'
GUEST_IP = '192.168.126.129'
GUEST_ROOT_SHARE = 'root'
GUEST_DRIVE = 'K:'

TCP_PORT = 5005
BUFFER_SIZE = 1024
ENCODING = 'utf-8'

# map network drive
try:
    import win32wnet
    import pywintypes
    from win32netcon import RESOURCETYPE_DISK

    network_path = r'\{}\{}'.format(GUEST_IP, GUEST_ROOT_SHARE)
    try:
        win32wnet.WNetAddConnection2(RESOURCETYPE_DISK, GUEST_DRIVE, network_path)
    except pywintypes.error as e:
        if (e.args[0] != 85 or
            win32wnet.WNetGetUniversalName(GUEST_DRIVE) != network_path):
            raise
except ImportError:
    pass


# allow GUI applications to pop to front on Windows
try:
    import win32gui
    from win32con import SPI_SETFOREGROUNDLOCKTIMEOUT

    result = win32gui.SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0)
    if result is not None:
        print("Failed:", result)
except ImportError:
    pass


class Handler(asynchat.async_chat):    
    def __init__(self, sock, map=None):
        asynchat.async_chat.__init__(self, sock, map=map)
        self.remote_ip, self.remote_port = self.socket.getpeername()
        self.log('connected')
        self.set_terminator(b'\x00')        
        self.data = b''
        self.state = 'cwd'

    def handle_close(self):
        remote_ip, remote_port = self.socket.getpeername()
        self.log('disconnected')
        self.close()

    def collect_incoming_data(self, data):
        self.data += data

    def found_terminator(self):
        if self.state == 'cwd':
            self.cwd = self.data.decode(ENCODING)
            self.state = 'cmd'
            self.data = b''
        elif self.state == 'cmd':
            self.cmd = self.data.decode(ENCODING)
            self.reply()
            self.state = 'end'

    def prepare(self):
        cwd = GUEST_DRIVE + self.cwd.replace('/', '\')
        self.log('in {}'.format(cwd))
        os.chdir(cwd)
        cmd_args = []
        for arg in shlex.split(self.cmd):
            if arg.startswith('[FILE]'):
                arg = arg[6:].replace('/', '\')
                if arg.startswith('\'):
                    arg = GUEST_DRIVE + arg
            cmd_args.append(arg)
        return cwd, cmd_args

    def run(self, cwd, cmd_args):
        self.log('executing: {}'.format(' '.join(cmd_args)))
        try:
            p = subprocess.Popen(cmd_args,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE,
                                 shell=True)
            out, err = p.communicate()
            rcode = p.returncode
        except WindowsError as e:
            out = b''
            err = '{}: {}\n'.format(e.__class__.__name__, e.args[1]).encode(ENCODING)
            rcode = -1
        return rcode, out, err

    def reply(self):
        cwd, cmd_args = self.prepare()
        rc, out, err = self.run(cwd, cmd_args)
        self.push(str(len(out)).encode(ENCODING) +  b'\x00')
        if len(out):
            self.push(out)
        self.push(str(len(err)).encode(ENCODING) +  b'\x00')
        if len(err):
            self.push(err)
        self.push(str(rc).encode(ENCODING) + b'\x00')

    def log(self, msg):
        print("[{}:{}]\t{}".format(self.remote_ip, self.remote_port, msg))


class HandlerThread(threading.Thread):
    def __init__(self, sock):
        super().__init__()
        self.sock = sock

    def run(self):
        handler = Handler(self.sock)
        asyncore.loop(map=handler._map)


class Server(asyncore.dispatcher):
    def __init__(self, host, port, guest_ip):
        asyncore.dispatcher.__init__(self, map={})
        self.guest_ip = guest_ip
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind((host, port))
        self.listen(5)
        print("Service started. Listening on {} port {}."
              .format(host, port))

    def handle_accepted(self, sock, addr):
        (guest_ip, guest_port) = addr
        if guest_ip == self.guest_ip:
            ht = HandlerThread(sock)
            ht.start()
        else:
            print("Ignoring request from {}".format(guest_ip))


server = Server(HOST_IP, TCP_PORT, GUEST_IP)
asyncore.loop(map=server._map)

Abaixo está o script para invocar no lado do convidado (host_run.py).

#!/usr/bin/env python3

import asyncore, asynchat
import os
import socket
import sys
from optparse import OptionParser


HOST_IP = "192.168.126.1"
GUEST_IP = "192.168.126.129"
HOST_IS_WINDOWS = True

TCP_PORT = 5005
BUFFER_SIZE = 1024
ENCODING = 'utf-8'

STD_ENCODING = 'cp1252' if HOST_IS_WINDOWS else ENCODING


class HostRun(asynchat.async_chat):    
    def __init__(self, host, port):
        asynchat.async_chat.__init__(self)
        self.set_terminator(b'\x00')        
        self.data = b''
        self.state = 'stdout1'
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect((host, port))

    def handle_connect(self):
        self.push(os.getcwd().encode(ENCODING) + b'\x00')
        self.push(command.encode(ENCODING) + b'\x00')

    def collect_incoming_data(self, data):
        self.data += data

    def found_terminator(self):
        if self.state == 'stdout1':
            stdout_len = int(self.data.decode(ENCODING))
            if stdout_len:
                self.set_terminator(stdout_len)
                self.state = 'stdout2'
            else:
                self.state = 'stderr1'
        elif self.state == 'stdout2':
            stdout = self.data.decode(STD_ENCODING)
            sys.stdout.write(stdout)
            self.set_terminator(b'\x00')
            self.state = 'stderr1'
        elif self.state == 'stderr1':
            stderr_len = int(self.data.decode(ENCODING))
            if stderr_len:
                self.set_terminator(stderr_len)
                self.state = 'stderr2'
            else:
                self.state = 'rc'
        elif self.state == 'stderr2':
            stderr = self.data.decode(STD_ENCODING)
            sys.stderr.write(stderr)
            self.set_terminator(b'\x00')
            self.state = 'rc'
        elif self.state == 'rc':
            rc = int(self.data.decode(ENCODING))
            sys.exit(rc)
            self.close_when_done()
        self.data = b''

    def handle_close(self):
        remote_ip, remote_port = self.socket.getpeername()
        print("%s:%s disconnected" %(remote_ip, remote_port))
        self.close()


parser = OptionParser()
(options, args) = parser.parse_args()

command = ' '.join(args)

HostRun(HOST_IP, TCP_PORT)

asyncore.loop()

Os scripts cuidam da tradução de caminhos de arquivos. Para que isso funcione, é necessário preceder os caminhos passados como argumentos para o script de cliente com [FILE]

Primeiro, inicie o script do servidor no host. Agora você pode passar comandos para o script do cliente:

brecht@krubuntu ~ $ ./host_run.py dir [FILE]/home

Isso traduzirá /home para K:\home e, portanto, executará dir K:\home no host. O servidor envia a saída stdout / stderr e retorna o código para o cliente, que o envia de volta para o prompt do shell:

 Volume in drive K is root
 Volume Serial Number is 64C2-522A

 Directory of K:\home

07/22/2012  22:13    <DIR>          .
12/04/2012  06:53    <DIR>          ..
02/28/2013  21:56    <DIR>          brecht
               0 File(s)              0 bytes
               3 Dir(s)  12,723,302,400 bytes free
    
por 28.02.2013 / 22:03
1

Isso pode ser feito, mas acho que seria necessário comunicação de rede entre convidado e host e um programa auxiliar em execução em cada um. Você pode, alternativamente, apenas copiar / colar se não for muito complicado.

Qual é o software que não será executado no Vista? Eu estou supondo que você tentou o modo de compatibilidade etc.

    
por 24.05.2011 / 22:45