批处理Bat教程-第八章:番外篇

转载自:http://docs.30c.org/dosbat/chapter08/

8.1 批量十六进制二进制格式转换

想把数据(流)以十六进制或二进制的形式显示出来?UltraEdit之类的编辑软件一定是首选。即使是要自己亲自转出来,C/C++等语言也会方便的多。如果您跟我一样选择使用批处理来实现的话,那么很好,很有挑战性。

::::::DataFormatConvert.bat::::: 
@echo off 

:Initialization 
set TempFile=temp.tmp 
set /a num = 0 
set BinaryFormat=Bin 
:: 默认为二进制数字0或1显示 
set ConvertOption=ConvertToHex 
:: 默认为十六进制转换 
set ShowProgress=ShowProgressOn 
:: 默认为显示转换进度 
set BackSpace=[将本文底部评论3中的退格符替换到此处] 
:: 退格符 

set Source=z%1 
:: 添加一个临时字符 z 
if %Source:~1,1%z%Source:~-1%=="z" set Source=z%Source:~2,-1% 
:: 检查变量参数1的第一个和最后一个字符是否为 "" ,是的话就去掉 
set Source=%Source:~1% 
:: 去掉临时字符 z 
if "%Source%"=="" goto :HelpInformation 
if "%Source%"=="/?" goto :HelpInformation 
if /i "%Source%"=="/help" goto :HelpInformation 
if not exist "%Source%" echo 目标文件不存在 & exit /b 2 
:: 检查参数1 [注1] 

if /i "%2"=="/Bin" set ConvertOption=ConvertToBin 
if /i "%3"=="/Bin" set ConvertOption=ConvertToBin 
if /i "%2"=="/Block" set ConvertOption=ConvertToBin & set BinaryFormat=BinBlock 
if /i "%3"=="/Block" set ConvertOption=ConvertToBin & set BinaryFormat=BinBlock 
if /i "%2"=="/ProgressOff" set ShowProgress=ShowProgressOff 
if /i "%3"=="/ProgressOff" set ShowProgress=ShowProgressOff 
:: 检查参数2和3 [注2] 

for %%i in ("%Source%") do ( 
set SourceDrivePathName=%%~dpni 
set FileSize=%%~zi 
) 
:: 获得源文件的 驱动器号+路径+标题名 ,以及文件大小。 d - drive, p - path, n - name, z - size 
if "%FileSize%"=="0" echo 目标文件为空 & exit /b 3 
del %TempFile% >nul 2>nul 
fsutil file createnew %TempFile% %FileSize% >nul 
:: 创建一个大小与源文件一样的空白文件,该文件里的所有字节均为0x00 

goto :%ConvertOption% 

:ConvertToHex 
:: 十六进制转换 
setlocal EnableDelayedExpansion 
set OutputFile="%SourceDrivePathName%.Hex.txt" 
echo 文件 %Source% 的十六进制格式:>%OutputFile% 
echo. & echo 正在转换为十六进制... 

for /f "skip=1 tokens=1,3" %%i in ('fc /b %TempFile% "%Source%"') do ( 
set index=0x%%i 
set index=!index:~0,-1! 
set /a offset = !index! - !num! 

for /l %%n in (1,1,!offset!) do ( 
set /p=00<nul>>%OutputFile% 
set /a num += 1 
) 
set /p=%%j<nul>>%OutputFile% 
set /a num += 1 
call :%ShowProgress% !num! 
) 
:: 通过与大小相同内容空白的文件进行二进制对比,获得源文件的十六进制码 [注3] 
endlocal 
goto :ExitSuccess 

:ConvertToBin 
setlocal EnableDelayedExpansion 
set OutputFile="%SourceDrivePathName%.%BinaryFormat%.txt" 
echo 文件 %Source% 的二进制格式:>%OutputFile% 
echo. & echo 正在转换为二进制... 

for /f "skip=1 tokens=1,3" %%i in ('fc /b %TempFile% "%Source%"') do ( 
set index=0x%%i 
set index=!index:~0,-1! 
set /a offset = !index! - !num! 

for /l %%n in (1,1,!offset!) do ( 
call :HexTo%BinaryFormat% 0 
call :HexTo%BinaryFormat% 0 
set /a num += 1 
) 
set HexData=%%j 
call :HexTo%BinaryFormat% !HexData:~0,1! 
call :HexTo%BinaryFormat% !HexData:~1,1! 
set /a num += 1 
call :%ShowProgress% !num! 
) 
endlocal 
goto :ExitSuccess 

