@echo off setlocal EnableExtensions EnableDelayedExpansion set "BACKUP_FULL_PATH=%~1" set "LOCAL_IMPORT_DIR=%~2" set "MUMU_MANAGER_PATH=%~3" set "VM_ID=%~4" set "DEFAULT_NET_BRIDGE_CARD=%~5" set "AHK_EXE=%~6" set "BRIDGE_IP_OFFSET=%~7" set "GATEWAY_RULES=%~8" if not defined BACKUP_FULL_PATH call :fail "BACKUP_FULL_PATH argument is required" if not defined LOCAL_IMPORT_DIR set "LOCAL_IMPORT_DIR=D:\mumu_backups" if not defined MUMU_MANAGER_PATH set "MUMU_MANAGER_PATH=C:\Program Files\Netease\MuMu\nx_main\MuMuManager.exe" if not defined VM_ID set "VM_ID=2" if not defined DEFAULT_NET_BRIDGE_CARD set "DEFAULT_NET_BRIDGE_CARD=Realtek PCIe GbE Family Controller" if not defined AHK_EXE call :fail "AHK_EXE argument is required" if not defined BRIDGE_IP_OFFSET set "BRIDGE_IP_OFFSET=100" if not defined GATEWAY_RULES call :fail "GATEWAY_RULES argument is required, format: 192.168.1=192.168.1.1;192.168.2=192.168.2.1" set "SUBNET_MASK=255.255.255.0" set "DNS1=8.8.8.8" set "DNS2=1.1.1.1" set "POLL_MAX=300" for %%I in ("%BACKUP_FULL_PATH%") do ( set "BACKUP_DIR=%%~dpI" set "BACKUP_FILENAME=%%~nxI" ) if "!BACKUP_DIR:~-1!"=="\" set "BACKUP_DIR=!BACKUP_DIR:~0,-1!" set "IMPORT_FILE=%LOCAL_IMPORT_DIR%\%BACKUP_FILENAME%" set "RESULT_FILE=%LOCAL_IMPORT_DIR%\result.txt" set "AHK_BAT=%LOCAL_IMPORT_DIR%\_run_ahk.bat" echo ================================================== echo Recover MuMu image started echo ================================================== echo [INFO] Backup source: %BACKUP_FULL_PATH% echo [INFO] Local import dir: %LOCAL_IMPORT_DIR% echo [INFO] MuMu manager: %MUMU_MANAGER_PATH% echo [INFO] VM index: %VM_ID% echo [INFO] AHK executable: %AHK_EXE% if not exist "%MUMU_MANAGER_PATH%" call :fail "MuMuManager.exe not found: %MUMU_MANAGER_PATH%" if not exist "%BACKUP_FULL_PATH%" call :fail "Remote backup not found: %BACKUP_FULL_PATH%" if not exist "%LOCAL_IMPORT_DIR%" ( mkdir "%LOCAL_IMPORT_DIR%" if errorlevel 1 call :fail "Failed to create local import dir: %LOCAL_IMPORT_DIR%" ) call :sync_backup if errorlevel 1 exit /b 1 call :run_restore if errorlevel 1 exit /b 1 call :configure_network if errorlevel 1 exit /b 1 echo ================================================== echo MuMu restore and network config completed successfully. echo ================================================== exit /b 0 :sync_backup echo [Phase 1] Check and synchronize backup image set "NEED_COPY_BACKUP=1" set "REMOTE_BACKUP_TIME=" set "LOCAL_BACKUP_TIME=" for %%I in ("%BACKUP_FULL_PATH%") do set "REMOTE_BACKUP_TIME=%%~tI" echo [INFO] Remote backup time = !REMOTE_BACKUP_TIME! if exist "%IMPORT_FILE%" ( for %%I in ("%IMPORT_FILE%") do set "LOCAL_BACKUP_TIME=%%~tI" echo [INFO] Local backup time = !LOCAL_BACKUP_TIME! if /i "!REMOTE_BACKUP_TIME!"=="!LOCAL_BACKUP_TIME!" ( echo [INFO] Backup timestamps match. Skip copying backup file. set "NEED_COPY_BACKUP=0" ) ) else ( echo [INFO] Local backup file not found. A fresh copy is required. ) if "!NEED_COPY_BACKUP!"=="1" ( echo [INFO] Copying backup file from %BACKUP_DIR% to %LOCAL_IMPORT_DIR% ... robocopy "%BACKUP_DIR%" "%LOCAL_IMPORT_DIR%" "%BACKUP_FILENAME%" /R:2 /W:2 /COPY:DAT /DCOPY:T /NFL /NDL /NJH /NJS /NP >nul if !errorlevel! gtr 7 call :fail "Failed to copy backup file to %IMPORT_FILE%" ) exit /b 0 :run_restore echo [Phase 2] Run MuMu restore through RunAHK scheduled task echo [INFO] Shutting down MuMu emulator... "%MUMU_MANAGER_PATH%" control -v %VM_ID% shutdown call :sleep 15 echo [INFO] Killing MuMu-related processes if they are running... call :kill_mumu_processes call :sleep 5 del /f /q "%RESULT_FILE%" >nul 2>&1 ( echo @echo off echo "%AHK_EXE%" "%IMPORT_FILE%" %VM_ID% "%RESULT_FILE%" ) > "%AHK_BAT%" if errorlevel 1 call :fail "Failed to write AHK runner: %AHK_BAT%" schtasks /delete /tn "RunAHK" /f >nul 2>&1 schtasks /create /tn "RunAHK" /tr "%AHK_BAT%" /sc ONCE /st 00:00 /rl HIGHEST /it /f >nul if errorlevel 1 call :fail "Failed to create RunAHK task" schtasks /run /tn "RunAHK" >nul if errorlevel 1 call :fail "Failed to start RunAHK task" echo [INFO] Waiting for restore result file: %RESULT_FILE% for /l %%I in (1,1,%POLL_MAX%) do ( if exist "%RESULT_FILE%" goto :check_restore_result call :sleep 2 ) call :fail "AHK restore timed out" :check_restore_result call :sleep 3 set "RESTORE_RESULT=" set /p RESTORE_RESULT=<"%RESULT_FILE%" echo [INFO] AHK result: !RESTORE_RESULT! echo !RESTORE_RESULT! | findstr /i /c:"OK" >nul if errorlevel 1 call :fail "AHK restore failed: !RESTORE_RESULT!" exit /b 0 :configure_network echo [Phase 3] Configure MuMu network call :detect_network_adapter if errorlevel 1 exit /b 1 call :detect_bridge_network if errorlevel 1 exit /b 1 call :set_mumu_setting net_bridge_card "!NetAdapterName!" if errorlevel 1 exit /b 1 call :set_mumu_setting net_bridge_ip_mode static if errorlevel 1 exit /b 1 call :set_mumu_setting net_bridge_ip_addr "!BRIDGE_IP!" if errorlevel 1 exit /b 1 call :set_mumu_setting net_bridge_gateway "!GATEWAY!" if errorlevel 1 exit /b 1 call :set_mumu_setting net_bridge_subnet_mask %SUBNET_MASK% if errorlevel 1 exit /b 1 call :set_mumu_setting net_bridge_dns1 %DNS1% if errorlevel 1 exit /b 1 call :set_mumu_setting net_bridge_dns2 %DNS2% if errorlevel 1 exit /b 1 echo [INFO] Network configuration completed successfully. exit /b 0 :kill_mumu_processes for %%P in (MuMuPlayer.exe MuMuNxDevice.exe MuMuNxMain.exe MuMuManager.exe) do ( taskkill /F /IM %%P >nul 2>&1 ) exit /b 0 :detect_network_adapter set "NetAdapterName=" for /f "tokens=* skip=1" %%a in ('wmic nic where "NetConnectionStatus=2" get Name /value 2^>nul') do ( if "!NetAdapterName!"=="" ( for /f "tokens=2 delims==" %%b in ("%%a") do set "NetAdapterName=%%b" ) ) if not "!NetAdapterName!"=="" ( for /f "tokens=*" %%a in ("!NetAdapterName!") do set "NetAdapterName=%%a" ) if "!NetAdapterName!"=="" set "NetAdapterName=%DEFAULT_NET_BRIDGE_CARD%" echo [INFO] net_bridge_card = !NetAdapterName! exit /b 0 :detect_bridge_network set "LOCAL_IP=" set "LOCAL_PREFIX=" for /f "tokens=2 delims=:" %%a in ('ipconfig ^| findstr /r /c:"[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*"') do ( if not defined LOCAL_IP ( set "CANDIDATE_IP=%%a" set "CANDIDATE_IP=!CANDIDATE_IP: =!" for /f "tokens=1-4 delims=." %%b in ("!CANDIDATE_IP!") do ( call :find_gateway "%%b.%%c.%%d" if defined GATEWAY ( set "LOCAL_IP=!CANDIDATE_IP!" set "LOCAL_PREFIX=%%b.%%c.%%d" ) ) ) ) if not defined LOCAL_IP call :fail "Failed to detect local IPv4 address matching GATEWAY_RULES: %GATEWAY_RULES%" echo [INFO] Local IP: !LOCAL_IP! set "BRIDGE_IP=" for /f "tokens=1-4 delims=." %%a in ("!LOCAL_IP!") do ( set /a LAST_OCTET=%%d + %BRIDGE_IP_OFFSET% if !LAST_OCTET! gtr 254 call :fail "Local IP last octet is too large for bridge IP derivation" set "BRIDGE_IP=%%a.%%b.%%c.!LAST_OCTET!" ) echo [INFO] net_bridge_ip_addr = !BRIDGE_IP! echo [INFO] net_bridge_gateway = !GATEWAY! exit /b 0 :find_gateway set "GATEWAY=" set "TARGET_PREFIX=%~1" for %%R in ("%GATEWAY_RULES:;=" "%") do ( for /f "tokens=1,* delims==" %%K in ("%%~R") do ( if "%%K"=="!TARGET_PREFIX!" set "GATEWAY=%%L" ) ) exit /b 0 :set_mumu_setting set "SETTING_KEY=%~1" set "SETTING_VALUE=%~2" echo [INFO] !SETTING_KEY! = !SETTING_VALUE! "%MUMU_MANAGER_PATH%" setting -v %VM_ID% -k "!SETTING_KEY!" -val "!SETTING_VALUE!" if errorlevel 1 call :fail "Failed to set !SETTING_KEY!" exit /b 0 :sleep set /a SLEEP_COUNT=%~1 + 1 ping -n !SLEEP_COUNT! 127.0.0.1 >nul exit /b 0 :fail echo. echo [ERROR] %~1 1>&2 echo Recover MuMu aborted. 1>&2 exit 1