ファイルをダウンロードするスクリプトを VBScript で書く
ある案件で, 「エンドユーザーがスクリプトファイルを実行したら, HKCU 配下のレジストリツリーへの書き込みと, クライアントソフトウェアのインストーラーのダウンロードと, インストールの実行がひととおりおこなわれるようにしてほしい」 という要件がありました. 本当は, ウェブページ上のリンクを 1 回クリックするだけで, それら一連の作業がすべて自動的に実行されることを期待されていたのですが, ブラウザーのセキュリティ設定を大幅に緩めることでもしないかぎり難しそうなので, エンドユーザーさんにはせめてスクリプトファイルのダウンロードと実行をおこなうという労力を負担していただくことで妥協することになりつつあります.
ちなみに, そういう顧客企業の個別の要望に応じたきめ細かなカスタマイズは日本企業の得意とするところなのかと思いきや, どうも弊社のようなパッケージベンダーの責務らしいということになりまして, これまで油断しっぱなしだったわたしとしては, 今般 VBScript をにわか勉強することになりました. ひょんなきっかけで知識や経験が増えるのは, 実にありがたいことです.
で, 本日は, レジストリへの書き込みに関することとファイルの実行に関することは捨象しまして, ファイルのダウンロードに関することだけ備忘録として書いておきたいと思います.
あるウェブサイトから HTTP を使ってファイルを取得する (ダウンロードする) のを VBScript で書くとした場合, どんな方法があるのでしょうか. ググってみましたところ, いくつかの記事がヒットするのですが, Windows XP 以降のクライアント OS を前提とするなら, たとえば次のようになりましょうか. (ちなみに, 現時点における Git の最新版の Windows 用インストーラーをダウンロードし, カレントディレクトリに保存するという事例で考えてみました.)
Const cReqPath = "http://msysgit.googlecode.com/files/" Const cFileName = "Git-1.7.9-preview20120201.exe" Set objShell = WScript.CreateObject("WScript.Shell") Set objXmlHttp = WScript.CreateObject("MSXML2.XmlHttp") objXmlHttp.Open "GET", cReqPath & cFileName, False objXmlHttp.Send intStatus = objXmlHttp.status If (intStatus <> 200) Then WScript.Echo "FAILED" & vbCrLf & vbCrLf & "HTTP status code is " & intStatus WScript.Quit End If Set objStream = WScript.CreateObject("ADODB.Stream") objStream.Open objStream.Type = 1 objStream.Write objXmlHttp.responseBody objStream.SaveToFile objShell.CurrentDirectory & "\" & cFileName, 2 objStream.Close Set objStream = Nothing Set objXmlHttp = Nothing WScript.Echo "Successfully done." WScript.Quit
変数名などは, VB 界隈におけるコーディングルールの鉄板をよく知りませんので, とりあえず見よう見まねで書いてみました. また, 冒頭の WScript.CreateObject("MSXML2.XmlHttp")
の部分は, ほかにも環境によって? 好みによって? いくつかほかにも選択肢があるようですが, それらの違いがよくわからなかったので, とりあえず Windows XP でも Windows 7 でも動作しそうなものを選んでみました.
さて, このスクリプトには, ひとつ困った点があります. それは, 一度ダウンロードしたファイルがローカルキャッシュに保存されますと, 次に再びこのスクリプトを実行しても, もはやウェブサイトにはアクセスせず, ローカルキャッシュに保存されているファイルを取得してしまうということです. ウェブサイトにアクセスしようともせずに XmlHttp
オブジェクトの status
プロパティが 200
を返すというのも, なんとなく釈然としないものが残ります.
この点に関しては, XmlHttp
オブジェクトの Send
メソッドを実行する前に, 次のようにキャッシュを無視するような設定を挿入しておけば, 毎回ウェブサイトからダウンロードしようとするようになるようです.
objXmlHttp.SetRequestHeader "Pragma", "no-cache" objXmlHttp.SetRequestHeader "Cache-Control", "no-cache" objXmlHttp.SetRequestHeader "If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT"
これについては XMLHttpRequest() という記事を参考にさせていただきました.
今夜は, 以上です.