vmware在全屏模式下快速切换回win桌面的方法

时间:2024-11-14 08:57:09

window上开发没有ubuntu下的方便,经常在window主机和ubuntu虚拟机直接切换太麻烦,每次得ctrl+alt从虚拟机释放鼠标才可以切换,经过折腾发现以下几种方法可行

方法1 虚拟机监听切换按键并通知主机进行切换桌面

虚拟主机放在单独的一个桌面上并全屏,在ubuntu虚拟机中配置一个Py脚本,把监听的按键写入主机中(tcp方式更麻烦,这里采用写入文件传递的方法)

import os
from pynput import keyboard
import time

# 定义组合键,例如 Ctrl + Alt + A、Ctrl + Alt + S、Ctrl + Alt + Z
COMBINATIONS = {
    frozenset([keyboard.Key.ctrl, keyboard.Key.alt, keyboard.KeyCode(char='a')]): "SWITCH_DESKTOP_A",
    frozenset([keyboard.Key.ctrl, keyboard.Key.alt, keyboard.KeyCode(char='s')]): "SWITCH_DESKTOP_S",
    frozenset([keyboard.Key.ctrl, keyboard.Key.alt, keyboard.KeyCode(char='z')]): "SWITCH_DESKTOP_Z"
}
current_keys = set()
triggered = False  # 防止重复触发


def on_press(key):
    global triggered
    current_keys.add(key)
    for combination, command in COMBINATIONS.items():
        if combination.issubset(current_keys) and not triggered:
            # 根据按键组合写入不同的内容到共享文件
            with open("/home/vm/Desktop-win11/switch_command.txt", "w") as f:
                f.write(command)
            triggered = True  # 设置标志位,防止重复触发
            break


def on_release(key):
    global triggered
    if key in current_keys:
        current_keys.remove(key)
    # 如果所有按键都释放,重置标志位
    if not current_keys:
        triggered = False


with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

在主机上使用autohotkeys进行多桌面切换

VDA_PATH := "./VirtualDesktopAccessor.dll"
hVirtualDesktopAccessor := DllCall("LoadLibrary", "Str", VDA_PATH, "Ptr")

GoToDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GoToDesktopNumber", "Ptr")

GoToDesktopNumber(num) {
    global GoToDesktopNumberProc
    Send, ^{Alt}
    DllCall(GoToDesktopNumberProc, "Int", num)
}

; vmware 切换回win
; 定义共享文件路径
sharedFilePath := "C:\Users\marswen\Desktop\switch_command.txt"
lastModified := ""  ; 用于存储上次检测到的文件修改时间
SetTimer, CheckSwitchFile, 100

CheckSwitchFile:
    if FileExist(sharedFilePath) {
        ; 获取当前文件的最后修改时间
        FileGetTime, currentModified, %sharedFilePath%, M

        if (lastModified=""){
            lastModified := currentModified  ; 第一次读取文件内容,记录修改时间
        }
        else if(currentModified != lastModified) {
            ; 如果文件的修改时间不同于上次记录的时间,则读取文件内容并执行操作
            lastModified := currentModified  ; 更新记录的修改时间

            ; 读取文件内容
            FileRead, content, %sharedFilePath%

            ; 根据内容执行不同的操作
            if (content = "SWITCH_DESKTOP_A") {
                GoToDesktopNumber(0)  ; 切换到桌面 1
            } else if (content = "SWITCH_DESKTOP_S") {
                GoToDesktopNumber(1)  ; 切换到桌面 2
            } else if (content = "SWITCH_DESKTOP_Z") {
                GoToDesktopNumber(2)  ; 切换到桌面 3
            }
        }
    }
return

; 使用快捷键 Ctrl + Alt + 字母
^!A::GoToDesktopNumber(0)  ; 切换到第 1 个桌面
^!S::GoToDesktopNumber(1)  ; 切换到第 2 个桌面
^!Z::GoToDesktopNumber(2)  ; 切换到第 3 个桌面


