1 @ECHO OFF 2 IF %1.==/?. GOTO Help 3 IF %1.==/h. GOTO Help 4 IF %1.==-?. GOTO Help 5 IF %1.==-h. GOTO Help 6 IF %1.==--help. GOTO Help 7 GOTO Start 8 9 :Help 10 ECHO ^+----------------------------------------------------------------------------^+ 11 ECHO ^| ^| 12 ECHO ^| AutoUpdateSoftOnSkycn.cmd v0.2 ^| 13 ECHO ^| ^| 14 ECHO ^| 此脚本用于自动从天空软件站(http://www.skycn.com)上下载指定软件的当前版本 ^| 15 ECHO ^| (新版本),可以用来方便的追踪指定软件的新版本。 ^| 16 ECHO ^| ^| 17 ECHO ^| 使用方法: 在 ItemIDList 文件中添加需要下载的软件的 ID,一行一个 ID。软件的 ^| 18 ECHO ^| ID 是指其下载页面的文件名。比如腾讯QQ/TM 2005 珊瑚虫外挂的下载页面 URL 是 ^| 19 ECHO ^| http://www.skycn.com/soft/14096.html,那么它的 ID 就是 14096。 ^| 20 ECHO ^| ^| 21 ECHO ^| AutoUpdateSoftOnSkycn [Option1=Value1] [Option2=Value2] ... ^| 22 ECHO ^| ^| 23 ECHO ^| 选项列表请参阅配置文件 AUSOS.conf ^| 24 ECHO ^| ^| 25 ECHO ^| 此脚本需要以下 GNU 命令行工具: ^| 26 ECHO ^| grep ^| 27 ECHO ^| sed ^| 28 ECHO ^| sleep ^| 29 ECHO ^| wget ^| 30 ECHO ^| 可以通过安装 Cygwin(http://www.cygwin.com)获得这些工具(推荐给 Linux 爱好者 ^| 31 ECHO ^| 和有经验的用户)。不要使用 GnuWin32(http://gnuwin32.sourceforge.net)中的这 ^| 32 ECHO ^| 些工具,因为其中的 grep 和 sed 都存在 bug。 ^| 33 ECHO ^| ^| 34 ECHO ^| 此外,如果没有 Cygwin 中的 unix2dos 程序,“记事本”将无法正常显示由此脚自 ^| 35 ECHO ^| 动修改过的 ItemIDList 文件。此时,除了 Vim、Emacs、EditPlus、UltraEdit 等 ^| 36 ECHO ^| 常见的文本编辑器外,也可以使用 Windows 自带的“写字板”来编辑它。 ^| 37 ECHO ^| ^| 38 ECHO ^| Creator: Rainux ^| 39 ECHO ^| URL: http://www.rainux.org ^| 40 ECHO ^| ^| 41 ECHO ^+----------------------------------------------------------------------------^+ 42 REM TODO: 43 REM 通用化,使其易于扩展 44 REM 增加软件类别设置 45 REM Port to bash script 46 REM 检测 grep 等工具是否是 GNU 版本 47 REM 48 REM Last change: 2006 Jan 04 49 GOTO End 50 51 :Start 52 REM -------------------------------------------------------------------------- 53 SETLOCAL 54 REM 软件 ID 列表文件 55 SET ItemIDList="ItemIDList.ini" 56 REM 镜像服务器名称(不要加“下载”二字) 57 SET MirrorServer=广东佛山 58 REM 下载文件存放目录 59 SET DownloadPath="D:\Software Collection" 60 REM 是否存放到单独目录 61 SET SaveSeprt=YES 62 REM 是否在文件名前添加软件名称(不建议使用,因为无法保留文件在服务器上的时间戳) 63 SET UseFullName=NO 64 REM 是否自动删除旧版本 65 SET DelOld=YES 66 REM 是否显示详细下载信息(如果禁用将无法看到 wget 下载文件的进度条) 67 SET Verbose=YES 68 REM 日志文件名(如果不设置,将使用标准输出) 69 SET LogFile= 70 REM 下载遇到严重错误时的重试次数,严重错误目前仅指 HTTP 403 71 SET TryOnFatalError=32 72 REM 下载遇到严重错误时重试的间隔时间(秒) 73 SET WaitRetry=5 74 REM 重试间隔时间的增量(秒) 75 SET WaitIncrement=5 76 REM 跳过下载测试,直接开始下载(不建议使用,除非确信不会遇到 HTTP 404 之类的情况, 77 REM 因为如果遇到无法下载的文件,将会把很长的时间浪费在毫无意义的重复累加等待上) 78 SET SkipTest=NO 79 REM Wget 使用的参数 80 SET WgetArgs=--no-cache -c -N -t0 --waitretry=10 81 REM 82 REM -------------------------------------------------------------------------- 83 REM 覆盖用户环境变量设置 84 REM 85 REM 防止 Cygwin 里的程序在 NTFS 卷上创建文件时修改文件的默认访问权限 86 SET CYGWIN=nontsec 87 REM 88 REM -------------------------------------------------------------------------- 89 REM 声明全局变量 90 SET ID=id 91 SET ItemName=itemname 92 SET FileName=filename 93 SET Referer=referer 94 SET Logger=logger 95 SET RealWaitRetry=0 96 REM 临时文件名 97 SET AUSOS1="%TEMP%\AUSOS1.tmp" 98 SET AUSOS2="%TEMP%\AUSOS2.tmp" 99 SET AUSOSfile="%TEMP%\AUSOSfile.tmp" 100 SET AUSOSname="%TEMP%\AUSOSname.tmp" 101 SET AUSOSurl="%TEMP%\AUSOSurl.tmp" 102 SET AUSOSwgetlog="%TEMP%\AUSOSwgetlog.tmp" 103 REM -------------------------------------------------------------------------- 104 105 REM Collect user's options 106 IF EXIST "AUSOS.conf" ( 107 FOR /F "usebackq eol=# tokens=1* delims==" %%i IN ("AUSOS.conf") DO ( 108 SET %%i=%%j 109 ) 110 ) 111 :Loop 112 IF %1.==. GOTO EndLoop 113 IF %2.==. GOTO EndLoop 114 SET %1=%2 115 SHIFT 116 SHIFT 117 GOTO Loop 118 :EndLoop 119 120 REM If LogFile not specified, not use Logger 121 FOR /F "tokens=*" %%f IN ("%LogFile%") DO ( 122 SET LogFile="%%~ff" 123 ) 124 IF %LogFile%.==. ( 125 SET Logger= 126 ) ELSE ( 127 REM Use Logger, set wget to no-verbose mode to disable the progress bar 128 DEL /F %LogFile% 2>NUL 129 SET Logger=^>^>%LogFile% 2^>^&1 130 SET WgetArgs=%WgetArgs% -nv 131 ) 132 133 REM Use the GNU tools in current directory first 134 FOR /F "tokens=*" %%i IN ("RNX") DO ( 135 SET PATH="%%~dpi";%PATH% 136 ) 137 138 IF NOT EXIST %ItemIDList% ( 139 ECHO 请先创建 ItemIDList 文件,在命令行带参数 -h 运行此脚本以查看帮助 140 GOTO End 141 ) 142 IF NOT EXIST %DownloadPath% MD %DownloadPath% 143 FOR /F "usebackq eol=# tokens=1,2* delims= " %%i IN (%ItemIDList%) DO ( 144 REM %%i=ID; %%j=OldItemName; %%k=OldFileName 145 SET ID=%%i 146 wget -q --no-cache -O%AUSOS1% "http://www.skycn.com/soft/%%i.html" 147 REM Get the name of the downloading software 148 grep -i "<title>" %AUSOS1% > %AUSOSname% 149 REM Since sed's in-place edit can not work with the file not in current volume 150 PUSHD %TEMP% 151 sed -i "s/\(<title>\)\(.*\)\( - 天空软件站.*\)/\2/g" %AUSOSname% 152 REM Replace the special character which can not be used as file name to _ 153 sed -i "s/[?""/\<>*|:]/_/g" %AUSOSname% 154 REM Replace space with . 155 sed -i "s/\s/\./g" %AUSOSname% 156 POPD 157 FOR /F "usebackq tokens=*" %%n IN (%AUSOSname%) DO ( 158 SET %ItemName%=%%n 159 REM Get the URL and file name of the downloading software 160 grep -i "<a href[^<]*%MirrorServer%" %AUSOS1% > %AUSOS2% 161 sed "s/下载/\n/g" %AUSOS2% | grep "%MirrorServer%" | grep -i -o "http://[^']*" > %AUSOSurl% 162 grep -o "[^/]*$" %AUSOSurl% > %AUSOSfile% 163 FOR /F "usebackq tokens=*" %%f IN (%AUSOSfile%) DO ( 164 SET %FileName%=%%f 165 REM Record the name of the downloading software, create a folder for it 166 FOR /F "tokens=*" %%p IN ("%ItemIDList%") DO ( 167 PUSHD %%~dpp 168 sed -i "s/\(%%i\)\(.*\)/\1\t%%n\t%%f/g" %ItemIDList% 169 unix2dos %ItemIDList% 2>NUL 170 POPD 171 ) 172 REM Delete old version if DelOld=YES and old name is present (%%j) 173 REM In this case, we assume user's options always the same 174 IF NOT "%%j"=="" ( 175 IF %DelOld%==YES ( 176 IF %SaveSeprt%==YES ( 177 IF NOT "%%j"=="%%n" ( 178 RD /S /Q %DownloadPath%\"%%j" 2>NUL 179 ECHO 已删除旧版本软件 "%%j"%Logger% 180 ) ELSE ( 181 REM If just file name changed 182 IF NOT "%%k"=="%%f" ( 183 IF %UseFullName%==YES ( 184 DEL /F %DownloadPath%\"%%j"\"%%j"_"%%k" 2>NUL 185 ) ELSE ( 186 DEL /F %DownloadPath%\"%%j"\"%%k" 2>NUL 187 ) 188 ECHO 已删除 "%%j" 的旧版本文件 "%%k"%Logger% 189 ) 190 ) 191 ) ELSE ( 192 REM If not save in separate directory and soft name changed 193 IF NOT "%%j"=="%%n" ( 194 IF %UseFullName%==YES ( 195 DEL /F %DownloadPath%\"%%j"_"%%k" 2>NUL 196 ) ELSE ( 197 DEL /F %DownloadPath%\"%%k" 2>NUL 198 ) 199 ECHO 已删除旧版本软件 "%%j"%Logger% 200 ) ELSE ( 201 REM If just file name changed 202 IF NOT "%%k"=="%%f" ( 203 IF %UseFullName%==YES ( 204 DEL /F %DownloadPath%\"%%j"_"%%k" 2>NUL 205 ) ELSE ( 206 DEL /F %DownloadPath%\"%%k" 2>NUL 207 ) 208 ECHO 已删除 "%%j" 的旧版本文件 "%%k"%Logger% 209 ) 210 ) 211 ) 212 ) 213 ) 214 REM Change current dir to file save dir 215 IF %SaveSeprt%==YES ( 216 MD %DownloadPath%\"%%n" 2>NUL 217 PUSHD %DownloadPath%\"%%n" 218 ) ELSE ( 219 PUSHD %DownloadPath% 220 ) 221 IF %UseFullName%==YES ( 222 SET OutFileName="%%n"_"%%f" 223 ) 224 CALL :GetFile 225 POPD 226 ) 227 ) 228 ) 229 230 DEL /F %AUSOS1% 2>NUL 231 DEL /F %AUSOS2% 2>NUL 232 DEL /F %AUSOSfile% 2>NUL 233 DEL /F %AUSOSname% 2>NUL 234 DEL /F %AUSOSurl% 2>NUL 235 DEL /F %AUSOSwgetlog% 2>NUL 236 ENDLOCAL 237 238 :End 239 GOTO :EOF 240 241 REM -------------------------------------------------------------------------- 242 REM TestGet: 243 REM 检查文件是否可以被下载,在遇到 HTTP 4xx 和 HTTP 5xx 状态时跳过下载 244 REM 245 :TestGet 246 SET Counter=0 247 SET RealWaitRetry=%WaitRetry% 248 :RetryTest 249 SET /A "Counter = Counter + 1" 250 ECHO 正在测试 "%FileName%" 是否可以下载%Logger% 251 wget -i%AUSOSurl% -o%AUSOSwgetlog% --spider %WgetArgs% --referer="http://www.skycn.com/soft/%ID%.html" 252 grep -q "HTTP.\+ 200 OK" %AUSOSwgetlog% 253 IF %ERRORLEVEL%==0 ( 254 SET CanGet=True 255 GOTO EndTestGet 256 ) 257 REM Stop retry on HTTP 4xx or HTTP 5xx except HTTP 403, 258 REM cause HTTP 403 often means server is busy 259 grep -q "HTTP.\+ 40[^3] .\+" %AUSOSwgetlog% 260 IF %ERRORLEVEL%==0 ( 261 SET CanGet=False 262 GOTO EndTestGet 263 ) 264 grep -q "HTTP.\+ 4[^0]\d .\+" %AUSOSwgetlog% 265 IF %ERRORLEVEL%==0 ( 266 SET CanGet=False 267 GOTO EndTestGet 268 ) 269 grep -q "HTTP.\+ 5\d\d .\+" %AUSOSwgetlog% 270 IF %ERRORLEVEL%==0 ( 271 SET CanGet=False 272 GOTO EndTestGet 273 ) 274 IF %Counter%==%TryOnFatalError% ( 275 REM Log GetFile max fatal error reached 276 ECHO 测试下载 "%FileName%" 时遇到错误,已经达到允许的最大错误次数,测试失败%Logger% 277 SET CanGet=False 278 GOTO EndTestGet 279 ) 280 ECHO 测试下载 "%FileName%" 时遇到错误,这是第 %Counter% 次出错,将在 %RealWaitRetry% 秒后重试%Logger% 281 sleep %RealWaitRetry% 282 SET /A "RealWaitRetry = RealWaitRetry + WaitIncrement" 283 GOTO RetryTest 284 SET CanGet=Unknown 285 :EndTestGet 286 IF %CanGet%==True ( 287 ECHO 测试完成,"%FileName%" 可以下载%Logger% 288 ) ELSE ( 289 ECHO 测试完成,"%FileName%" 无法下载,下载动作将被跳过%Logger% 290 ) 291 GOTO :EOF 292 REM -------------------------------------------------------------------------- 293 294 REM -------------------------------------------------------------------------- 295 REM GetFile: 296 REM 取得 %ItemName% 的文件 %FileName% 297 REM 298 :GetFile 299 IF %SkipTest%==NO ( 300 CALL :TestGet 301 ) ELSE ( 302 SET CanGet=True 303 ) 304 IF NOT %CanGet%==True ( 305 REM Log GetFile fail 306 GOTO EndGetFile 307 ) 308 REM CAUTION: Must use "" to quote ItemName, cause if it have () will break the script 309 ECHO 开始下载 "%ItemName%",文件名为 "%FileName%"%Logger% 310 ECHO.%Logger% 311 REM Retry on download fail, e.g. HTTP 403 312 SET Counter=0 313 SET RealWaitRetry=%WaitRetry% 314 :RetryGet 315 SET /A "Counter = Counter + 1" 316 IF %UseFullName%==YES ( 317 wget %WgetArgs% -i%AUSOSurl% -O%OutFileName% --referer="http://www.skycn.com/soft/%ID%.html"%Logger% 318 ) ELSE ( 319 wget %WgetArgs% -i%AUSOSurl% --referer="http://www.skycn.com/soft/%ID%.html"%Logger% 320 ) 321 IF %ERRORLEVEL%==0 ( 322 REM Log GetFile success 323 ECHO "%ItemName%" 已经成功下载%Logger% 324 ECHO.%Logger% 325 GOTO EndGetFile 326 ) ELSE ( 327 IF %Counter%==%TryOnFatalError% ( 328 REM Log GetFile max fatal error reached 329 ECHO 下载 "%ItemName%" 时遇到错误,已经达到允许的最大错误次数,下载该文件失败%Logger% 330 ECHO.%Logger% 331 GOTO EndGetFile 332 ) 333 ECHO 下载 "%ItemName%" 时遇到错误,这是第 %Counter% 次出错,将在 %RealWaitRetry% 秒后重试%Logger% 334 ECHO.%Logger% 335 sleep %RealWaitRetry% 336 SET /A "RealWaitRetry = RealWaitRetry + WaitIncrement" 337 GOTO RetryGet 338 ) 339 :EndGetFile 340 REM --------------------------------------------------------------------------