@echo off setlocal enabledelayedexpansion chcp 65001 >nul REM ======================================== REM 配置文件版本Java Protocol Buffers构建脚本 REM 支持配置文件、命令行参数和灵活路径配置 REM 使用protoc编译器直接生成Java代码 REM ======================================== REM ======================================== REM 配置文件设置 REM ======================================== REM 配置文件路径 - 存储所有配置项的INI格式文件 set CONFIG_FILE=buildjava_config.ini REM ======================================== REM 默认配置值定义 REM ======================================== REM Proto文件输入目录 - 存放.proto文件的源目录 set DEFAULT_PROTO_INPUT_DIR=. REM Java代码输出目录 - 生成的Java文件存放目录 set DEFAULT_JAVA_OUTPUT_DIR=javaprotocol REM Protoc编译器路径 - Protocol Buffers编译器可执行文件路径 set DEFAULT_PROTOC=protoc.exe REM 备份功能开关 - 是否在生成前备份现有Java文件 (true/false) set DEFAULT_BACKUP_ENABLED=true REM 详细输出模式 - 是否显示详细的处理信息 (true/false) set DEFAULT_VERBOSE=false REM 清理输出目录 - 是否在生成前清空输出目录 (true/false) set DEFAULT_CLEAN_OUTPUT=false REM Java项目目录 - 用于将生成的Java文件拷贝到实际项目中的目标目录 set DEFAULT_JAVA_PROJECT_DIR=D:\project\game-framework\game-battle\src\main\java\vip\metadev\module\battle\protobuf REM Proto项目目录 - 用于将proto文件拷贝到独立的目标目录 (如果为空则使用JAVA_PROJECT_DIR/proto) set DEFAULT_PROTO_PROJECT_DIR=D:\project\game-framework\game-battle\src\main\resources\proto REM 拷贝到项目功能 - 是否启用自动拷贝到项目目录功能 (true/false) set DEFAULT_COPY_TO_PROJECT=true REM 包含文件模式 - 指定要处理的proto文件模式,支持通配符 (如: *.proto, battle_*.proto) REM set DEFAULT_INCLUDE_PROTO_FILES=*.proto set DEFAULT_INCLUDE_PROTO_FILES=*.proto REM 排除文件模式 - 指定要排除的proto文件模式,支持通配符 (如: test_*.proto, *_old.proto) set DEFAULT_EXCLUDE_PROTO_FILES= REM 文件匹配模式 - 使用正则表达式进行更精确的文件匹配 (暂不支持,保留扩展性) set DEFAULT_PROTO_FILE_PATTERNS= REM ======================================== REM 配置变量初始化 REM ======================================== REM 将默认值赋给实际使用的配置变量,这些变量会在后续被配置文件或命令行参数覆盖 set PROTO_INPUT_DIR=%DEFAULT_PROTO_INPUT_DIR% set JAVA_OUTPUT_DIR=%DEFAULT_JAVA_OUTPUT_DIR% set PROTOC=%DEFAULT_PROTOC% set BACKUP_ENABLED=%DEFAULT_BACKUP_ENABLED% set VERBOSE=%DEFAULT_VERBOSE% set CLEAN_OUTPUT=%DEFAULT_CLEAN_OUTPUT% set JAVA_PROJECT_DIR=%DEFAULT_JAVA_PROJECT_DIR% set PROTO_PROJECT_DIR=%DEFAULT_PROTO_PROJECT_DIR% set COPY_TO_PROJECT=%DEFAULT_COPY_TO_PROJECT% set INCLUDE_PROTO_FILES=%DEFAULT_INCLUDE_PROTO_FILES% set EXCLUDE_PROTO_FILES=%DEFAULT_EXCLUDE_PROTO_FILES% set PROTO_FILE_PATTERNS=%DEFAULT_PROTO_FILE_PATTERNS% REM ======================================== REM 配置文件加载和参数解析 REM ======================================== REM 检查并加载配置文件 - 如果配置文件存在则加载,否则创建默认配置 if exist "%CONFIG_FILE%" ( echo 📖 加载配置文件: %CONFIG_FILE% call :load_config ) else ( echo 📝 配置文件不存在,创建默认配置... call :create_default_config ) REM 解析命令行参数 - 命令行参数会覆盖配置文件中的设置,提供运行时配置灵活性 call :parse_args echo. echo ======================================== echo 配置文件版本Java Protocol Buffers构建工具 echo ======================================== echo. REM ======================================== REM 配置信息显示 REM ======================================== REM 显示当前配置 - 展示所有配置项的当前值,便于用户确认配置是否正确 echo 📋 当前配置: echo Proto输入目录: %PROTO_INPUT_DIR% echo Java输出目录: %JAVA_OUTPUT_DIR% echo Protoc编译器: %PROTOC% echo 备份功能: %BACKUP_ENABLED% echo 详细模式: %VERBOSE% echo 清理输出: %CLEAN_OUTPUT% echo Java项目目录: %JAVA_PROJECT_DIR% echo Proto项目目录: %PROTO_PROJECT_DIR% echo 拷贝到项目: %COPY_TO_PROJECT% (Java文件 + Proto文件) echo 包含文件模式: %INCLUDE_PROTO_FILES% echo 排除文件模式: %EXCLUDE_PROTO_FILES% echo 文件匹配模式: %PROTO_FILE_PATTERNS% echo ======================================== echo. REM ======================================== REM 环境检查和文件搜索 REM ======================================== REM 检查protoc编译器是否存在 - 验证配置的protoc路径是否有效 if not exist "%PROTOC%" ( echo ❌ 错误: 未找到 %PROTOC% echo 请确保protoc.exe在指定路径中可用 echo. echo 💡 提示: echo 1. 在配置文件中修改PROTOC路径 echo 2. 使用 --protoc 参数指定路径 echo 3. 确保protoc.exe在当前目录或PATH中 echo. pause exit /b 1 ) REM 搜索proto文件 - 根据配置的包含/排除模式查找要处理的文件 echo 🔍 搜索proto文件... set /a proto_count=0 set /a filtered_count=0 REM 调用文件过滤函数 - 应用包含/排除规则,生成最终要处理的文件列表 call :filter_proto_files if %proto_count% equ 0 ( echo ❌ 错误: 在 %PROTO_INPUT_DIR% 目录中未找到.proto文件 echo. echo 请检查: echo 1. 配置文件中的PROTO_INPUT_DIR路径 echo 2. --input 参数路径 echo 3. 该目录下是否有.proto文件 echo. pause exit /b 1 ) echo 📊 找到 %proto_count% 个proto文件 if "%VERBOSE%"=="true" echo. REM ======================================== REM 输出目录管理和备份 REM ======================================== REM 清理输出目录 - 根据配置决定是否在生成前清空现有输出目录 if "%CLEAN_OUTPUT%"=="true" ( if exist "%JAVA_OUTPUT_DIR%" ( echo 🗑️ 清理输出目录: %JAVA_OUTPUT_DIR% rmdir /s /q "%JAVA_OUTPUT_DIR%" 2>nul ) ) REM 创建备份 - 根据配置决定是否备份现有的Java文件,防止意外覆盖 if "%BACKUP_ENABLED%"=="true" ( if not exist "backup" mkdir "backup" set BACKUP_DIR=backup_%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2% set BACKUP_DIR=%BACKUP_DIR: =0% if exist "%JAVA_OUTPUT_DIR%" ( echo 🔄 备份现有输出目录... move "%JAVA_OUTPUT_DIR%" "backup\%BACKUP_DIR%" >nul 2>&1 echo ✅ 已备份到: backup\%BACKUP_DIR% ) ) REM 创建输出目录 - 确保Java代码输出目录存在,为后续生成做准备 mkdir "%JAVA_OUTPUT_DIR%" 2>nul echo ✅ 创建输出目录: %JAVA_OUTPUT_DIR% echo. REM ======================================== REM Java代码生成 REM ======================================== REM 生成Java代码 - 使用protoc编译器将proto文件转换为Java代码 echo 🚀 开始生成Java代码... echo. set /a success_count=0 set /a fail_count=0 REM 调用编译函数 - 根据过滤后的文件列表进行批量编译 call :compile_proto_files echo ======================================== echo 📊 代码生成结果: echo 成功: %success_count% echo 失败: %fail_count% echo ======================================== echo. if %fail_count% gtr 0 ( echo Warning: %fail_count% files failed to process echo Please check proto file syntax and dependencies echo. ) else ( echo All proto files processed successfully! echo. REM ======================================== REM Java文件整理 REM ======================================== REM 将所有Java文件移动到主目录 - protoc可能生成嵌套目录结构,需要整理到统一目录 echo 🔄 整理Java文件到主目录... for /r "%JAVA_OUTPUT_DIR%" %%f in (*.java) do ( if not "%%~dpf"=="%JAVA_OUTPUT_DIR%\" ( move "%%f" "%JAVA_OUTPUT_DIR%\" >nul 2>&1 if !errorlevel! equ 0 ( if "%VERBOSE%"=="true" echo ✅ 移动: %%~nxf ) ) ) REM 删除空的子目录 - 清理protoc生成的空目录,保持输出目录整洁 for /f "delims=" %%d in ('dir "%JAVA_OUTPUT_DIR%" /ad /b 2^>nul') do ( rmdir "%JAVA_OUTPUT_DIR%\%%d" 2>nul ) echo ✅ Java文件整理完成 ) REM 拷贝到Java项目目录(如果启用) if "%COPY_TO_PROJECT%"=="true" ( if not "%JAVA_PROJECT_DIR%"=="" ( echo. echo 🔄 拷贝Java文件到项目目录: %JAVA_PROJECT_DIR% REM 检查目标目录是否存在 if not exist "%JAVA_PROJECT_DIR%" ( echo 📁 创建目标目录: %JAVA_PROJECT_DIR% mkdir "%JAVA_PROJECT_DIR%" 2>nul ) REM 拷贝所有Java文件 set copy_count=0 for %%f in ("%JAVA_OUTPUT_DIR%\*.java") do ( copy "%%f" "%JAVA_PROJECT_DIR%\" >nul 2>&1 if !errorlevel! equ 0 ( set /a copy_count+=1 if "%VERBOSE%"=="true" echo ✅ 拷贝: %%~nxf ) else ( echo ❌ 拷贝失败: %%~nxf ) ) if !copy_count! gtr 0 ( echo ✅ 成功拷贝 !copy_count! 个Java文件到项目目录 ) else ( echo ❌ 没有文件被拷贝 ) REM ======================================== REM Proto文件拷贝 REM ======================================== REM 拷贝对应的proto文件到项目目录 - 便于开发时查看proto定义 echo. echo 🔄 拷贝Proto文件到项目目录... REM 确定proto文件目标目录 if not "%PROTO_PROJECT_DIR%"=="" ( REM 使用独立的proto项目目录 set PROTO_TARGET_DIR=%PROTO_PROJECT_DIR% ) else ( REM 使用Java项目目录下的proto子目录 set PROTO_TARGET_DIR=%JAVA_PROJECT_DIR%\proto ) REM 创建proto文件目标目录 if not exist "!PROTO_TARGET_DIR!" ( echo 📁 创建proto目标目录: !PROTO_TARGET_DIR! mkdir "!PROTO_TARGET_DIR!" 2>nul ) REM 拷贝过滤后的proto文件 set proto_copy_count=0 if defined FILTERED_FILE_LIST ( REM 使用过滤后的文件列表 for /f "delims=" %%f in (!FILTERED_FILE_LIST!) do ( if exist "%PROTO_INPUT_DIR%\%%f" ( copy "%PROTO_INPUT_DIR%\%%f" "!PROTO_TARGET_DIR!\" >nul 2>&1 if !errorlevel! equ 0 ( set /a proto_copy_count+=1 if "%VERBOSE%"=="true" echo ✅ 拷贝proto: %%f ) else ( echo ❌ 拷贝proto失败: %%f ) ) ) ) else ( REM 如果没有过滤,拷贝所有proto文件 for %%f in ("%PROTO_INPUT_DIR%\*.proto") do ( copy "%%f" "!PROTO_TARGET_DIR!\" >nul 2>&1 if !errorlevel! equ 0 ( set /a proto_copy_count+=1 if "%VERBOSE%"=="true" echo ✅ 拷贝proto: %%~nxf ) else ( echo ❌ 拷贝proto失败: %%~nxf ) ) ) if !proto_copy_count! gtr 0 ( echo ✅ 成功拷贝 !proto_copy_count! 个Proto文件到项目目录 ) else ( echo ❌ 没有Proto文件被拷贝 ) REM 清理临时文件列表(在拷贝完成后) if defined FILTERED_FILE_LIST ( if exist "!FILTERED_FILE_LIST!" del "!FILTERED_FILE_LIST!" >nul 2>&1 ) ) else ( echo ❌ 错误: 拷贝功能已启用但未指定Java项目目录 echo 请在配置文件中设置JAVA_PROJECT_DIR或使用--project参数 ) ) REM 显示生成的Java文件 echo 📁 生成的Java文件: if exist "%JAVA_OUTPUT_DIR%" ( dir /b "%JAVA_OUTPUT_DIR%\*.java" 2>nul if !errorlevel! equ 0 ( echo. echo Total Java files generated in %JAVA_OUTPUT_DIR% directory ) else ( echo No Java files found ) ) else ( echo Output directory does not exist ) echo. echo ======================================== echo 🎯 构建完成! echo ======================================== echo. goto :end REM 加载配置文件 :load_config for /f "tokens=1,2 delims==" %%a in (%CONFIG_FILE%) do ( if "%%a"=="PROTO_INPUT_DIR" set PROTO_INPUT_DIR=%%b if "%%a"=="JAVA_OUTPUT_DIR" set JAVA_OUTPUT_DIR=%%b if "%%a"=="PROTOC" set PROTOC=%%b if "%%a"=="BACKUP_ENABLED" set BACKUP_ENABLED=%%b if "%%a"=="VERBOSE" set VERBOSE=%%b if "%%a"=="CLEAN_OUTPUT" set CLEAN_OUTPUT=%%b if "%%a"=="JAVA_PROJECT_DIR" set JAVA_PROJECT_DIR=%%b if "%%a"=="COPY_TO_PROJECT" set COPY_TO_PROJECT=%%b if "%%a"=="INCLUDE_PROTO_FILES" set INCLUDE_PROTO_FILES=%%b if "%%a"=="EXCLUDE_PROTO_FILES" set EXCLUDE_PROTO_FILES=%%b if "%%a"=="PROTO_FILE_PATTERNS" set PROTO_FILE_PATTERNS=%%b ) goto :eof REM 创建默认配置文件 :create_default_config ( echo # Java Protocol Buffers构建配置文件 echo # 修改以下路径配置您的环境 echo. echo # Proto文件输入目录 echo PROTO_INPUT_DIR=. echo. echo # Java代码输出目录 echo JAVA_OUTPUT_DIR=javaprotocol echo. echo # Protoc编译器路径 echo PROTOC=protoc.exe echo. echo # 是否启用备份功能 (true/false) echo BACKUP_ENABLED=true echo. echo # 是否启用详细输出 (true/false) echo VERBOSE=false echo. echo # 是否清理输出目录 (true/false) echo CLEAN_OUTPUT=false echo. echo # Java项目目录(用于拷贝生成的Java文件) echo JAVA_PROJECT_DIR=%DEFAULT_JAVA_PROJECT_DIR% echo. echo # Proto项目目录(用于拷贝proto文件,如果为空则使用JAVA_PROJECT_DIR/proto) echo PROTO_PROJECT_DIR=%DEFAULT_PROTO_PROJECT_DIR% echo. echo # 是否启用拷贝到项目目录功能 (true/false) echo # 启用后会将Java文件拷贝到JAVA_PROJECT_DIR,proto文件拷贝到PROTO_PROJECT_DIR或JAVA_PROJECT_DIR/proto echo COPY_TO_PROJECT=%DEFAULT_COPY_TO_PROJECT% echo. echo # 包含的proto文件模式 (支持通配符,如: *.proto, battle_*.proto) echo INCLUDE_PROTO_FILES=%DEFAULT_INCLUDE_PROTO_FILES% echo. echo # 排除的proto文件模式 (支持通配符,如: test_*.proto, *_old.proto) echo EXCLUDE_PROTO_FILES=%DEFAULT_EXCLUDE_PROTO_FILES% echo. echo # 正则表达式匹配模式 (暂不支持,请使用包含/排除模式) echo PROTO_FILE_PATTERNS=%DEFAULT_PROTO_FILE_PATTERNS% ) > "%CONFIG_FILE%" echo ✅ 已创建默认配置文件: %CONFIG_FILE% echo 💡 请根据需要修改配置文件中的路径设置 echo. goto :eof REM 解析命令行参数 :parse_args :parse_loop if "%1"=="" goto :eof if "%1"=="--input" ( set PROTO_INPUT_DIR=%2 shift shift goto :parse_loop ) if "%1"=="--output" ( set JAVA_OUTPUT_DIR=%2 shift shift goto :parse_loop ) if "%1"=="--protoc" ( set PROTOC=%2 shift shift goto :parse_loop ) if "%1"=="--no-backup" ( set BACKUP_ENABLED=false shift goto :parse_loop ) if "%1"=="--verbose" ( set VERBOSE=true shift goto :parse_loop ) if "%1"=="--clean" ( set CLEAN_OUTPUT=true shift goto :parse_loop ) if "%1"=="--project" ( set JAVA_PROJECT_DIR=%2 set COPY_TO_PROJECT=true shift shift goto :parse_loop ) if "%1"=="--proto-project" ( set PROTO_PROJECT_DIR=%2 set COPY_TO_PROJECT=true shift shift goto :parse_loop ) if "%1"=="--copy" ( set COPY_TO_PROJECT=true shift goto :parse_loop ) if "%1"=="--include" ( set INCLUDE_PROTO_FILES=%2 shift shift goto :parse_loop ) if "%1"=="--exclude" ( set EXCLUDE_PROTO_FILES=%2 shift goto :parse_loop ) if "%1"=="--pattern" ( set PROTO_FILE_PATTERNS=%2 shift shift goto :parse_loop ) if "%1"=="--help" ( goto :show_help ) if "%1"=="-h" ( goto :show_help ) if "%1"=="--config" ( echo 📖 重新加载配置文件... call :load_config shift goto :parse_loop ) shift goto :parse_loop REM 显示帮助信息 :show_help echo. echo ======================================== echo 使用帮助 echo ======================================== echo. echo 用法: buildjava.bat [选项] echo. echo 选项: echo --input DIR 指定proto文件输入目录 echo --output DIR 指定Java代码输出目录 echo --protoc PATH 指定protoc.exe路径 echo --no-backup 禁用备份功能 echo --verbose 启用详细输出模式 echo --clean 清理输出目录 echo --project DIR 指定Java项目目录并启用拷贝功能 echo --proto-project DIR 指定Proto文件项目目录(独立于Java项目目录) echo --copy 启用拷贝到项目目录功能(Java文件+Proto文件) echo --include PAT 指定包含的proto文件模式 (如: *.proto, battle_*.proto) echo --exclude PAT 指定排除的proto文件模式 (如: test_*.proto, *_old.proto) echo --pattern REGEX 指定正则表达式匹配模式 echo --config 重新加载配置文件 echo --help, -h 显示此帮助信息 echo. echo 配置文件: %CONFIG_FILE% echo 配置文件优先级低于命令行参数 echo. echo 示例: echo buildjava.bat --input proto --output java echo buildjava.bat --protoc "C:\protobuf\bin\protoc.exe" echo buildjava.bat --no-backup --verbose --verbose --clean echo buildjava.bat --project "C:\MyJavaProject\src\main\java" echo buildjava.bat --copy --project "D:\workspace\MyApp\src" echo buildjava.bat --proto-project "D:\workspace\MyApp\proto" --project "D:\workspace\MyApp\src" echo REM 将生成Java文件到javaprotocol目录,并拷贝到项目目录 echo REM 同时将proto文件拷贝到指定的proto项目目录(如果未指定则使用项目目录的proto子目录) echo buildjava.bat --include "battle_*.proto" --exclude "test_*.proto" echo buildjava.bat --pattern ".*battle.*\.proto" --verbose echo. echo ======================================== echo. pause exit /b 0 REM 文件过滤函数 :filter_proto_files set /a proto_count=0 set /a filtered_count=0 REM 创建临时文件列表 set TEMP_FILE_LIST=%TEMP%\proto_files_%random%.txt if exist "%TEMP_FILE_LIST%" del "%TEMP_FILE_LIST%" REM 首先收集所有proto文件 for %%f in ("%PROTO_INPUT_DIR%\*.proto") do ( set /a proto_count+=1 echo %%~nxf>> "%TEMP_FILE_LIST%" if "%VERBOSE%"=="true" ( echo 📄 发现: %%~nxf ) ) if %proto_count% equ 0 ( echo ❌ 未找到任何proto文件 goto :eof ) echo 📊 找到 %proto_count% 个proto文件 REM 应用包含模式过滤 if not "%INCLUDE_PROTO_FILES%"=="*.proto" ( echo 🔍 应用包含模式: %INCLUDE_PROTO_FILES% set TEMP_FILTERED=%TEMP%\proto_filtered_%random%.txt if exist "%TEMP_FILTERED%" del "%TEMP_FILTERED%" for /f "delims=" %%f in (%TEMP_FILE_LIST%) do ( set filename=%%f set matched=false REM 检查是否匹配包含模式 for %%p in (%INCLUDE_PROTO_FILES%) do ( if "!filename!"=="%%p" ( set matched=true goto :include_check_done ) if "%%p"=="*.proto" ( set matched=true goto :include_check_done ) if "%%p:~-6%"=="*.proto" ( set prefix=%%p:~0,-6% if "!filename:~0,%%p:~-6%!"=="!prefix!" ( set matched=true goto :include_check_done ) ) ) :include_check_done if "!matched!"=="true" ( echo !filename!>> "%TEMP_FILTERED%" ) ) if exist "%TEMP_FILTERED%" ( move "%TEMP_FILTERED%" "%TEMP_FILE_LIST%" >nul ) ) REM 应用排除模式过滤 if not "%EXCLUDE_PROTO_FILES%"=="" ( echo 🚫 应用排除模式: %EXCLUDE_PROTO_FILES% set TEMP_FILTERED=%TEMP%\proto_filtered_%random%.txt if exist "%TEMP_FILTERED%" del "%TEMP_FILTERED%" for /f "delims=" %%f in (%TEMP_FILE_LIST%) do ( set filename=%%f set excluded=false REM 检查是否匹配排除模式 for %%p in (%EXCLUDE_PROTO_FILES%) do ( if "!filename!"=="%%p" ( set excluded=true goto :exclude_check_done ) if "%%p"=="*.proto" ( set excluded=true goto :exclude_check_done ) if "%%p:~-6%"=="*.proto" ( set prefix=%%p:~0,-6% if "!filename:~0,%%p:~-6%!"=="!prefix!" ( set excluded=true goto :exclude_check_done ) ) ) :exclude_check_done if "!excluded!"=="false" ( echo !filename!>> "%TEMP_FILTERED%" ) ) if exist "%TEMP_FILTERED%" ( move "%TEMP_FILTERED%" "%TEMP_FILE_LIST%" >nul ) ) REM 应用正则表达式模式过滤 if not "%PROTO_FILE_PATTERNS%"=="" ( echo 🔍 应用正则表达式模式: %PROTO_FILE_PATTERNS% REM 注意:Windows批处理不支持正则表达式,这里只是占位符 REM 实际实现需要PowerShell或其他工具 echo ⚠️ 正则表达式模式暂不支持,请使用包含/排除模式 ) REM 统计过滤后的文件数量 set /a filtered_count=0 for /f "delims=" %%f in (%TEMP_FILE_LIST%) do ( set /a filtered_count+=1 ) echo 📊 过滤后剩余 %filtered_count% 个proto文件 echo. REM 保存过滤后的文件列表供编译使用 set FILTERED_FILE_LIST=%TEMP_FILE_LIST% goto :eof REM 编译proto文件函数 :compile_proto_files if not defined FILTERED_FILE_LIST ( REM 如果没有过滤,使用所有proto文件 for %%f in ("%PROTO_INPUT_DIR%\*.proto") do ( call :compile_single_proto "%%f" ) ) else ( REM 使用过滤后的文件列表 for /f "delims=" %%f in (%FILTERED_FILE_LIST%) do ( call :compile_single_proto "%PROTO_INPUT_DIR%\%%f" ) REM 注意:临时文件在proto文件拷贝完成后才删除,避免拷贝时找不到文件列表 ) goto :eof REM 编译单个proto文件 :compile_single_proto set proto_file=%~1 set proto_name=%~nx1 if "%VERBOSE%"=="true" ( echo 📝 处理: !proto_name! ) else ( echo 📝 处理: !proto_name! ) REM 使用protoc.exe生成Java代码 "%PROTOC%" --java_out="%JAVA_OUTPUT_DIR%" "!proto_file!" if !errorlevel! equ 0 ( set /a success_count+=1 if "%VERBOSE%"=="true" ( echo ✅ 成功处理: !proto_name! ) ) else ( set /a fail_count+=1 echo ❌ 处理失败: !proto_name! (错误代码: !errorlevel!) ) if "%VERBOSE%"=="true" echo. goto :eof :end pause