Bootstrap

bat批处理与adb命令的配合

和安卓系统打交道,难免用到adb命令;和很多安卓硬件打交道,就要大量用到adb命令,如果一个一个写就太累了,在windows系统下还是借助批处理吧。

adb命令基础

首先需要准备的一些adb命令:

  • 查看当前连接的安卓设备
adb devices
  • 连接某个远程安卓设备
adb connect [host]:5555
  • 为某安卓设备安装某个应用
adb -s [device] install -r -t [app_file_path]
  • 为某安卓设备卸载某个应用
adb -s [device] uninstall [app_package_name]
  • 为某安卓设备启动某个应用
adb -s [device] shell am start -n [app_component_name]
  • 为某安卓设备停止某个应用
adb -s [device] shell am force-stop [app_package_name]
  • 为某安卓设备清除某应用数据
adb -s [device] shell pm clear [app_package_name]
名目含义
[host]代表局域网内的IP,如192.168.1.101
[device]代表设备的识别码,真机或模拟器会是设备的IEM或mac,远程设备会是192.168.1.101:5555形式
[app_file_path]apk文件所在路径,如C:/test.apk
[app_package_name]应用的包名,某种意义上说也是applicationId,如com.example.testapp
[app_component_name]应用的launcher,一般为com.example.testapp/com.example.testapp.MainActivity形式,即【包名/launcher类名】形式,包名与applicationId相同时,可省略,写成com.example.testapp/.MainActivity
bat批处理基础

这一部分算是了解windows的DOS命令,以上的adb命令算是外来的,windows内置了一些比较有用的命令,利用他们可以如编程一样写出一个脚本用以处理逻辑:

dos命令含义
echo打印,相当于其他语言中的print
@不显示当前命令行,通常与echo一起使用
goto跳转,一般为标签(方法函数)一起使用,标签需用:表示,如goto add
rem表示注释
pause暂停,会等待用户并显示“按任意键后继续”
for循环,语法类似于python、kotlin等,如 for i in (…)
if判断条件,语法与其他编程语言相似
set赋值,可用于变量常量赋值
%引用,set /a num=9,那么%num%就是9了,%也可用于for循环中表示循环变量
ping检测是否连接,如ping -n 1 -w 10表示检测1次等待超时时间为10ms

可以使用 [keyword] /?方法查看某个内置dos命令的语法,如想知道ping的用法就使用ping /?。
ping help

批处理语法较为粗糙,都比较好理解,主要理解if和for的用法就行。
if命令使用if /?可以得到相关语法解释:

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

  NOT               指定只有条件为 false 的情况下,Windows 才
                    应该执行该命令。

  ERRORLEVEL number 如果最后运行的程序返回一个等于或大于
                    指定数字的退出代码,指定条件为 true。

  string1==string2  如果指定的文字字符串匹配,指定条件为 true。

  EXIST filename    如果指定的文件名存在,指定条件为 true。

  command           如果符合条件,指定要执行的命令。如果指定的
                    条件为 FALSE,命令后可跟 ELSE 命令,该命令将
                    在 ELSE 关键字之后执行该命令。

ELSE 子句必须出现在同一行上的 IF 之后

这里只截取了一部分,大致可以看到有三种用法,
第一种可用于判断在此之前的一行dos命令是否得到了正确的结果,比如:

@echo off
ping www.baidu.com -n 1 -w 10
IF ERRORLEVEL 0 (@echo baidu is available) ELSE (@echo baidu is unavailable)
pause

第二种和其他编程语言中的==或equals类似,比如:

@echo off
set a="9"
IF %a% == "9" (@echo success)
pause

第三种就是判断文件是否存在的,不多说。

for命令同样可以使用for /?查看帮助,这里用到的有两种:
第一种,数字的遍历:

FOR /L %variable IN (start,step,end) DO command [command-parameters]

例如:

FOR /L %%i in (1,2,10) DO (echo %%i)

输出:

1
3
5
7
9

第二种,读字符集合,包括文件/字符/某命令返回的结果:

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]

例如:

@echo off
FOR /F %%i in ("abcde") DO (echo %%i )
pause

输出:

adbce

这种用法的options有讲究:

        eol=c           - 指一个行注释字符的结尾(就一个)
        skip=n          - 指在文件开始时忽略的行数。
        delims=xxx      - 指分隔符集。这个替换了空格和制表符的
                          默认分隔符集。
        tokens=x,y,m-n  - 指每行的哪一个符号被传递到每个迭代
                          的 for 本身。这会导致额外变量名称的分配。m-n
                          格式为一个范围。通过 nth 符号指定 mth。如果
                          符号字符串中的最后一个字符星号,
                          那么额外的变量将在最后一个符号解析之后
                          分配并接受行的保留文本。
        usebackq        - 指定新语法已在下类情况中使用:
                          在作为命令执行一个后引号的字符串并且一个单
                          引号字符为文字字符串命令并允许在 file-set
                          中使用双引号扩起文件名称。