:HexToBin 
:: 函数: HexToBin 用途: 以0或1的形式显示 
if %1==0 set /p=0000<nul>>%OutputFile% 
if %1==1 set /p=0001<nul>>%OutputFile% 
if %1==2 set /p=0010<nul>>%OutputFile% 
if %1==3 set /p=0011<nul>>%OutputFile% 
if %1==4 set /p=0100<nul>>%OutputFile% 
if %1==5 set /p=0101<nul>>%OutputFile% 
if %1==6 set /p=0110<nul>>%OutputFile% 
if %1==7 set /p=0111<nul>>%OutputFile% 
if %1==8 set /p=1000<nul>>%OutputFile% 
if %1==9 set /p=1001<nul>>%OutputFile% 
if %1==A set /p=1010<nul>>%OutputFile% 
if %1==B set /p=1011<nul>>%OutputFile% 
if %1==C set /p=1100<nul>>%OutputFile% 
if %1==D set /p=1101<nul>>%OutputFile% 
if %1==E set /p=1110<nul>>%OutputFile% 
if %1==F set /p=1111<nul>>%OutputFile% 
goto :EOF 

:HexToBinBlock 
:: 函数: HexToBinBlock 用途: 以 或■的形式显示[注3] 
if %1==0 set /p=    <nul>>%OutputFile% 
if %1==1 set /p=   ■<nul>>%OutputFile% 
if %1==2 set /p=  ■ <nul>>%OutputFile% 
if %1==3 set /p=  ■■<nul>>%OutputFile% 
if %1==4 set /p= ■  <nul>>%OutputFile% 
if %1==5 set /p= ■ ■<nul>>%OutputFile% 
if %1==6 set /p= ■■ <nul>>%OutputFile% 
if %1==7 set /p= ■■■<nul>>%OutputFile% 
if %1==8 set /p=■   <nul>>%OutputFile% 
if %1==9 set /p=■  ■<nul>>%OutputFile% 
if %1==A set /p=■ ■ <nul>>%OutputFile% 
if %1==B set /p=■ ■■<nul>>%OutputFile% 
if %1==C set /p=■■  <nul>>%OutputFile% 
if %1==D set /p=■■ ■<nul>>%OutputFile% 
if %1==E set /p=■■■ <nul>>%OutputFile% 
if %1==F set /p=■■■■<nul>>%OutputFile% 
goto :EOF 

:ShowProgressOn 
:: 函数: ShowProgressOn 用途: 显示转换进度 
set /a mod = %1 %% 50 
if %mod% equ 0 ( 
set /a percent = %1 * 100 / %FileSize% 
set /p=%BackSpace%%BackSpace%%BackSpace%<nul 
set /p=!percent!%%<nul 
) 
goto :EOF 

:ShowProgressOff 
:: 函数: ShowProgressOff 用途: 不显示转换进度 
goto :EOF 

:HelpInformation 
:: 该批处理的帮助信息 
echo 将文件转换为十六进制或二进制的格式。 
echo. 
echo DataFormatConvert source [/Hex ^| /Bin ^| /Block] [/ProgressOn ^| /ProgressOff] 
echo. 
echo source 指定要转换的文件。 
echo /Hex 表示转换为十六进制格式(默认)。 
echo /Bin 表示转换为二进制格式。 
echo /Block 表示转换为二进制格式并以方块的形式显示。 
echo /ProgressOn 显示转换进度(默认)。 
echo /ProgressOff 关闭显示进度。 
exit /b 1 

:ExitSuccess 
:: 成功完成并退出 
del %TempFile% >nul 
set /p=%BackSpace%%BackSpace%%BackSpace%%BackSpace%<nul 
echo 转换完成! 
exit /b 0 
:::::::::::::::::::::::::::::::: 

注1 exit 的参数 /b ,可以退出当前批处理脚本而不退出调用它的 CMD.EXE。如果从一个批处理脚本外执行,则会退出 CMD.EXE 。exit 的第二个参数 exitCode 是一个数字号码,如果使用了参数 /b ,这个数字号码将成为该批处理退出的 ErrorLevel 。如果退出 CMD.EXE ,则用那个数字设置过程退出代码。

