雷电模拟器数据备份

本文介绍了一段用于在雷电模拟器中备份和恢复数据的Python脚本,支持指定模拟器操作,包括备份所有设备、单设备备份与还原,以及跨设备的数据迁移。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值