其中delims=就相当于JAVA中的split,
而tokens=2,就相当于split返回的数组中取第2个也就是split(“xx”)[1],
依此类推。
例如一个hosts.txt文件中存有:

192.168.0.111
192.168.0.53
192.168.0.32
192.168.0.14

现用命令:

@echo off
FOR /F "delims=. tokens=4" %%i in (hosts.txt) DO (echo %%i )
pause

输出即为:

111
53 
32 
14 

另外set命令可以用来作为赋值使用,

SET [variable=[string]]
SET /A expression
SET /P variable=[promptString]

第一种就是普通的赋值,第二种是表达式赋值,第三种是系统输入,类似C语言的scanf;
用法简单:

set str1=sssss
set /A c=2+3
set /P c=input:

另外注意变量延迟(setlocal)的用法,往往与!配合使用:

@echo off
set var=ff
for /l %%i in (1,1,3) do (
       set var=%%i
        echo %var%
        echo !var!
)

输出为:

ff    
!var! 
ff    
!var! 
ff    
!var! 

加入变量延迟操作以后:

@echo off&setlocal enabledelayedexpansion
set var=ff
for /l %%i in (1,1,3) do (
        set var=%%i
        echo %var%
        echo !var!
)

输出为:

ff
1
ff
2
ff
3

这和其他编程语言中的自增i++有点相似的意味。

最后贴出整个代码,也传到github批处理代码

@echo off

rem 得到本机IP
for /f "tokens=4" %%a in ('route print^|findstr 0.0.0.0.*0.0.0.0') do (
 set IP=%%a
)
echo LocalHost : %IP%
echo %cd%

rem 得到局域网范围
for /f "tokens=1-3 delims=." %%i in ('echo %IP%') do (
       set local_area=%%i.%%j.%%k
)
echo LocalArea : %local_area%

:main
echo please choose execution:
echo 	1.scan IP in LAN
echo 	2.connect all host:
echo 	3.install APK:
echo 	4.start APK:
echo 	5.kill app process:
echo 	6.clear App:
echo 	7.uninstall APK:
echo 	0.exit:

set /p choose=please input choose:
if %choose%==1 goto scan
if %choose%==2 goto connect
if %choose%==3 goto install
if %choose%==4 goto startapp
if %choose%==5 goto killapp
if %choose%==6 goto clearapp
if %choose%==7 goto uninstall
if %choose%==0 exit
pause

:scan
del %~dp0reachable_list.txt
@rem ping局域网内IP
setlocal enabledelayedexpansion
set /p indexStart=input start(such as 80):
set /p indexEnd=input end(such as 100):

set /a total = 0

FOR /L %%n in (%indexStart%,1,%indexEnd%) DO (
	ping %local_area%.%%n -n 1 -w 100
	IF !ERRORLEVEL! EQU 0 (
		echo %local_area%.%%n >> %~dp0reachable_list.txt
		set /a total = total + 1
	)
) 
echo %total% alive
endlocal
pause 
goto main

:connect
setlocal enabledelayedexpansion
FOR /f %%h in (%~dp0reachable_list.txt) DO (
	adb connect %%h:5555
 	echo ----------%%h connect success
)
adb devices
endlocal
pause
goto main

:install
@rem 设置apk路径
setlocal enabledelayedexpansion
set /p apk_path=input apk_path:
if not exist %apk_path% (
	echo %apk_path% not exist!
)
FOR /f %%h in (%~dp0reachable_list.txt) DO (
	adb -s %%h:5555 install -r -t %apk_path%
	echo ----------%%h install success
)
endlocal
pause
goto main

:startapp
@rem 启动apk
setlocal enabledelayedexpansion
set /p apk_intent=input apk_intent:
FOR /f %%h in (%~dp0reachable_list.txt) DO (
	adb -s %%h:5555 shell am start -n %apk_intent%
	echo ----------%%h start success
)
endlocal
pause
goto main

:killapp
@rem 启动apk
setlocal enabledelayedexpansion
set /p apk_package1=input apk_package:
FOR /f %%h in (%~dp0reachable_list.txt) DO (
	adb -s %%h:5555 shell am force-stop %apk_package1%
	echo ----------%%h kill app success
)
endlocal
pause
goto main

:clearapp
@rem 启动apk
setlocal enabledelayedexpansion
set /p apk_package1=input apk_package:
FOR /f %%h in (%~dp0reachable_list.txt) DO (
	adb -s %%h:5555 shell pm clear %apk_package2%
	echo ----------%%h clear app success
)
endlocal
pause
goto main

:uninstall 
@rem 卸载apk
setlocal enabledelayedexpansion
set /p apk_package2=input apk_package:
FOR /f %%h in (%~dp0reachable_list.txt) DO (
	adb -s %%h:5555 uninstall %apk_package2%
	echo ----------%%h uninstall app success
)
endlocal
pause
goto main
;