ClickOnceプログラミング 其の弐
ClickOnceプログラミング 其の弐 「差分ダウンロード機能の仕組みと罠パターン」
初回は「差分ダウンロード機能」について掘り下げてみます。
では、ちょっとだけ前置きします。
差分ダウンロード機能とは、「変更されてないファイルはそのまま使いたい」という要求に応えた機能です。
アプリケーションのVer1.00を配置して数日後にバグが見つかったので、すぐさまパッチをあてたVer1.01をリリースしたケースを考えてみてください。バグは膨大なアプリケーション全体から見るとたった1行の勘違いが原因で、修正はファイル1つだけだったなんてこと、よくあることです。
※ネットワークを介するテストはしづらいので初期リリースにはよくありがちなんです。いや、言い訳ですけど・・・。
このアプリケーションをネットワークを介してクライアントにダウンロードさせる。このとき、「アプリケーション全部がダウンロードされる」のと「ファイル1つだけダウンロードされる」のでは、通信帯域の圧迫度合が全然違います。
でも、この差分ダウンロード機能はClickOnceで初めて登場したわけじゃありません。
実は前身技術であるノータッチデプロイメントでも差分ダウンロードはありました。
ノータッチデプロイメントでの差分ダウンロードはHTTPヘッダのIf-modified-sinceフィールドを用いて実装されていますので、ファイルタイムスタンプがちょっとでも違うと、全く同じファイルでも別のファイルとして認識されてしまうという問題がありました。リリース担当者が5月1日に配置したファイルと同一のファイルを5月5日に再配置してファイルタイムスタンプが変わっちゃうと・・・。
ファイルが別モノとして認識されちゃいます。
ここまでをふまえてClickOnceの差分ダウンロードを考えてみましょう。
前置き終わり。
ClickOnceで差分ダウンロードがファイルを同一か否かを認識する方法は以下です。
テキトーにアプリケーションを公開してみます。Visual StudioでWindowsアプリケーションをすぐさま発行という手抜きっぷりには目をつぶってくださいな^-^;発行が終わったら、発行されたアプリケーションの「アプリケーションマニフェスト(拡張子manifest)」を開いてみます。
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="WindowsFormsApplication1.exe" size="6656">
<assemblyIdentity name="WindowsFormsApplication1" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1 " />
<dsig:DigestValue>5D3KU1fjkM9nEjFnBgW6VyZC2q4=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>>
エントリポイントに関する記載 WindowsFormsApplication1.exe.manifest(ver1.0.0.0)
DigestValueという項目はメッセージダイジェスト値を示しており、この値は以下の2つの用途に使われています。
・DigestValueが同じファイルは同一として、ダウンロードさせない(差分ダウンロード機能)。
・DigestValueと実際のメッセージダイジェスト値を比較して、異なる場合はダウンロードを破棄(改ざん検知機能)。
ちなみに。
このDigestValueはファイル名に依存しないので、ファイル名が異なってもDigestValueが全く同じなら差分ダウンロード機能が働きます(笑)偶然同じ文字列になることはないでしょうけど、万が一同じになったら誤作動するかもしれませんね。
このようにClickOnceの差分ダウンロード機能ではファイルのタイムスタンプは完全に無視されるため、前身技術であるノータッチデプロイメントの弱点を解決しています。
ではでは、ClickOnceで気にしておきたい2つの問題を考えてみましょう。
これが差分ダウンロード機能の罠にあたります。
たいていの場合はそこまで気にするほどのことではないのですが、ネットワーク負荷を考慮しなくてはならない案件だと面倒かもしれないです。
1.もう一度アプリケーションを発行する。
ここでは、先ほどのアプリケーションをもう一度発行してみます。再度アプリケーションマニフェストを見てください。
エントリポイントに関する記載 WindowsFormsApplication1.exe.manifest(ver1.0.0.1)
なんだか値変わってませんか?
これがVisual Studioを用いてClickOnceアプリケーションを発行した場合に必ずエントリポイントがダウンロードされてしまう原因です。プログラム上では全く変更されていなくとも、エントリポイントは必ずダウンロードされてしまいます。
受容: それくらい気にしないと言って無視する(笑) ※結構アリだと思っています。
2.クラスライブラリを追加してみる。
ビジネスロジックやデータアクセスロジックコンポーネントのためにアセンブリ分割したことを考えて見ます。
<dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="ClassLibrary1.dll" size="4096">
<assemblyIdentity name="ClassLibrary1" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
<hash>
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1 " />
<dsig:DigestValue>WhGfB0gihK5vWsqOFS2zKIPVj3M=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
クラスライブラリに関する記載 WindowsFormsApplication1.exe.manifest(ver1.0.0.2)
クラスライブラリに関する記載 WindowsFormsApplication1.exe.manifest(ver1.0.0.3)
クラスライブラリに関する記載 WindowsFormsApplication1.exe.manifest(ver1.0.0.4)