ClickOnceプログラミング 其の参 | あとはよしなに
May 10, 2009

ClickOnceプログラミング 其の参

テーマ:NET Programming

ClickOnceプログラミング 其の参 「データディレクトリの仕組みと利用アイデア」


今回は「データディレクトリ」について考えてみます。


1.データディレクトリとは。

そもそもデータディレクトリとは何なのかから説明します。

ClickOnceにはファイルを保存できる領域が2種類あります。

注) Vista以降の場合、パスが変わっていますので注意してくださいー。


ClickOnceキャッシュ領域

%userprofile%\LocalSetting\Apps\2.0


ClickOnceデータディレクトリ

%userprofile%\LocalSetting\Apps\2.0\Data

ClickOnceを発行すると、ファイルはデフォルトでClickOnceキャッシュ領域に格納されます。

ユーザが発行時にオプションを選択することでファイルはデータファイルとしてマークでき、

データファイルとしてマークしたファイルはClickOnceデータディレクトリに格納されることになります。


あとはよしなに-datafile

XMLファイルなど一部の形式のファイルは、デフォルトでデータファイルになるため、注意が必要です。


2.データディレクトリの不具合

※不具合といっても、バグではありません。適切に使えば、データディレクトリはうまく機能します。


データディレクトリには1つだけ困った特徴があります。

その特徴とは「データファイルは変更がなくとも、必ずダウンロードされる。」ということです。


これは、ネットワークトラフィックに制限がある案件では困ったことになります。

WEBを見ていると、データベースファイルやACCESSのファイルをデータファイルとしているのをよく見ますが、この方法は更新時に通信量がえらいことになっちゃうのでお勧めできないです;;


僕的にデータファイルは「ユーザがカスタマイズする」という範囲に留めるべきじゃないのかな?と思っています。

「キーコンフィグ」や「デザイン」をカスタマイズ可能にしてクライアントに保存する機能が必要な場合、データディレクトリを使うのがいいんでしょうね。


すみませんが、以下ではデータファイルに利用するのは、XMLファイルなどの小さなファイルとすることを前提にします。

データベースファイルやACCESSをデータファイルとしたいのであれば別の考慮を組み込むほうが良いですから・・・。


3.データディレクトリの仕様


それではデータディレクトリの仕様について。

※ここで述べるのはデータファイルがサーバで管理されている場合の話です。


XMLFileというXMLファイルをデータファイルとしてマークしてインストールしたとします。


すると、キャッシュ領域とデータディレクトリには以下のようにファイルが配置されます。

あとはよしなに-datadirectory

あれ?データファイルはデータディレクトリに配置されるんじゃないの?と思いそうですが、、、


実はClickOnceキャッシュ領域にあるファイルとデータディレクトリにあるファイルの役割は全然違います。

その役割は以下。


・ClickOnceキャッシュ領域にあるデータファイル

  サーバでデータファイルが変更されたかどうかを検知する。

・ClickOnceデータディレクトリ

  クライアントアプリケーションでファイル操作をする場合の対象ファイル。


サーバでアプリケーションが更新されたら?

前述の通り、データファイルがクライアントにダウンロードされます。


ダウンロードされたデータファイルは前バージョンのClickOnceキャッシュ領域にあるデータファイルと比較されます。比較結果に応じてデータディレクトリに配置されるデータファイルが異なります。

あ) 比較した結果、データファイルに変更がなかった場合

  前バージョンのデータディレクトリからデータファイルをコピーします。

い) 比較した結果、データファイルに変更があった場合

  新バージョンのデータファイルをデータディレクトリにコピーします。前バージョンのデータファイルは破棄します。


このため更新時にデータファイルを破棄したくない場合は、サーバでデータファイルを更新してはならなくなります。

まぁ、これはメジャーバージョンアップ時にデザインの仕様などを一新した場合などにいい仕組みかも。


でもでも、サーバでファイルを更新しないならサーバで管理する必要ないですね^-^;
サーバでデータファイルを管理せずにデータファイルをうまく扱う方法があればいいのですが・・・。