; #:WIN  ^:Ctrl !:Alt  +:Shift  
; 映射window终端中键为 Ctrl + Shift + V
#IfWinActive ahk_exe WindowsTerminal.exe ; 针对 Windows Terminal
MButton::Send ^+v ; 将中键设置为 Ctrl + Shift + V
#IfWinActive

; 映射window终端中键为 WIN+V
; ctrl+alt+G -> WIN+V
^!G::Send #v ; 将 ctrl+alt+G 映射为 WIN+V

把这两个文件设置分别开机启动即可

方法2 通过vmware-kvm.exe配置参数,window主机和vmware共用一个桌面

进入C:\Program Files (x86)\VMware\VMware Workstation,该目录下有vmware-kvm.exe,在该目录下配置vmware-kvm.exe的切换回window的快捷键

 vmware-kvm.exe --preferences

这里我设置的ctrl+alt+x
在这里插入图片描述
把vmware-kvm.exe快捷方式发送到桌面,找到你对应的虚拟机.vmx文件,复制其路径到快捷方式的参数中
例如

"C:\Program Files (x86)\VMware\VMware Workstation\vmware-kvm.exe" "D:\win\Ubuntu20\Ubuntu20.vmx"

在这里插入图片描述
双击这个快捷方式启动虚拟机,使用快捷键就可以方便在win和vm之间切换

方法三 使用hook获取系统底层输入

请参考WinDeskSwitch,真正可以随心所欲切换

#include Lib\AutoHotInterception.ahk

VDA_PATH := "./Lib/VirtualDesktopAccessor.dll"
hVirtualDesktopAccessor := DllCall("LoadLibrary", "Str", VDA_PATH, "Ptr")
GoToDesktopNumberProc := DllCall("GetProcAddress", "Ptr", hVirtualDesktopAccessor, "AStr", "GoToDesktopNumber", "Ptr")
GoToDesktopNumber(num) {
    global GoToDesktopNumberProc
    DllCall(GoToDesktopNumberProc, "Int", num)
}

AHI := new AutoHotInterception()
keyboardId := 1  
AHI.SubscribeKey(keyboardId, GetKeySC("Control"), false, Func("KeyEvent").Bind("ctrl"))
AHI.SubscribeKey(keyboardId, GetKeySC("Alt"), false, Func("KeyEvent").Bind("alt"))
AHI.SubscribeKey(keyboardId, GetKeySC("a"), false, Func("KeyEvent").Bind("a"))
AHI.SubscribeKey(keyboardId, GetKeySC("s"), false, Func("KeyEvent").Bind("s"))
AHI.SubscribeKey(keyboardId, GetKeySC("z"), false, Func("KeyEvent").Bind("z"))

ctrl_state :=  "Released"
alt_state :=  "Released"
a_state :=  "Released"
s_state :=  "Released"
z_state :=  "Released"

KeyEvent(keyName, state) {
    global ctrl_state, alt_state, a_state, s_state, z_state, hLvKeyboard
    Gui, ListView, % hLvKeyboard
    stateText := (state = 1) ? "Pressed" : "Released"

    if (keyName = "ctrl") {
        ctrl_state := stateText
    } else if (keyName = "alt") {
        alt_state := stateText
    } else if (keyName = "a") {
        a_state := stateText
    } else if (keyName = "s") {
        s_state := stateText
    } else if (keyName = "z") {
        z_state := stateText
    }
    
    ; ToolTip, %ctrl_state%   %alt_state%  %a_state%   %s_state%   %z_state%
    if (ctrl_state= "Pressed" && alt_state== "Pressed" ) {
        if(a_state== "Pressed" ){
            GoToDesktopNumber(0)  ; 切换到桌面 1
        }
        else if(s_state== "Pressed" ){
            GoToDesktopNumber(1)  ; 切换到桌面 2
        }
        else if(z_state== "Pressed" ){
            GoToDesktopNumber(2)  ; 切换到桌面 3
        }
    }
}