批处理批量编译java源文件,并有条件的自动执行

效果图:

批处理批量编译java源文件,并有条件的自动执行_第1张图片

背景:最近在学习反编译android apk, 有想从反编译出来的java文件着手。但显然,先不说别个引用的各种包,即使只引用了android.jar 要想从.java正常编译回去

也不太容易,还是改smali代码实际些。。。。探索的这过程中产生了这么一个批处理文件,算是自娱自乐,毕竟我也不是吃专业饭的..


注意:代码中的echo出的横线“--”符号在这里删减了一些,不然网页上显示很乱,要像图上那样的话,保证每行输出字符80个就成,因为窗口大小我设置的是80列


使用:复制下代码保存为.bat格式,先双击运行一次,这时在针对“目录”的右键菜单里会多出一项 “Compile-Multi-Javas” 。

只需在需要编译的的java源 文件夹 上右键选择 “Compile-Multi-Javas” 或将文件夹拖到.bat 文件上 即可编译(不论文件夹里的java文件是否按照 包名.ClassName存放 都可以编译,实质就是  javac -d )



::Copyright <span>©</span> [email protected]


@echo off
title 批量编译java文件
mode con cols=80 lines=33 & color 52
set %~1=%1%2%3%4%5%6%7%8%9%*

::下面几个变量,还没应用,主要是想顾及名称带空格的文件夹
::name only
set inputFolderNameOnly="%~n1"
::equals %~1
set inputFolderNameFull="%~f1"
::where the folder stays
set inputFoldersParent="%~dp1"


::下面这几步考虑了空格,但就这个批处理来说,不支持含空格的目录
if %inputFolderNameFull%=="" echo USAGE:%~n0 [A Folder] & echo "No Directory Input" & goto end
if not exist %inputFolderNameFull% echo USAGE:%~n0 [A Folder] & echo "No Directory Found" & goto end
pushd "%~dp1."
for /f "usebackq tokens=1 delims=" %%t in (`dir /AD /B`) do (
if /I "%~n1"=="%%t" popd & goto start
)
echo "Not Directory" & popd & goto end 


::查找java源文件,并保存列表
:start
cd /d "%~dp1"
::Create @source java files list
set manifest=%~n0_manifest.txt
if exist %~dp1%manifest% (
del %~dp1%manifest% 
)
for /r %~f1 %%i in (*.java) do (
echo %%i
if "%%i" NEQ "" echo %%i >> %~dp1%manifest%
)
ping /n 1.5 127.0.0.1 > nul
if not exist %manifest% echo "No Java File exists!" & goto failed


::查找javac.exe
cls
call :findJavaCOrJavaExe "javac.exe"

::创建class输出文件夹
set /a count=0
set tmp=%~f1%-Classfiles
set classdest=%tmp%-%count%
:createFolder
if exist %classdest% (
set /a count+=1
set classdest=%tmp%-%count%
goto createFolder
) else (
mkdir %classdest% 
)

::set classpath
set classpath=%classpath%^;%~f1^
::其实主要就是调用java.exe罢了...
javac -source 1.7 -target 1.7^
 -nowarn -verbose -sourcepath %~f1^
  -cp "<span id="transmark"></span>%classpath%" -d %classdest% @%~dp1%manifest%
::test if it is successed
goto answer%ERRORLEVEL%
:answer2
goto failed
:answer1
goto failed
:answer0
ping /n 1 127.0.0.1 > nul
goto success

:success
cls
echo ----------------
echo 【编译成功】
echo Congratulation!
echo 文件生成于:
echo %classdest%
goto findmain

:failed
echo.
echo 【编译失败!】
if exist %classdest% echo 删除文件夹(组) -- %classdest% && rd /q /s %classdest% > nul & goto delete_temp_file

:delete_temp_file
if exist %manifest% (
echo 删除临时文件1 -- %manifest%...
del /Q/S %manifest% > nul
)