これについては次のセクションで。


4.データファイルと扱われる条件


データファイルが「データファイルと扱われる」条件を紹介します。


どういったファイルがデータファイルなのでしょうか?

実は以下の条件に当てはまるものは全てデータファイルとして扱われます。

・ファイルが「データファイル」としてマニフェストにマークされている。

・マニフェストで管理されていないファイルがデータディレクトリにある。
・user.config


一つずつ見てみます。

でも『ファイルが「データファイル」としてマニフェストにマークされている』は説明しませーん^-^


マニフェストで管理されていないファイルがデータディレクトリにある。


要はファイルがデータディレクトリにあれば、データファイルとして扱われるということです。

サーバでファイルが更新されることがないため、データファイルは破棄されることがありません。


じゃあ「どうやってデータディレクトリにファイルを置けばいいの?」という問題が出てきそうです。

何しろ、ClickOnceキャッシュ領域もデータディレクトリもランダム文字列を含むディレクトリですから、アクセスが大変そう・・・。


でも、実はすごくアクセスが簡単で、以下のコードで取得したパスにファイルを置けばいいんです。

※アプリケーションの単体テストなどを実現するため、アプリケーションがClickOnceとして管理されていない場合の制御は必ず入れる必要があります。この考慮をしていないと、単体テスト時に例外が出放題になります


if (!ApplicationDeployment.IsNetworkDeployed)
{
  return Application.StartupPath;
}

return ApplicationDeployment.CurrentDeployment.DataDirectory;


user.config

なんだか意味不明なこのConfigファイル。

これはapp.configにユーザスコープで定義したパラメータを定義するファイルのことです。

構成ファイル(app.config)にユーザスコープの変数を定義します(以下参照)。

<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup・・・省略" >
<section name="WindowsFormsApplication2.Properties.Settings" ・・・省略/>
</sectionGroup>
</configSections>
<userSettings>
<WindowsFormsApplication2.Properties.Settings>
<setting name="Yoshinani" serializeAs="String">
<value>HogeHoge</value>
</setting>
</WindowsFormsApplication2.Properties.Settings>
</userSettings>
</configuration>


このYoshinaniという変数はユーザスコープで利用されるため、

プログラムからYoshinani変数を変更すればuser.configがデータディレクトリに生成され、以後データファイルとして扱われます。

Yoshinani変数にアクセスするときは、このuser.configにアクセスすることになるので、カスタマイズを実現することができます。

ちなみに、プログラムからYoshinani変数に一度もアクセスしない場合、user.configは生成されません。


変数の体系を変えたい場合はサーバ側のapp.configを操作すればOKです。

なお、user.configでは新バージョンで使わなくなる変数がクライアント側で消えないのがネックです。

まぁ旧変数にアクセスしなければいいですよね。無理やり削除してあげてもいいわけですg・・・(自粛



5.まとめ


データディレクトリは特に消えてもエンドユーザの業務に致命的なダメージを与えない、

ユーザの利便性向上のためのユーザカスタマイズを実現したい場合にぴったりです。


以下の理由により、消えてはならないデータをデータファイルとすべきではありません。

・データが破棄される可能性がある。

・ClickOnceアプリケーションをアンインストールすると消える。


アプリケーションログも必要に応じてデータファイルではない場所に保存するべきでしょう。

僕はよくCドライブ直下にディレクトリを作って、そこに置くようにしています。アンインストールで消えないことは先に顧客と握っています。

こういった場合、ユーザアカウント制御(UAC)には注意してくださいね。

何しろClickOnceアプリケーションを利用している場合、UACの権限昇格ダイアログを出すことができませんから。。。


さて。

ここから先はアイデア勝負です。

アイデアは要件に応じてカスタマイズしなくてはならないのでアイデアを例示することができません・・・。

ただ、データディレクトリとデータファイルの仕様が分かれば要件にあわせて、アイデアを考え出すのはそう難しくはないはずです。


ほら、適用範囲を絞ればデータディレクトリの不具合なんか、あまり気にならないですよね?^-^