1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
| 7.1 坐在家里周游世界
没错,我想是认真的,对于任何您想去往地球上的地点,您所需要做的仅仅是提供一个目的地的经纬度坐标而已。当然,我是不会给您提供去往世界各地的签证和机票的,但是海量的卫星照片还是能让您过足了瘾的。此时您手头可能并没有足够的坐标资源,不过我这里"恰好"有些陈芝麻烂谷子,是当年在留园网上搜集的地理坐标,具体请参阅《关于Google Maps的趣点》。这里必须得先感谢卫星图片的提供者 Google Maps ,因为你知道,毕竟航拍卫星并不是人人都能买的起的。
本小节也是在我回顾《关于Google Maps的趣点》这篇文章开始的。因为当年在搜集这些该死的地理坐标时,偷了一些懒,结果有些是小数格式的,有些是度分秒格式的,查看起来并不方便。如果有 Google Earth 来转换它们之间的格式倒也不难。但我知道,此时您的迅雷网快电驴里已经排满了各种各样电影、游戏、动漫的下载任务,看来您并没有下载 Google Earth 的意思。没关系,下面这个批处理多少能让您更方便地浏览 Google Maps 上的卫星照片。
::::::坐在家里周游世界.bat:::::: @echo off title 坐在家里周游世界 :: 设置标题 :Start cls :: 清屏 set choice=1 set /p choice=请选择经纬度格式(1. 小数格式 2. 度分秒格式 3. 退出): :: 选择经纬度的格式 或 退出程序 if %choice%==3 goto :EOF if %choice%==2 goto :DMSFormat
:DecimalFormat :: 小数格式的经纬度处理 set latitude=39.906477 set longitude=116.391467 :: 初始化为伟大首都天安门的坐标 set /p latitude=纬度: set /p longitude=经度: :: 提示用户输入目标的经纬度 [注1] goto :LaunchMap
:DMSFormat :: 度分秒格式的经纬度处理 set "DMSlatitude=39 54 23 N" set /a degree=39 set /a minute=54 set /a second=23 set NorthOrSouth=N :: 初始化为美丽首都天安门度分秒格式的纬度 echo. set /p DMSlatitude=纬度(格式 [度] [分] [秒] [N ^| S]): :: 提示用户输入目标的纬度 [注2] for /f "tokens=1,2,3,4,5" %%i in ("%DMSlatitude%") do ( set degree=%%i set minute=%%j set second=%%k set NorthOrSouth=%%l if "%%l"=="" echo 不正确的格式 & goto :DMSFormat ) :: 分别获得纬度的度、分、秒,以及南半球或北半球 if %degree% lss 0 echo 纬度必须大于0度 或不正确的格式 & goto :DMSFormat if %degree% gtr 90 echo 纬度必须小于90度 或不正确的格式 & goto :DMSFormat if %minute% lss 0 echo 纬度必须大于0分 或不正确的格式 & goto :DMSFormat if %minute% gtr 60 echo 纬度必须小于60分 或不正确的格式 & goto :DMSFormat if %second% lss 0 echo 纬度必须大于0秒 或不正确的格式 & goto :DMSFormat if %second% gtr 60 echo 纬度必须小于60秒 或不正确的格式 & goto :DMSFormat :: 判断纬度的度、分、秒格式是否有效 [注3] set /a degree*=3600 set /a minute*=60 set /a second=%degree%+%minute%+%second% set /a latitude=%second%*2500/9 :: 将度分秒计算并转换为小数格式 [注4] if %NorthOrSouth%==N goto :LatitudeLockDown if %NorthOrSouth%==n goto :LatitudeLockDown if %NorthOrSouth%==S set /a latitude=0-%latitude% & goto :LatitudeLockDown if %NorthOrSouth%==s set /a latitude=0-%latitude% & goto :LatitudeLockDown :: 判断南北半球格式是否有效 echo 南北半球标识不明确,请使用 N 或 S 来表示,不区分大小写。 & goto :DMSFormat
:LatitudeLockDown set "DMSlongitude=116 23 29 E" set /a degree=116 set /a minute=23 set /a second=29 set EastOrWest=E :: 初始化为可爱首都天安门度分秒格式的经度 echo. set /p DMSlongitude=经度(格式 [度] [分] [秒] [E ^| W]): :: 提示用户输入目标的经度 for /f "tokens=1,2,3,4" %%i in ("%DMSlongitude%") do ( set degree=%%i set minute=%%j set second=%%k set EastOrWest=%%l if "%%l"=="" echo 不正确的格式 & goto :LatitudeLockdown ) :: 分别获得经度的度、分、秒,以及东半球或西半球 if %degree% lss 0 echo 经度必须大于0度 或不正确的格式 & goto :LatitudeLockDown if %degree% gtr 180 echo 经度必须小于180度 或不正确的格式 & goto :LatitudeLockDown if %minute% lss 0 echo 经度必须大于0分 或不正确的格式 & goto :LatitudeLockDown if %minute% gtr 60 echo 经度必须小于60分 或不正确的格式 & goto :LatitudeLockDown if %second% lss 0 echo 经度必须大于0秒 或不正确的格式 & goto :LatitudeLockDown if %second% gtr 60 echo 经度必须小于60秒 或不正确的格式 & goto :LatitudeLockDown :: 判断经度的度、分、秒格式是否有效 set /a degree*=3600 set /a minute*=60 set /a second=%degree%+%minute%+%second% set /a longitude=%second%*2500/9 :: 将度分秒计算并转换为小数格式 if %EastOrWest%==E goto :LongitudeLockDown if %EastOrWest%==e goto :LongitudeLockDown if %EastOrWest%==W set /a longitude=0-%longitude% & goto :LongitudeLockDown if %EastOrWest%==w set /a longitude=0-%longitude% & goto :LongitudeLockDown :: 判断东西半球格式是否有效 echo 东西半球标识不明确,请使用 E 或 W 来表示,不区分大小写。 & goto :LatitudeLockDown
:LongitudeLockDown set latitude=%latitude:~0,-6%.%latitude:~-6% set longitude=%longitude:~0,-6%.%longitude:~-6% :: 整理纬度和经度
:LaunchMap echo. set /a zoom=16 set /p zoom=放缩度(0~18 默认值:%zoom%): :: 提示用户输入照片的放缩值 echo. echo 正在打开 纬度:%latitude% 经度:%longitude% 的卫星照片... start "正在打开Google Maps..." "http://maps.google.com/?t=k&z=%zoom%&ll=%latitude%,%longitude%" :: 将放缩值和经纬度值作为 Google Maps 链接参数,打开相应的照片 [注5]
pause goto :Start ::::::::::::::::::::::::::::::::
注1. 纬度或经度尽量能精确到小数点后3位数以上,因为越精确的坐标越能准确地帮您找到目标的位置
注2. 度分秒格式的纬度(或经度)您大概并不陌生,如果高中时代的您没有选择在地理课上逃课的话。例如 39°54' 23.32" N 就表示北纬39度54分23.32秒。另外,正在上高中的朋友在政治课上可以适当地翘课,个人研究表明,政治这玩意学多了不利于青少年大脑的发育。
注3. 纬度不能超过90度,而经度不能超过180度,分和秒的范围是0~59,这些常识是绝不会难到您的。
注4. 经纬度从度分秒格式转换为小数格式只需要:(度*60*60+分*60+秒)/60/60 即可,北纬39度54分23.32秒转换为小数即39.906477度。事实上,此处latitude的值是实际纬度的一百万倍,因为DOS命令中并不支持浮点型(实数)的变量,不用担心,在后面会有小数点向前移动6位的处理。同时,希望您也没有在数学课上翘课的习惯。
注5. 该链接正指向此时经纬度和放缩值的卫星地图,其中具体参数的含义可以参考《关于Google Maps的趣点》文中的解释。
好吧,您可能已经迫不及待地想试试这东西了。那么在运行该批处理后,首先您会得到选择两种经纬度类型的提示。选1的话,只需要分别输入小数格式的纬度和精度,以及放缩值即可(如果您还不确定放缩值是啥东西的话,可以置空直接使用默认值)。 如果在程序的一开始选择了2,也就是度分秒格式的经纬度。比如我们的目的地是:北纬15°17' 55" ,东经19°25' 47" ,您可以依次在纬度和经度里输入 15 17 55 n 和 19 25 47 e ,然后在放缩值里填上 22 。这样您就能看到北非中部一个小村庄里的几位村民,以及他们的奶牛和骆驼。
坐在家里周游世界.bat 的运行界面
坐在家里周游世界.bat 的运行结果
事实上,上面的照片是 Google Maps 中罕见的几张高清卫星照片之一,并不是每张照片的放缩值都能达到23滴,因为你也知道,即使是能买得起航拍卫星的家伙,也是没有足够的资金和精力来把地球的每一个角落都拍得一清二楚的。
========================================朴实的分割线========================================
7.2 进程分析者
写了一篇很简单却又很占篇幅的玩意,被我称之为"进程分析者"。此批处理的构思很轻松,只是简单地使用 tasklist 列出所有的进程,再显示为容易理解的文字说明而已。这与任务管理器中的进程相比,除了易于识别以外,还能帮您鉴别出那些喜欢"偷梁换柱"的隐患进程。比如用肉眼去观察 winhlep.exe 或 winhe1p.exe 的时候很容易忽视它们,而使用"进程分析者"却不会。
:::::::::进程分析者.bat::::::::: @echo off setlocal enabledelayedexpansion
title 进程分析者 set SPACE= set /a NumOfTotal=0 set /a NumOfSafe=0 set /a NumOfNasty=0 set /a NumOfUnknown=0 set IconOfSafe=√ set IconOfNasty=× set IconOfUnknown=?
:::::::: 以下定义为可信任的进程,可自定义更多的扩充 :::::::: :: 1. 系统进程 set alg.exe=%IconOfSafe%处理Windows网络连接共享和网络连接防火墙[系统进程] set csrss.exe=%IconOfSafe%管理Windows图形相关任务[系统进程] set explorer.exe=%IconOfSafe%用于显示系统桌面的图标,任务栏等[系统进程] set lsass.exe=%IconOfSafe%用于本地安全和登陆策略[系统进程] set services.exe=%IconOfSafe%管理启动和停止服务[系统进程] set smss.exe=%IconOfSafe%用于对话管理子系统调用和系统对话操作[系统进程] set spoolsv.exe=%IconOfSafe%用于将打印机任务发送到本地打印机[系统进程] set svchost.exe=%IconOfSafe%用于执行动态链接库DLL文件[系统进程] set System=%IconOfSafe%[系统进程] set taskmgr.exe=%IconOfSafe%任务管理器,用于显示系统正在运行的进程[系统进程] set winlogon.exe=%IconOfSafe%用于处理系统的登陆和登陆过程[系统进程] set winmgmt.exe=%IconOfSafe%用于系统管理员创建WIndows管理脚本[系统进程] :: 2. 基本进程 set cmd.exe=%IconOfSafe%Windows系统的命令行程序 set msimn.exe=%IconOfSafe%OutlookExpress相关程序 set mspaint.exe=%IconOfSafe%画图板 set notepad.exe=%IconOfSafe%记事本 set wab.exe=%IconOfSafe%通讯薄,用于储存地址、联系人和Email set ctfmon.exe=%IconOfSafe%提供语音识别、手写识别等 set conime.exe=%IconOfSafe%输入法编辑器相关程序 set SOUNDMAN.EXE=%IconOfSafe%Realtek声卡相关程序 set tasklist.exe=%IconOfSafe%这是本批处理的核心所在-_-b set wmiprvse.exe=%IconOfSafe%用于通过WinMgmt.exe程序处理WMI操作 :: 3. 工作进程 set EXCEL.EXE=%IconOfSafe%Excel set WINWORD.EXE=%IconOfSafe%Word set XDICT.EXE=%IconOfSafe%金山词霸 set sqlservr.exe=%IconOfSafe%用于SQL基础服务 set wmplayer.exe=%IconOfSafe%Windows Media Player set Mplayerc.exe=%IconOfSafe%暴风影音 set WinRAR.exe=%IconOfSafe%WinRAR :: 4. 防护进程 set 360tray.exe=%IconOfSafe%360安全卫士实时监控程序 set AntiArp.exe=%IconOfSafe%ARP防火墙 set CCenter.exe=%IconOfSafe%瑞星信息中心 set RavMonD.exe=%IconOfSafe%瑞星监控程序 set rfwsrv.exe=%IconOfSafe%瑞星个人防火墙相关程序 set RavStub.exe=%IconOfSafe%瑞星杀毒软件相关程序 set RfwMain.exe=%IconOfSafe%瑞星防火墙主程序 set RavTask.exe=%IconOfSafe%瑞星定时杀毒程序 set RavMon.exe=%IconOfSafe%瑞星监控程序 :: 5. 网络进程 set iexplore.exe=%IconOfSafe%IE浏览器 set Maxthon.exe=%IconOfSafe%傲游浏览器 set BaiduHi.exe=%IconOfSafe%百度Hi set msmsgs.exe=%IconOfSafe%MSN网络聊天工具 set QQ.exe=%IconOfSafe%腾迅QQ set TXPlatform.exe=%IconOfSafe%腾迅平台 set Thunder5.exe=%IconOfSafe%迅雷下载 set Skype.exe=%IconOfSafe%Skype语音聊天 set Contentfilter.exe=%IconOfSafe%Skype的相关程序 set skypePM.exe=%IconOfSafe%Skype语音聊天
:::::::: 以下定义为已知的危险进程,可自定义更多的扩充 :::::::: set a.exe=%IconOfNasty%蠕虫 set av.exe=%IconOfNasty%蠕虫 set blss.exe=%IconOfNasty%木马/拨号器 set cmd32.exe=%IconOfNasty%病毒 set crss.exe=%IconOfNasty%蠕虫 set csrse.exe=%IconOfNasty%病毒/木马 set Desktop.exe=%IconOfNasty%木马/病毒/间谍 set directs.exe=%IconOfNasty%蠕虫 set dllhlp.exe=%IconOfNasty%木马 set dllreg.exe=%IconOfNasty%病毒 set explore.exe=%IconOfNasty%灰鸽子 set explored.exe=%IconOfNasty%蠕虫 set optimize.exe=%IconOfNasty%拨号器/广告 set pcsvc.exe=%IconOfNasty%间谍 set rundll16.exe=%IconOfNasty%木马 set run32dll.exe=%IconOfNasty%间谍 set scvhost.exe=%IconOfNasty%木马/广告 set svchosts.exe=%IconOfNasty%木马 set system32.exe=%IconOfNasty%木马 set updater.exe=%IconOfNasty%蠕虫 set web.exe=%IconOfNasty%病毒/木马 set win32.exe=%IconOfNasty%病毒 set windows.exe=%IconOfNasty%蠕虫 set winlogin.exe=%IconOfNasty%病毒/木马 set winstart.exe=%IconOfNasty%间谍/广告 set wintsk32.exe=%IconOfNasty%病毒 set winupdate.exe=%IconOfNasty%病毒 set winxp.exe=%IconOfNasty%病毒 set winhlep.exe=%IconOfNasty%病毒
:::::::: 以下定义为未知的进程 :::::::: set UnknownTask=%IconOfUnknown%未识别的进程
:: 程序开始 echo 进程名称 分析结果 echo.
for /f "tokens=1" %%i in ('tasklist /NH') do ( set TaskName=%%i%SPACE% set TaskName=!TaskName:~0,20! if defined %%i ( echo !TaskName! !%%i! if "!%%i:~0,1!"=="%IconOfNasty%" ( set /a NumOfNasty+=1 ) ) else ( echo !TaskName! %UnknownTask% set /a NumOfUnknown+=1 ) set /a NumOfTotal+=1 ) echo ________________________________________________________________ echo. echo 共 %NumOfTotal% 个进程。 if %NumOfNasty% gtr 0 ( echo %NumOfNasty% 个存在安全隐患的进程! ) if %NumOfUnknown% gtr 0 ( echo %NumOfUnknown% 个未知进程。 ) pause>nul ::::::::::::::::::::::::::::::::
结果:
图7-3 进程分析者.bat 的运行结果
分析完毕!
========================================朴实的分割线========================================
7.3 公元2738年11月28日是星期几[编写中]
公元2738和11月28日,是个好日子。我打赌您不知道这天究竟是星期几而且您也并不想知道。
:::公元2738-11-28是星期几.bat:::[β版] @echo off setlocal enabledelayedexpansion
:Initialization :: 初始化 set TargetDate=%date:~0,4%%date:~5,2%%date:~8,2% set /a Year = 0 & rem 年 范围: 1~9999 set /a Mon = 0 & rem 月 范围: 1~12 set /a Day = 0 & rem 日 范围: 1~28 29 30 31 set /a IsLeapYear = 0 & rem 是否闰年 范围: 0~1
:PromptEntering :: 提示输入日期 set /p TargetDate=请输入日期(格式: YYYYMMDD 例如: %TargetDate%):
:: 转换为有效的年月日[注1] if %TargetDate:~0,3% == 000 ( set /a Year = %TargetDate:~3,1% ) else ( if %TargetDate:~0,2% == 00 ( set /a Year = %TargetDate:~2,2% ) else ( if %TargetDate:~0,1% == 0 ( set /a Year = %TargetDate:~1,3% ) else ( set /a Year = %TargetDate:~0,4% ) ) ) if %TargetDate:~4,1% == 0 ( set /a Mon = %TargetDate:~5,1% ) else ( set /a Mon = %TargetDate:~4,2% ) if %TargetDate:~6,1% == 0 ( set /a Day = %TargetDate:~7,1% ) else ( set /a Day = %TargetDate:~6,2% )
:CheckLeapYear :: 检测是否是闰年[注2] set /a DivisionBy4 = %Year%%%4 set /a DivisionBy100 = %Year%%%100 set /a DivisionBy400 = %Year%%%400
if %DivisionBy4% == 0 set /a IsLeapYear = 1 & rem 能被4整除的是闰年 if %DivisionBy100% == 0 set /a IsLeapYear = 0 & rem 能被100整除的非闰年 if %DivisionBy400% == 0 set /a IsLeapYear = 1 & rem 能被400整除的是闰年
set /a Month1 = 31 set /a Month2 = 28 + %IsLeapYear% set /a Month3 = 31 set /a Month4 = 30 set /a Month5 = 31 set /a Month6 = 30 set /a Month7 = 31 set /a Month8 = 31 set /a Month9 = 30 set /a Month10= 31 set /a Month11= 30 set /a Month12= 31
:: 检测范围是否有效[注3] if %Year% lss 1 echo 年份应该大于0 & goto :Initialization if %Year% gtr 9999 echo 年份不能超过9999 & goto :Initialization if %Mon% lss 1 echo 月份不能小于1 & goto :Initialization if %Mon% gtr 12 echo 月份不能大于12 & goto :Initialization if %Day% lss 1 echo 日数不能小于1 & goto :Initialization if %Day% gtr 31 echo 日数不能大于31 & goto :Initialization if %IsLeapYear% == 0 ( if %Mon%%Day% == 229 echo %Year%年的2月没有29日 & goto :Initialization ) if %Day% gtr !Month%Mon%! echo %Mon%月没有%Day%日 & goto :Initialization
:: 开始计算天数 set /a Year -= 1 & rem 该年未结束,应减一年 set /a Day = %Day% + Year * 365 & rem 一年365天 set /a Day = %Day% + Year/4 & rem 每4年多一闰 set /a Day = %Day% - Year/100 & rem 可每100年少一闰 set /a Day = %Day% + Year/400 & rem 但每400年还多一闰
set /a Mon -= 1 & rem 该月未结束,应减一月 for /l %%i in (1,1,%Mon%) do ( set /a Day = !Day! + !Month%%i! & rem 累计前几月的天数 )
:: 计算星期 set /a Week = %Day%%%7 & rem 除7得余数 set WeekChars=日一二三四五六 set Week=!WeekChars:~%Week%,1! & rem 换成汉字
:: 显示结果 echo. echo %TargetDate:~0,4%年%TargetDate:~4,2%月%TargetDate:~6,2%日,是公元第%Day%天,星期%Week% echo ___________________________________________ echo. & pause>nul & goto :Initialization ::::::::::::::::::::::::::::::::
注1 正如第三章关于 set 为变量赋予数值型的值所说的,如果数值是以 0 开头的,那么该数值便是八进制的。这并不是我们所期望,因此对变量的首位数非零的检测是必要的。
注2 闰年每隔四年来一次,这是众所周知的,但它并不完全正确。因为一年约为365.24219天,因此闰年将遵循于“四年一闰,百年不闰,四百年再闰”的规则。
注3 每个月的天数并不固定,但它们都在28~31这个范围内。
公元2738年11月28日是星期一,跟 Garfield 一样,我也讨厌星期一。
========================================朴实的分割线========================================
7.4 163邮箱登录器之不显示密码篇
还记得我们在3.4节中所提到过的163信箱登录的问题吗,那是一个不错的小批处理。不过那个批处理存在着一个小小的缺憾:在输入密码时,密码会暴露无遗地直接显示在屏幕上,这对于注重个人隐私的您来说,显然是无法接受的。
:::::::163邮箱登录器.bat:::::::: @echo off title 163邮箱登录器 mode con cols=80 lines=25 ::设置窗口的尺寸
set /p username=用户名: cls
chcp 437>nul graftabl 936>nul :: 转换代码页编号为 936
echo 用户名: %username% set /p =密 码: <nul
echo hP1X500P[PZBBBfh :: 创建一个神奇的二进制可执行文件 for /f "tokens=*" %%i in ('in.com') do set password=%%i :: 在那个神奇的文件被执行完返回结果之前,不显示任何东西 del in.com
setlocal EnableDelayedExpansion for /l %%i in (0,1,255) do ( if not "!password:~%%i,1!"=="" ( set /p =*<nul ) else ( endlocal goto :LoginMail ) ) endlocal :: 计算密码长度,然后显示相应个数的星号
:LoginMail
start "正在登录邮箱" "https://reg.163.com/logins.jsp?username=%username%&password=%password%&url=http://fm163.163.com/coremail/fcg/ntesdoor2"
echo. echo 正在登录邮箱... ping -n 2 127.0>nul :: 等待一小段时间 ::::::::::::::::::::::::::::::::
备注:本小节尚存在问题待解决(输入密码时使用退格会被当作字符记录下来,不输入任何东西则将显示Invalid keyboard code specified)……
|