From abdaa277f879c8b2b8d64c49afefbe35ee8e0918 Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Mon, 6 Jul 2026 10:11:29 +0800 Subject: [PATCH] feat: add LDPlayer_id property and improve emulator stop logic --- module/device/platform/emulator_base.py | 17 +++++++ module/device/platform/platform_windows.py | 54 +++++++++++----------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/module/device/platform/emulator_base.py b/module/device/platform/emulator_base.py index 394becc..51925e9 100644 --- a/module/device/platform/emulator_base.py +++ b/module/device/platform/emulator_base.py @@ -114,6 +114,23 @@ class EmulatorInstanceBase: return None + @cached_property + def LDPlayer_id(self): + """ + Convert LDPlayer instance name to instance id. + Example names: + leidian0 + leidian1 + + Returns: + int: Instance ID, or None if this is not a LDPlayer instance + """ + res = re.search(r'leidian(\d+)', self.name) + if res: + return int(res.group(1)) + + return None + class EmulatorBase: # Values here must match those in argument.yaml EmulatorInfo.Emulator.option diff --git a/module/device/platform/platform_windows.py b/module/device/platform/platform_windows.py index 1a71c29..d4e38c2 100644 --- a/module/device/platform/platform_windows.py +++ b/module/device/platform/platform_windows.py @@ -1,5 +1,4 @@ import ctypes -import os import re import subprocess @@ -83,7 +82,7 @@ class PlatformWindows(PlatformBase, EmulatorManager): """ Start a emulator without error handling """ - exe = instance.emulator.path + exe: str = instance.emulator.path if instance == Emulator.MuMuPlayer: # NemuPlayer.exe self.execute(exe) @@ -105,13 +104,11 @@ class PlatformWindows(PlatformBase, EmulatorManager): # HD-Player.exe --instance Pie64 self.execute(f'"{exe}" --instance {instance.name}') elif instance == Emulator.BlueStacks4: - # BlueStacks\Client\Bluestacks.exe -vmname Android_1 + # Bluestacks.exe -vmname Android_1 self.execute(f'"{exe}" -vmname {instance.name}') - elif instance == Emulator.LDPlayer9: - directory, filename = os.path.split(exe) - new_filename = 'ldconsole.exe' - exe = os.path.join(directory, new_filename) - self.execute(f'"{exe}" launch --index {instance.name.replace("leidian", "")}') + elif instance == Emulator.MEmuPlayer: + # MEmu.exe MEmu_0 + self.execute(f'"{exe}" {instance.name}') else: raise EmulatorUnknown(f'Cannot start an unknown emulator instance: {instance}') @@ -119,8 +116,7 @@ class PlatformWindows(PlatformBase, EmulatorManager): """ Stop a emulator without error handling """ - logger.hr('Emulator stop', level=2) - exe = instance.emulator.path + exe: str = instance.emulator.path if instance == Emulator.MuMuPlayer: # MuMu6 does not have multi instance, kill one means kill all # Has 4 processes @@ -166,26 +162,19 @@ class PlatformWindows(PlatformBase, EmulatorManager): # C:\Program Files\BlueStacks_nxt_cn\BstkSVC.exe -Embedding self.kill_process_by_regex( rf'(' - rf'MuMuVMMHeadless.exe.*--comment {instance.name}' - rf'|MuMuPlayer.exe.*-v {instance.MuMuPlayer12_id}' + rf'HD-Player.exe.*"--instance" "{instance.name}"' rf')' ) - # There is also a shared service, no need to kill it - # "C:\Program Files\MuMuVMMVbox\Hypervisor\MuMuVMMSVC.exe" --Embedding - elif instance == Emulator.NoxPlayerFamily: - # Nox.exe -clone:Nox_1 -quit - self.execute(f'"{exe}" -clone:{instance.name} -quit') - elif instance == Emulator.BlueStacks5: - self.execute(f'taskkill /fi "WINDOWTITLE eq {instance.name}" /IM "HD-Player.exe" /F') - elif instance == Emulator.LDPlayer9: - directory, filename = os.path.split(exe) - new_filename = 'ldconsole.exe' - exe = os.path.join(directory, new_filename) - self.execute(f'"{exe}" quit --index {instance.name.replace("leidian", "")}') + elif instance == Emulator.BlueStacks4: + # E:\Program Files (x86)\BluestacksCN\bsconsole.exe quit --name Android + self.execute(f'"{Emulator.single_to_console(exe)}" quit --name {instance.name}') + elif instance == Emulator.MEmuPlayer: + # F:\Program Files\Microvirt\MEmu\memuc.exe stop -n MEmu_0 + self.execute(f'"{Emulator.single_to_console(exe)}" stop -n {instance.name}') else: raise EmulatorUnknown(f'Cannot stop an unknown emulator instance: {instance}') - def _emulator_function_wrapper(self, func): + def _emulator_function_wrapper(self, func: callable): """ Args: func (callable): _emulator_start or _emulator_stop @@ -337,7 +326,20 @@ class PlatformWindows(PlatformBase, EmulatorManager): def emulator_stop(self): logger.hr('Emulator stop', level=1) - return self._emulator_function_wrapper(self._emulator_stop) + for _ in range(3): + # Stop + if self._emulator_function_wrapper(self._emulator_stop): + # Success + return True + else: + # Failed to stop, start and stop again + if self._emulator_function_wrapper(self._emulator_start): + continue + else: + return False + + logger.error('Failed to stop emulator 3 times, stopped') + return False if __name__ == '__main__':