import subprocess
import glob
import time
import os
import shutil
from pathlib import Path
# (要改1)模拟器文件共享路径
BACKUP_DIR = r"C:\Users\Administrator\Documents\XuanZhi64\Pictures"
# (要改2)模拟器安装路径
LD_DIR = r"D:\LDPlayer\LDPlayer64"
VMS_CONFIG_DIR = LD_DIR + r"\vms\config"
BACKUP_CMD = "cd /data && tar -zhpcf /sdcard/Pictures/{}_data.tar.gz . --exclude=local --exclude=app " \
"--exclude=user_de/0/com.google.android.tts --exclude=dalvik-cache --exclude=tombstones " \
"--exclude=system_de/0/ringtones --exclude=misc --exclude=app-lib --exclude=media --exclude=ota " \
"--exclude=property --exclude=adb --exclude=anr --exclude=app-asec;exit\n "
ROLLBACK_CMD = "cd /data && tar -zxf /sdcard/Pictures/{}_data.tar.gz;exit\n"
# PULL_FILE_TEMPLATE = 'ldconsole.exe adb --index {} --command "pull /sdcard/data.tar.gz {}"'
# PUSH_FILE_TEMPLATE = 'ldconsole.exe adb --index {} --command "push {} /sdcard/data.tar.gz"'
# def ensure_dir(p):
# b = Path(p)
# if not b.exists():
# b.mkdir()
# return b
os.chdir(LD_DIR)
# ensure_dir(BACKUP_DIR)
ba = glob.glob(f"{VMS_CONFIG_DIR}\\leidian[0-9]*.config")
ld_count = len(ba)
def backup(dst_ld_index, is_rollback=False, rollback_from_other_index=None):
rollback_index = dst_ld_index
if is_rollback and isinstance(rollback_from_other_index, int):
rollback_index = rollback_from_other_index
backup_config_path = f"{BACKUP_DIR}/{rollback_index}.config"
backup_datagz_path = f"{BACKUP_DIR}/{rollback_index}_data.tar.gz"
if is_rollback:
if not Path(backup_config_path).exists() or not Path(backup_datagz_path).exists():
print("恢复到模拟器失败,先备份再进行还原")
return -2
p = subprocess.Popen(f"ld -s {dst_ld_index}", shell=True, universal_newlines=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
time.sleep(1)
# not found emulator
if isinstance(p.poll(), int) and p.poll() > 0:
return p.poll()
if p.poll() is None:
# BACKUP_CMD = "echo 11 && exit\n"
if not is_rollback:
p.stdin.write(BACKUP_CMD.format(dst_ld_index))
else:
p.stdin.write(ROLLBACK_CMD.format(rollback_index))
p.stdin.flush()
wait_count = 0
start = time.time()
while p.poll() is None:
wait_count += 1
time.sleep(1)
if wait_count > 3:
print("备份超时 > {}s".format(wait_count))
break
end = time.time()
print("备份完成,耗时{}秒".format(int(end - start)))
if not is_rollback:
shutil.copyfile(f"{VMS_CONFIG_DIR}/leidian{dst_ld_index}.config", backup_config_path)
else:
for i in range(5):
time.sleep(10)
test(dst_ld_index, rollback_index)
# if p.poll() == 0:
# copy file
# pull_cmd = PULL_FILE_TEMPLATE.format(ld_index, f"{BACKUP_DIR}/{ld_index}.tar.gz")
# ret_code = subprocess.check_call(pull_cmd, shell=True, stderr=subprocess.PIPE)
return p.poll()
return -1
def test(dst_ld_index,rollback_index):
# dst_ld_index = 12
# rollback_index = 2
subprocess.check_call(f"ldconsole.exe quit --index {dst_ld_index}", shell=True, stderr=subprocess.PIPE)
time.sleep(10)
backup_config_path = f"{BACKUP_DIR}/{rollback_index}.config"
shutil.copyfile(backup_config_path, f"{VMS_CONFIG_DIR}/leidian{dst_ld_index}.config")
subprocess.check_call(f"ldconsole.exe launch --index {dst_ld_index}", shell=True,
stderr=subprocess.PIPE)
print(dst_ld_index, rollback_index)
def shell_mode():
tips = f"""
雷电模拟器数据备份工具 1.0 ### (当前扫描到{ld_count}个模拟器)
{", ".join([str(i) for i in range(ld_count)])}
使用方法:
1. 输入b11 备份11号模拟器
2. 输入h11 从11号模拟器数据还原到11号模拟器数据
3. 输入h11-2 从 2号模拟器数据还原到11号模拟器数据
4. 输入ba 备份所有模拟器
5. 输出ha 还原所有模拟器
"""
print(tips)
while True:
cmd = input("\n>> 输入下一步操作指令\n")
ret = -16
if cmd == "ba":
print("开始备份所有模拟器")
for i in range(ld_count):
ret = backup(i)
print(f"备份模拟器{i},返回码:{ret} (0是正常)")
continue
elif cmd == "ha":
print("开始还原所有模拟器")
for i in range(ld_count):
ret = backup(i, is_rollback=True)
print(f"还原模拟器{i},返回码:{ret} (0是正常)")
continue
elif "h" in cmd and "-" in cmd:
ld_index = int(cmd.split("-")[0][1:])
rollback_from_index = int(cmd.split("-")[1])
print(f"还原模拟器{ld_index}, 数据来源:{rollback_from_index}")
ret = backup(ld_index, True, rollback_from_index)
elif "h" in cmd:
ld_index = int(cmd[1:])
print(f"还原模拟器{ld_index}")
ret = backup(ld_index, True)
elif "b" in cmd:
ld_index = int(cmd[1:])
print(f"备份模拟器{ld_index}")
ret = backup(ld_index)
else:
print("执行代码指令:" + cmd)
eval(cmd)
continue
print(f"执行完成, 返回码:{ret} (0是正常)")
if __name__ == "__main__":
shell_mode()
雷电模拟器数据备份
最新推荐文章于 2025-02-25 15:48:07 发布