使用Python快速啟動多個PC客戶端

作為一枚游戲測試抵拘,日常工作的時候,經(jīng)常需要同時開著多個游戲賬號進行測試述呐。

以Unity打包出來的PC客戶端為例馏谨,每次都需要雙擊運行exe程序,等著游戲啟動后物舒,因為同時開著多個客戶端,所以還需要拖動客戶端,來調(diào)整游戲在屏幕上的位置闻牡,防止遮擋,方便查看绳矩。

操作流程差不多就像這樣子(本文用記事本來替代游戲客戶端):

這個操作其實還是挺繁瑣的罩润,尤其你開了3個以上客戶端的時候,能不能將上邊的操作做成工具來自動完成呢翼馆?

首先我們分析下這個操作的流程

那接下來用Python各個擊破吧~

啟動游戲

啟動游戲只需要一句代碼~

subprocess.Popen(r"C:\Windows\system32\notepad.exe")

subprocess是Python自帶的子進程管理模塊割以,定義有數(shù)個創(chuàng)建子進程的函數(shù),也提供了一些管理標準流(standard stream)和管道(pipe)的工具应媚,從而在進程間使用文本通信严沥。簡單理解就是,通過CMD敲的命令中姜,都基本可以用subprocess來實現(xiàn)批量處理消玄。

計算客戶端的坐標位置

基本思路:

  • 確認游戲的窗口大小,如800*450
  • 計算整個屏幕大小丢胚,可以放多少個800*450的客戶端翩瓜,并計算出每個客戶端的坐標位置

如何獲取屏幕大小呢?Python在Windows平臺有一個庫叫pywin32携龟,它為Python提供訪問Windows API的擴展兔跌,提供了齊全的Windows常量、接口峡蟋、線程以及COM機制等坟桅。

安裝pywin32相满,在sourceforge下載對于你電腦Py版本的exe安裝包,直接運行即可桦卒。

pywin32提供了一個方法win32gui.GetClientRect立美,可以獲取窗口坐標及大小,只需要將桌面窗口句柄作為參數(shù)傳進去即可方灾。

所以獲取桌面分辨率的方式就是:

_, _, width, height = win32gui.GetClientRect(win32gui.GetDesktopWindow())

接下來就是計算在桌面上建蹄,可以擺放多少個游戲客戶端了,就像下圖這個樣子裕偿。

這個不復雜洞慎,就直接上代碼了,計算出桌面可以擺放的客戶端的左上角坐標嘿棘,保存到一個列表里邊備用

game_width = 450
game_height = 800

_, _, width, height = win32gui.GetClientRect(win32gui.GetDesktopWindow())

x_num = int(width / game_width)
y_num = int(height / game_height)

result = list()

for y in range(y_num):
    for x in range(x_num):
        result.append((x * game_width, y * game_height, game_width, game_height))

print(result)

output: [(0, 0, 450, 800), (450, 0, 450, 800), (900, 0, 450, 800), (1350, 0, 450, 800)]

調(diào)整窗口大小并拖動到指定位置


win32gui.MoveWindow(hwnd, x, y, width, height, bRepaint) 提供了一個移動窗口的方式劲腿,函數(shù)的幾個參數(shù)分別表示句柄,起始點x坐標鸟妙,y坐標焦人,寬度,高度重父,是否重繪界面花椭。

app_pid = subprocess.Popen(r"C:\Windows\system32\notepad.exe").pid  # 獲取進程pid
time.sleep(1)
hwnd_list = []
win32gui.EnumWindows(lambda _hwnd, _hwnd_list: _hwnd_list.append(_hwnd), hwnd_list)  # 獲取當前全部的窗口句柄
app_hwnd = None
for hwnd in hwnd_list:
    hid, pid = win32process.GetWindowThreadProcessId(hwnd)  # 根據(jù)窗口句柄取出窗口的hid和pid
    if pid == app_pid:
        app_hwnd = hwnd
        break
