Antoine.st | Automatic Update |
Automatic Update配布対象がごく少数であれば、セットアップパッケージを作成してそれを動かすだけで OK です。ですが、配布対象が十数台を超えると、もう面倒。バージョンアップが合ったときなんて大変です。 そこで、検討対象となるのが自動更新機能。ノータッチデプロイメントとか ClickOnce などは言うまでもなく、Web アプリケーションも、そもそも配布の手間を減らすってのが大きな目的のひとつです。 この辺、割とありがちな機能なので、フレームワークで用意されていてもいいと思うんです。やることは簡単で、サーバー側のアプリケーションのバージョンを調べ、もしクライアントのものより新しければ更新、同じであればそのままにする、とそれだけです。 ただ、更新の頻度をどうするか、タイミングをどうするか、バージョンの確認をどうするか、自分自身を更新するときはどうするか、などがポイントになってきます。前に作ったときは、サーバーの共有ディレクトリにファイルを置いておく仕組みだったので、実行ファイルのバージョン情報をクライアントから読み取るようにしていました。ただし、これをやるとえらい時間がかかったので (64 K で接続された環境もあったから)、XML ファイルを置いておいて、それをダウンロード、読み取るように修正。タイミングは、アプリケーションを起動したときでした。 Functionalityこの辺をいろいろ考慮して、必要な機能を考えていくことにしましょう。 UpdateMethod PropertyUpdate、バージョンのチェック方法を指定する。HTTP、FTP、FileShare (Windows のファイル共有) などでしょうかね。 FileURL Propertyファイルを置いておく場所。ファイル共有でも URL? という疑問があったりなかったりしますが、ま、あまり気にしないでください。 IsNewerVersionByFileVersion() Method対象となるファイルのバージョンでチェックを行う。使用可能なのは、UpdateMethod で FileShare が指定されているときのみ。わざわざダウンロードしてからチェックするってのもおかしな話ですからね。 CheckVersionByFileName() Method対象となるファイルの名前でバージョンチェックを行う。これを利用するときは、機能名_x.xx.xxxx.exe というような名前にしておく必要がある。複数のバージョンを保持したいときとか便利かも。このメソッドを使うときは、HTTP でディレクトリリスティングができないと駄目ですね。 CheckVersionBySettingFile() Method対象となるファイルの名前、バージョンが書かれた設定ファイルを使ってバージョンチェックを行う。設定ファイルは XML でしょうかね。やっぱり。CheckVersion 系のメソッドでは、True/False で処理の成功/不成功を示します。 CheckingProgress Eventチェックの途中経過を示すイベント。ファイル数と確認済みファイル数を返せばいいでしょうか。 IsNewerVersion Propertyバージョンチェックの結果として、新しいバージョンのファイルがあれば True を返します。メソッドで直接返せないってのはちょっと嫌かも。 Details Propertyチェック結果の詳細を示します。ファイル名、現在のバージョン、新しいバージョンを返せば十分でしょうかね。複数のファイルが含まれる可能性があるので、文字列の配列にしておきます。 DownloadFiles() Methodファイルをダウンロードします。とりあえず、ダウンロードとアップデートは分けておくことにします。 DownloadProgress Eventダウンロード中の経過って必要ですね。ファイル共有時はどうしましょうか。途中経過が出せるコピー方法ってかなり限られちゃいますが。 UpdateFiles() MethodUpdateFilesByReboot() MethodUpdateFilesByRestart() MethodSample使用例としては、以下のような感じになるでしょうか。 bool updateSample() { AutomaticUpdate au = new AutomaticUpdate(); au.UpdateMethod = UpdateMethods.HTTP; au.FileURL = "http://www.sample.com/"; if (!au.CheckVersionBySettingFile()) { ShowErrors(); return false; } if (!au.IsNewerVersion()) { return true; } ShowDetails(au.Details); if (!au.DownloadFiles()) { ShowErrors(); return false; } if (!au.UpdateFiles()) { ShowErrors(); return false; } return true; }
|