:end
::检测注册表,第一次运行完后,删掉为好,不然每次运行都会检测注册表,运行会有点慢
call :checkReg
echo ------------------------------------
echo            【程序结束】
set /p a=------剩余 5 秒自动退出---------<nul
for /L %%i in (4,-1,0) do (
ping /n 2 127.0.0.1 >nul
::下面b的值是个特殊符号“退格键”,网页显示不了
::按Win+R,输入edit,按Ctrl+p进入特殊控制键符号的输入
::输完可保存到记事本里,在在windows下打开复制即可
for /L %%x in (1,1,100) do set /p b=<nul
set /p a=------剩余 %%i 秒自动退出--------<nul
)
exit

::查找main函数
:findmain
set mainInJavaFile=
for /f "usebackq tokens=1 delims=" %%i in (`findstr /s /m /R /C:" *main(String\[\]" %~f1\*.java`) do (
set mainInJavaFile=%%i && goto getout || goto err
)

:getout
echo.
echo 【搜索main()所在源】
echo %mainInJavaFile%
echo.
call :findJavaCOrJavaExe "java.exe"
call :excuteClass %mainInJavaFile%
goto delete_temp_file
:err
echo 查找出错,不自动执行class....
goto delete_temp_file
::
::
::-------------执行含main()的class文件-------------
:excuteClass
::依据java文件名搜索对应class文件
set main_class_file=%~n1.class
set main_class_file_full=
for /r %classdest% %%c in (%main_class_file%) do (
if exist %%c set main_class_file_full=%%~c && goto excute || echo Error occurs!
)
if not defined %main_class_file_full% echo 未找到含main() class & goto :EOF
:excute
echo 【找到待执行class文件】 & echo %main_class_file_full% & echo.
set final_class_file=%main_class_file_full%
set package_and_file_name=
set get_fore_dir=%classdest%\


::提取包名+文件名(不含扩展名.class)
::将字串中的前部分字串-即当前工作目录字串用空字串替换掉
::然后截取0,-5  即截取.class之前的部分
setlocal enabledelayedexpansion
set count=1
:get_package_loop
set get_fore_dir=!get_fore_dir:~0,-1!
set package_and_file_name=!final_class_file:~%count%!
set /a count+=1
::echo !package_and_file_name!
if "!get_fore_dir!" NEQ "" goto get_package_loop
::echo 取完了,测试
set file_name=%package_and_file_name:\=.%
set file_name=%file_name:~0,-7%
echo 【获得包名+ClassName】
echo %file_name%
echo.
set /p aa=开始执行^>^><nul
for /L %%i in (1,1,35) do ping /n 0 127.0.0.1>nul & set /p a=^>^><nul
echo.
echo 结果:
echo.
set classpath=%classdest%;%classpath%
java -cp %classpath% %file_name% || echo Error! && goto :eof
echo.
echo ^>^>^>^>执行完毕^<^<^<^< & pause >nul
echo.
goto :EOF

::查找java.exe javac.exe
:findJavaCOrJavaExe
for /f "delims=" %%i in (%1) do (
if exist %%~$Path:i echo 【找到java.exe】 & echo %%~$Path:i & echo. && goto :eof
)
cls
echo 环境变量或未配置jdk--找不到文件 %~1
pause
exit
::
::注册表操作
:checkReg
setlocal enabledelayedexpansion
set command="%~f0" "%%1"
goto check

:add
reg add "HKLM\SOFTWARE\Classes\Directory\shell\Compile-Multi-Javas" /d Compile-Multi-Javas /f
reg add "HKLM\SOFTWARE\Classes\Directory\shell\Compile-Multi-Javas\command" /t REG_EXPAND_SZ /d "%command%" /f
goto :eof

:check
reg query HKLM\SOFTWARE\Classes\Directory\shell\Compile-Multi-Javas\command | set /p isexist=
if "!isexist!" NEQ "0" goto add
for /f "usebackq skip=1 tokens=2 delims=^"" %%i in (`REG query HKLM\SOFTWARE\Classes\Directory\shell\Compile-Multi-Javas\command /f %~f0 /d /t REG_EXPAND_SZ`) do (
set isKeyexist=%%i
if "%isKeyexist%" NEQ "%~f0" goto add
)
goto :eof


我是得有多闲..

你可能感兴趣的:(windows,shell,批处理,批处理文件)