「第2回 ClickOnceの仕組みを理解しよう」の中で述べたように、ClickOnceは差分ダウンロード(File Patching)に対応しており、特に開発者やユーザーが何も指定しなくても暗黙的にそれが行われるようになっている(逆にいえば差分ダウンロードは無効にできない)。
差分ダウンロードとは、「変更されたファイルやアセンブリのみをダウンロードし、変更されていないものは前回のものをローカル内でコピーして使い回す機能」のことである*2。
*2 変更されていないファイルやアセンブリもローカルでコピーされるので、ダウンロードする変更されたファイルやアセンブリと同様に、ClickOnceのアップデート時の画面にあるプログレスバーのメータはその分進むことになる。
従ってClickOnceアプリの更新を効率的にするためにも、1つの巨大なアセンブリでアプリケーションを作成するのではなく、複数の小さな.DLLファイルに機能を分割して1つのアプリケーションを構成する方がよいだろう。こうしておけば、変更されていないファイルはダウンロードされないので通信データ量が減るからだ。
また、前々回説明した「オンデマンド配置」を利用すれば、最初の更新時間をさらに短縮することが可能である(※もちろんオンデマンド配置で更新される各ダウンロード・グループも差分ダウンロードが行われる)。
●差分ダウンロードにより展開を効率化する際の注意点
差分ダウンロードによってアプリケーションの展開を効率化する際には、いくつかの注意点がある。
特に大事なのは、変更していないプロジェクトは不要にビルドしないことである。ビルドを行うことによって、(ClickOnceの発行時に生成される)アセンブリのハッシュ値が更新されてしまい、変更されたアセンブリと見なされるからだ。また関連ファイルについても、必要がなければ何も変更しないように注意しなければならない。
●差分ダウンロードの欠点
また、次のファイルにはこの差分ダウンロードの仕組みが適用されないという欠点がある。
これらの欠点を正しく理解しておくことで、より最適化された運用展開が行えるようになるだろう。そこで以下にもう少し細かい内容を説明しておこう。
●データ・ファイル(データ・ディレクトリに格納されたファイル)
ClickOnceのデータ・ファイルについては「TIPS:ClickOnceデータ・ディレクトリのパスを取得するには?」で詳しく説明されているが、要は[発行の状況]が「データ ファイル」に指定されたファイルで(具体的な設定方法は「第3回 Visual Studio 2005でClickOnceを極めよう」を参照されたい)、ClickOnceデータ・ディレクトリに配置されるファイルのことだ。
ClickOnceデータ・ディレクトリにあるファイルは、アプリケーションのバージョンをアップデートしても、前回のファイルがすべてコピーされて引き継がれる。よって、バージョン・アップ後も継続して使い続けたいデータなどはClickOnceデータ・ディレクトリに格納するのが好ましい(ただし、ClickOnceアプリをアンインストールすると消失するので、エンド・ユーザーが保存して使うようなファイルはここに格納してはならない)。
しかし、[発行の状況]が「データ ファイル」に指定されたデータ・ファイルは、内容が変更されていようといまいと(内容変更されていない場合は利用されないにもかかわらず)常にダウンロードされてしまう(=差分ダウンロードされない)という問題がある(この問題は将来的な.NET Frameworkで解決される方向のようだ)。
このことは、巨大なファイルは「データ ファイル」として配布すべきではないということを意味する。そうしてしまうと、アップデートのたびにダウンロードされるので、ネットワーク・トラフィックが増すばかりか、更新速度も遅くなってしまうからだ。
それでは、例えば巨大な.mdfファイル*3を配布したい場合、どうすればより効率的な展開が行えるのだろうか。
*3 .mdfファイルは自動的に[発行の状況]が「データ ファイル」に設定される。
1つの対策案としては、いったん通常のファイルとして(つまり[発行の状況]を「追加」に手動で変更して)、ClickOnceアプリのディレクトリに配置し(参考:「TIPS:ClickOnceアプリのディレクトリ・パスを取得するには?」)、その後ClickOnceアプリが起動したら、内部でそのファイルをClickOnceデータ・ディレクトリにコピーするのである。以後はコピー先のファイルを利用すればよい。
これにより、そのファイルはClickOnceデータ・ディレクトリが持つ「アップデート時のデータ維持機能」が活用できるにもかかわらず、Webサーバ(あるいはファイル共有)上からはダウンロードされない(内部でコピーされるだけになる)というメリットが得られるというわけだ。
次のコードは、実際にファイルをClickOnceアプリのディレクトリからClickOnceデータ・ディレクトリにコピーする例である。
using System.Windows.Forms;
using System.IO;
using System.Deployment.Application;
[STAThread]
static void Main()
{
CopyDataFileToDataDirectory();
……中略……
}
private static void CopyDataFileToDataDirectory()
{
// ClickOnceアプリでなければ以下のコードは実行しない
if (ApplicationDeployment.IsNetworkDeployed == false)
return;
// 現在のApplicationDeploymentオブジェクトを取得
ApplicationDeployment ad =
ApplicationDeployment.CurrentDeployment;
// 初回起動時でなければ以下のコードは実行しない
if (ad.IsFirstRun == false)
return;
// ClickOnceアプリ・ディレクトリに配置済みのデータ・ファイル
string appDir = Application.StartupPath;
string srcFilePath = Path.Combine(appDir, "BigSize.mdf");
// ClickOnceデータ・ディレクトリに配置予定のデータ・ファイル
string dataDir = ad.DataDirectory;
string destFilePath = Path.Combine(dataDir, "BigSize.mdf");
// ファイルをコピーする
if (File.Exists(destFilePath) == false)
{
File.Copy(srcFilePath, destFilePath);
}
}
なお、データ・ファイルが数百Mbytes以上もあり、バージョン・アップデート時にClickOnceデータ・ディレクトリ内でコピー作業が行われるだけでも更新に時間がかかってしまい、それが問題となるのであれば、完全にClickOnceの管理外のフォルダを利用するほかない。これには例えば、次のようなメソッドで取得できるフォルダの配下が使えるだろう。
ちなみにClickOnceアプリ内では、Application.CommonAppDataPathプロパティやApplication.UserAppDataPathプロパティの値はClickOnceデータ・ディレクトリを指す。
●.EXEファイル(ClickOnceアプリの本体)
更新バージョンのClickOnceアプリの発行を行う際、当然ながら発行バージョンを変更する必要がある。この発行バージョンの設定はプロジェクト・ファイル(MSBuildファイル)内に記述されているが、発行バージョンを変更するにはどうしてもその記述を書き換えざるを得ない。書き換えによりプロジェクト・ファイルが変更されれば、アセンブリをビルドし直すことになるため、ClickOnceアプリの起動開始ポイントである.EXEファイルは、変更されたアセンブリとして必ず配布されてしまう結果となるのである。
このことは、.EXEファイルが巨大な場合に問題になる可能性がある。例えば、小さな.DLLファイルだけを変更してClickOnceアプリをアップデートする際にも、常に巨大な.EXEファイルが一緒にダウンロードされることになるからだ。
従って、起動開始ポイントとなる.EXEファイルは極力小さくすることが重要である。
Copyright© Digital Advantage Corp. All Rights Reserved.