DOBON.NET どぼん!のVB道掲示板(プログラム)過去ログ

msiパッケージの内容をプログラムから参照するには?

msiパッケージでシステムをインストールする場合、インストール先の同じ場所に同じ名前のdllがあるとそのdllがインストールされません。
そこで、msiパッケージの内容をプログラムから参照する方法があれば教えていただきたいのです。msiファイルにパッケージされているdllと実際マシンにインストールされているdllのタイムスタンプを比較し、それが同一であれば、新しいdllがインストールされているというふうに判断ができます。
いろいろ方法を探してはみたのですが、それらしいものは全く見つけることができませんでした。どうぞよろしくおねがいします。
>msiパッケージでシステムをインストールする場合、
>インストール先の同じ場所に同じ名前のdllがあるとそのdllがインストールされません。
>そこで、msiパッケージの内容をプログラムから参照する方法があれば教えていただきたいのです。
>msiファイルにパッケージされているdllと実際マシンにインストールされているdllのタイムスタンプを比較し、
>それが同一であれば、新しいdllがインストールされているというふうに判断ができます。
>いろいろ方法を探してはみたのですが、それらしいものは全く見つけることができませんでした。どうぞよろしくおねがいします。

苦労なされていますね。そうなのです。私どもも苦労させられましたから。
MSIの機能としては、無条件に上書きさせるようにパッケージを作るか、バージョン比較で判定させるか、このどちらかを選ぶことしか出来ません。
動きとしては、DLL, EXE, OCXのようにバージョン情報を持っているものはバージョン比較が実施されるようですが、そうでないただのデータファイルの場合、果たしてタイムスタンプ比較をしてくれるのかどうか、定かではありません。まあ、これについては実際に試してみればどうなるか分ると思いますが・・・。

私が以前いたプロジェクトに於いては、インストールするファイルを一切インストール・レジストリには登録しなかった(自動修復対象外にする)ので、DLLでも何でも、本来インストールする場所とはまったく別の場所にインストールさせ、タイムスタンプを比較して必要なものだけ、本来インストールされるべき場所にコピーするようにしました。つまり、MSIを殆ど無視して作ったということです。

しかし、ちゃんとインストール・レジストリの登録を行うように作ってあるパッケージではそうは行きません。厄介ですが、MsiのAPIを使って、インストーラ・データベースを覗くしかありません。

やり方を詳しく説明していくのは大変なので、というか、もう殆ど忘れかけているのですが、以下のページを調べてください。

MSIのトップページ:
http://search.microsoft.com/gomsuri.asp?n=4&c=rp_BestBets&siteid=us/dev&target=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/about_windows_installer.asp

インストーラ・データベース:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/installer_database.asp
これで、どんなテーブルがあるか確認できます。コアテーブルとファイルテーブルの両方を見ないといけなかった気がします。

Installer Function Reference:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/installer_function_reference.asp
MSIのAPI群です。この中に、どれだったか忘れましたが、パッケージをオープンして、データベースみたいにSQLでクエリーしていくためのAPIがあります。
>msiパッケージでシステムをインストールする場合、インストール先の同じ場所に同じ名前のdllがあるとそのdllがインストールされません。

Kamaliさんご指摘の通り、インストールされないということはありません。デフォルトではバージョンの新しいファイルのみ置き換えるというようになっています。この設定はREINSTALLMODEプロパティで変更できます。

またはFileテーブルのversionを変更する(上書きしたければバージョンをあげる)という方法もあります。この方法であればバージョン情報を持たないファイルでも上書きさせるかどうか個別に指定することも可能になるのではないでしょうか。
>>msiパッケージでシステムをインストールする場合、インストール先の同じ場所に同じ名前のdllがあるとそのdllがインストールされません。
>
>Kamaliさんご指摘の通り、インストールされないということはありません。デフォルトではバージョンの新しいファイルのみ置き換えるというようになっています。この設定はREINSTALLMODEプロパティで変更できます。
>
>またはFileテーブルのversionを変更する(上書きしたければバージョンをあげる)という方法もあります。この方法であればバージョン情報を持たないファイルでも上書きさせるかどうか個別に指定することも可能になるのではないでしょうか。

どぼんさん、そうそう。そうなんです。Orcaを使って、手でversion情報を書換えていく。やりましたよ。面倒臭いから二度とやりたくないですが。。。

私が以前作成していたものはプリンタとプリンタドライバを新規追加したり、新しいドライバに置換えたりするものだったのですが、プリンタドライバの特殊性から、ファイルテーブル内のドライバ*.DLL/*.DRVのバージョン情報を書換えていたことがありました。プリンタドライバのバージョンというのは普通のバージョンと違って、Win9X, WinNT3/4/5(2k)/6(XP)というWindowsプラットフォームのどれに対応するドライバかを示すための数字に使われていて、バージョンは絶対変らないのです。

その後、結局、まったく別のフォルダにファイルを展開する方法に代えたため、なんとかこの面倒な作業は要らなくなりましたが・・・。
この発言は削除されました
Kamaliさんどぼんさんありがとうございました。

まず、インストール時に無条件に上書きするというREINSTALLMODEを試してみました。うまくいきました。ただ、システムファイルも上書きされてしまうのですね・・・?特定のファイルのみ上書きなどということはできないですよね・・?

次に、Kamaliさんから教えていただいたmsiのAPI群のページを見てみました。ひととおり探して見ましたが、英語もわからないうえに内容もちんぷんかんぷんで、どれが自分の求めているものなのか、さっぱり見当がつきません。もし思い出したらでいいので、そのときは教えてください。
とりあえず、もう少し粘って探してみたいと思います!!
やはりFileテーブルのversionを変更するという方法はかなり大変でしょうね。他に方法があればよいのですが...。
>まず、インストール時に無条件に上書きするというREINSTALLMODEを試してみました。うまくいきました。ただ、システムファイルも上書きされてしまうのですね・・・?特定のファイルのみ上書きなどということはできないですよね・・?

特定のファイルのみ上書きする方法は前に書いたとおり、Fileテーブルのversionを書き換える方法があるのではないかと思うのですが、試されたでしょうか?

DOBON.NET | プログラミング道 | プログラミング掲示板