if not app_hwnd:
    raise Exception("沒有找到hwnd")

app_position = result.pop(0)
win32gui.MoveWindow(app_hwnd, *app_position, True)  # 移動窗口位置

再封裝下


import win32gui
import win32process
import subprocess
import time


def calculate_app_positions(app_width, app_height, scale):
    _, _, width, height = win32gui.GetClientRect(win32gui.GetDesktopWindow())
    final_app_width = int(app_width * scale)
    final_app_height = int(app_height * scale)
    x_num = int(width / final_app_width)
    y_num = int(height / final_app_height)

    positions = list()

    for y in range(y_num):
        for x in range(x_num):
            positions.append((x * final_app_width, y * final_app_height, final_app_width, final_app_height))
    return positions


def start_app(app_path, num, app_width, app_height, scale):
    app_positions = calculate_app_positions(app_width, app_height, scale)
    for i in range(num):
        app_pid = subprocess.Popen(app_path).pid  # 獲取進程pid
        time.sleep(1)
        hwnd_list = []
        win32gui.EnumWindows(lambda _hwnd, _hwnd_list: _hwnd_list.append(_hwnd), hwnd_list)  # 獲取當前全部的窗口句柄
        app_hwnd = None
        for hwnd in hwnd_list:
            hid, pid = win32process.GetWindowThreadProcessId(hwnd)  # 根據(jù)窗口句柄取出窗口的hid和pid
            if pid == app_pid:
                app_hwnd = hwnd
                break
        if not app_hwnd:
            raise Exception("沒有找到hwnd")

        app_position = app_positions.pop(0)
        win32gui.MoveWindow(app_hwnd, *app_position, True)  # 移動窗口位置


if __name__ == '__main__':

    app_path = r"C:\Windows\system32\notepad.exe"
    app_width = 450
    app_height = 800

    result = input("輸入要打開的客戶端數(shù)量和顯示比例,默認比例是1.0房午,例子:3 0.75\n")
    result = result.split()
    if len(result) == 2:
        num, scale = result
    else:
        num = result[0]
        scale = 1
    start_app(app_path, int(num), app_width, app_height, float(scale))

最終運行效果~

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矿辽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子郭厌,更是在濱河造成了極大的恐慌袋倔,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件折柠,死亡現(xiàn)場離奇詭異宾娜,居然都是意外死亡,警方通過查閱死者的電腦和手機液走,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門碳默,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缘眶,你說我怎么就攤上這事嘱根。” “怎么了巷懈?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵该抒,是天一觀的道長。 經(jīng)常有香客問我顶燕,道長凑保,這世上最難降的妖魔是什么冈爹? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮欧引,結果婚禮上频伤,老公的妹妹穿的比我還像新娘。我一直安慰自己芝此,他們只是感情好憋肖,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著婚苹,像睡著了一般岸更。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上膊升,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天怎炊,我揣著相機與錄音,去河邊找鬼廓译。 笑死评肆,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的责循。 我是一名探鬼主播糟港,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼院仿!你這毒婦竟也來了?” 一聲冷哼從身側響起速和,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤歹垫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后颠放,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體排惨,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年碰凶,在試婚紗的時候發(fā)現(xiàn)自己被綠了暮芭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡欲低,死狀恐怖辕宏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情砾莱,我是刑警寧澤瑞筐,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站腊瑟,受9級特大地震影響聚假,放射性物質(zhì)發(fā)生泄漏块蚌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一膘格、第九天 我趴在偏房一處隱蔽的房頂上張望峭范。 院中可真熱鬧,春花似錦瘪贱、人聲如沸纱控。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽其徙。三九已至,卻和暖如春喷户,著一層夾襖步出監(jiān)牢的瞬間唾那,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工褪尝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留闹获,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓河哑,卻偏偏與公主長得像避诽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子璃谨,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容