注2 看到该批处理这些可使用的参数,您可能已经发现了,该批处理可以作为一条外部命令来使用,如果您把它放到 %SystemRoot%\system32 或 %SystemRoot% 路径下的话。默认情况下,%SystemRoot%\system32 和 %SystemRoot% 都是环境变量 PATH 的值之一(在 我的电脑->属性->高级->环境变量 中可以查看并设置相关环境变量)。

注3 源文件通过与其大小相同内容全为0x00的文件进行对比后,可以将源文件中所有与0x00不同的字节内容以十六进制码的形式表达出来。同时,还能得到每个不同字节所在的字节数位置,通过这个也便确定了源文件中0x00的内容。

正如注2中所说的,如果该批处理被放到了环境变量 PATH 中的路径中,则它可以作为外部命令来为您工作。
在这里插入图片描述

DataFormatConvert 的执行示意

十六进制或二进制转换成功的文件将被写到与源文件相同的路径中。

在这里插入图片描述

经DataFormatConvert 十六进制转换后的文件
对于计算机而言,十六进制码(或者说0和1)才能表达出它们自己的想法,尽管这些对我们来说犹如天书一般。

朴实的分割线

8.2 别挤,自启动的排队来

被放入到自启动项里的程序,从某种意义上来说,在被开启的时候确实简化了用户的操作。然而,在开机后众多的程序就像春运时期挤火车一样的蜂拥而上,这并不是我们所期望的。请不要问我为什么给这个批处理起了个如此无理的名称,所有放在 C:\WINDOWS 下的批处理我都会以小写字母 z 打头,方便管理。

::::::::::zLauncher.bat::::::::: 
@echo off 
setlocal enabledelayedexpansion 
title Launching... 
set /a ShortDelay = 6 
set BackSpace=[将本文底部评论3中的退格符替换到此处] 

set /p choice=LaunchOptions: 
if not "%choice%"=="" goto :CustomLaunch 

:BasicLaunch 
call :LaunchItem1 
call :LaunchItem2 
call :LaunchItem3 
call :LaunchItem4 
call :LaunchItem5 
goto :EOF 

:CustomLaunch 
for /l %%i in (0 1 9) do ( 
set "choice_=!choice:~%%i,1!" 
if "!choice_!"=="" echo All Launched! & goto :EOF 
if !choice_! gtr 9 echo Unknown Define & goto :EOF 
if !choice_! lss 0 echo Unknown Define & goto :EOF 
call :LaunchItem!choice_! 
) 

:LaunchItem1 
start "OE" "C:\Program Files\Outlook Express\msimn.exe" 
call :IsItemLaunchedSuccessful OE 
goto :EOF 
:LaunchItem2 
start "Skype" "D:\Program Files\Skype\Phone\Skype.exe" /nosplash /minimized 
call :IsItemLaunchedSuccessful Skype 
goto :EOF 
:LaunchItem3 
Start "QQ" "D:\Program Files\Tencent\QQ\QQ.exe" 
call :IsItemLaunchedSuccessful QQ 
goto :EOF 
:LaunchItem4 
start "BaiduHi" /min "D:\Program Files\baidu\Baidu Hi\BaiduHi.exe" 
call :IsItemLaunchedSuccessful BaiduHi 
goto :EOF 
:LaunchItem5 
start "Thunder" /min "D:\Program Files\Thunder Network\Thunder\Thunder.exe" 
call :IsItemLaunchedSuccessful Thunder 
goto :EOF 
:LaunchItem6 
start "Tudou" /min "D:\Program Files\Tudou\iTudou\iTudou.exe" 
call :IsItemLaunchedSuccessful Tudou 
goto :EOF 
:LaunchItem7 
start "MSN" /min "C:\Program Files\MSN Messenger\msnmsgr.exe" 
call :IsItemLaunchedSuccessful MSN 
goto :EOF 

:IsItemLaunchedSuccessful 
set /p =Launching %1<nul & title Launching %1 
if ERRORLEVEL 0 ( 
for /l %%i in (1,1,4) do ( 
ping -n %ShortDelay% 127.1>nul 
set /p =.<nul 
) 
) 
for /l %%i in (1,1,32) do set /p =%BackSpace%<nul 
echo %1 Launched 
title %1 Launched 
ping -n %ShortDelay% 127.1>nul 
goto :EOF 
:::::::::::::::::::::::::::::::: 

看得出来,这是一个科技含量很低的批处理,仅仅是在 start 每个程序之间将其挂起一段时间来避免众多程序同时启动所带来的负荷。当然,为了使它能够发挥作用,您得亲自配置它所要启动的程序,以及程序所在的路径才行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值