none
インストールされる前に行いたい動作について RRS feed

  • 質問

  • こんにちは。

    WindowsInstallerについてご教授下さい。

    インストールをするフォルダ名と同一のフォルダ名がインストール先にある場合は、

    既存のフォルダ名を変更した上で、新規のフォルダをインストールしたいと

    考えております。そこで、VS.NetのソリューションエディタでInstallerクラスを追加して

    BeforeInstallイベントのイベントハンドラを記述しました。

    この動作はファイルがインストールされる前に行いたい動作なので、VSデプロイで提供されるカスタム動作に追加してもダメだという事は理解出来るのですが、上記機能を実現したい場合は、どのような手段をとれば良いのでしょうか?

    初心者で申し訳ありませんが、宜しくお願い致します。

    2006年12月7日 5:24

すべての返信

  •  kalpoo さんからの引用
    インストールをするフォルダ名と同一のフォルダ名がインストール先にある場合は、

    既存のフォルダ名を変更した上で、新規のフォルダをインストールしたい

    既存のフォルダをリネームしたらどうなるかの検証はすんでいますか?もしまだ確認していないのなら、まずは、リネームしても問題がないことを確認してください。

    もし、何か問題が出るという場合は、それを解決してください。その上で、改めてもう一度論点を整理して質問しなおしてください。

    一応やるという方向での回答ならこんな感じでしょうか。やってみればわかりますが、おそらく解決できない問題が出てくるのではないかと思われます。

    で、どうせ出てくるであろうことなので、続きを書いてしまいますが。。。w

    既存フォルダをリネームするのではなく、新規にインストールしようとしているアプリケーションのインストール先を既存フォルダにできないようにするという方向では検討できないでしょうか?

    おそらく、実装するという点で考慮するなら、この方が現実的ではないかと思います。

    いずれにしても、何でフォルダがかぶるのかが明記されてないので、これ以上は言及できないのですが。。。

    2006年12月7日 8:14
  • とっちゃんさん、回答頂きましてありがとうございます。

    すみません、フォルダがかぶる理由を記載しておりませんでした。

    弊社が開発しましたプログラムが入っているフォルダ(仮に『AAA』フォルダとします。)が既に

    ユーザー様のPC内に存在しておりまして、今まではインストーラを使用しておりませんでした。

    (手作業でのコピーだったようです。)

    又、プログラムの関係上、そのフォルダの位置はフルパス固定にしなければいけません。

    既に何度かリリースが済んでいるのですが、社内での検討の結果、今後はインストーラを導入したいとの事になりました。

    インストールするにあたっては、

    1.インストール先は固定

    2.インストーラを導入するので今後は手作業はしない

    3.ユーザー様PC内の既存の『AAA』フォルダにはユーザー様が作成されたプログラムも入っており、

     こちらから提供(インストール)するファイルだけではないので、むやみに削除出来ない。

    を検討する必要がありましたので、既存のフォルダはリネームして保存しないといけないかな、と考えておりました。

    ただ、これだと、インストーラを使用したインストールが初回の場合は良いけれど、以降が問題になってきますよね・・・。

    とっちゃんさんのおっしゃる通り、問題がありそうです。

    こういう場合は、どう考えれば宜しいのでしょうか?

    ぶしつけな質問で申し訳ありませんが、宜しくお願い致します。

     

    2006年12月7日 9:35
  • なるほど。とすると気にしないといけないのは

    3.ユーザー様PC内の既存の『AAA』フォルダにはユーザー様が作成されたプログラムも入っており、

    ですね。

    もしユーザーが配置するファイルにインストーラで提供する予定と同名のものがある場合、どちらが残るかは条件にもよりますが、二者択一となります(インストールしないという条件は設けられますが、更新条件を満たせなくともインストールはできません)。

    それを除けば、何にも考えることなくインストールしても、インストーラの関与しないファイルは消されることはありません。

    もちろん、アンインストールするとき(インストール時も可能)に、強制的に削除するという設定を行うことはできますが、別途設定を行わない限りそのようなことはできませんので、心配することはありません。

    今までが手作業だったのなら、インストーラにしたからといって大きく変わるということはありませんよ。

    その点については特に心配は不要だと思います。

    ただし、これらはあくまでもインストールするファイルがバージョン情報を持っている場合のみのこととなります。

    もし、バージョンを持っていないという場合は、File Versioning Rules を参考に更新されない条件が成立しないかを確認してください。

    #途中で投稿されちゃった...orz

    2006年12月7日 10:04
  • とっちゃんさん、ご教授頂きましてありがとうございます。

    最初からキ書いておけば良かったのですが・・・失礼致しました。

    心配下さっている

    『ユーザーが配置するファイルにインストーラで提供する予定と同名のものがある場合』

    ですが、それはなさそうなので大丈夫そうです。

    とっちゃんさんのおっしゃる通り、バージョン管理をキチンとしておかないと今後のインストールに

    関係してくると思いますので、勉強しておきます。

    すみません、話が戻るのですが・・・。

    最初に投稿しておりました、BeforeInstallイベントのイベントハンドラの機能実現は

    どうすれば出来るのでしょうか?

    何度もすみませんが宜しくお願い致します。

     

    2006年12月7日 11:00
  •  すみません、先に投稿しました内容では情報が足りませんので、付け加えさせて下さい。

    近い将来、弊社開発プログラム(ベースプログラム)が大幅に仕様変更される予定です。

    そうなると、新しいベースプログラムでは以前のユーザー様作成プログラムが動作しなくなりますので、

    その時のインストール方法としまして、既存のフォルダ名をリネームして保存したいと考えておりました。

    (ユーザー様が間違って以前のプログラムを使用しないようにする事とプログラム環境のバックアップ

    が目的です。)

    そこで、インストーラに含まれるファイルがインストールされる前のイベントにて上記処理をしたいの

    ですが、VSデプロイで提供されるカスタム動作ではタイミングが遅いので、どうすれば実現出来るのか

    を悩んでおりました。

    ちなみに、InstallerクラスのBeforeInstallイベントのイベントハンドラでデバッグとして

    MsgBoxを表示させているのですが、そのMsgBoxが表示されたタイミングでは、

    既にファイル(フォルダ)がインストールされていました。(カスタム動作の「インストール」に追加したから?)

    BeforeInstallイベントに処理を記述した場合、カスタム動作の「インストール」に追加しても無視される

    と思っていたのですが、私の考えが違った様です。

    どうか、ご教授を宜しくお願いいたします。

     

    2006年12月8日 3:30
  • 最初に投稿しておりました、BeforeInstallイベントのイベントハンドラの機能実現は

    どうすれば出来るのでしょうか?

    ドキュメントに書いてある通り、イベントハンドラを登録すれば自動的に呼び出してくれると思いますが?

    もしかして、呼ばれませんか?その場合は、Install メソッドも呼ばれないと思うのですが?

    それとも、具体的なコーディングの仕方でしょうか?イベントハンドラの手書きはできますか?

    BeforeInstall イベントのドキュメントに使用例として、具体的な実装例が出ています。

    ただ、ここでの使用例のままだと、まずもって見た目の変化はないと思います。インストーラクラス(を呼び出している実際のモジュール)が動いているプロセスには、コンソールがありませんので、Console.WriteLine の出力先はNULコンソールとなります。そのため、プログラムとしては動いていても、画面上でのフィードバックは全くありません。

    呼ばれていることを確認したい(デバッガを使うのではなくという意味で)のなら、MessageBox.Show など、GUIのウィンドウを出すようにしないとだめです。

     

    2006年12月8日 3:41
  • とっちゃんさん、こんにちは。

    すみません、投稿するタイミングが悪かったみたいです。

    先に投稿した内容が現状です。

    宜しくお願い致します。

    2006年12月8日 3:46
  • あ、ちょうど書いてる最中にアップだったんですね(^^;

    タイミングが合わなかったようです。

    近い将来、弊社開発プログラム(ベースプログラム)が大幅に仕様変更される予定です。

    そうなると、新しいベースプログラムでは以前のユーザー様作成プログラムが動作しなくなりますので、

    その時のインストール方法としまして、既存のフォルダ名をリネームして保存したいと考えておりました。

    下位互換もなくなるということですね。であれば、インストール先を変えてしまえばいいのではないでしょうか?

    それとも、それは他の関係(提供するプログラムが依存する何かなど)で不可能なのでしょうか?聞く限りでは、ベースプログラムのようですので、他からの影響を受ける可能性はほとんどないように思うのですが?

    まだ、プログラムの改訂に間に合うのかはわかりませんが、今までと同じフォルダだった場合、どういうことが起こりえるのかを人の操作ミスも含めて一度きっちりと洗いなおしてみることをお勧めします。

    インストールされていない状態になるということも含め、それがどういうことを招く可能性があるのか?をきちんと調査していれば、おそらくこの問題自体上がってこないように思うのですが...(私の勘ぐりすぎなのかもしれませんけど)

    さて、文句ばっかり書いていても仕方ありませんので

    ですが、VSデプロイで提供されるカスタム動作ではタイミングが遅いので、どうすれば実現出来るのか

    を悩んでおりました。

    のあたりについて。

    Installerクラスですが、これはこのクラスの実装を抱えるアセンブリ自身がインストール対象ファイルとなっています。そのため、そこに定義されたメソッド、イベントなどはすべてファイルをインストールしたじゃないと利用できません。実質的には、インストール後にアプリを動かしてできることと同様のことしかできないと思ってよいでしょう(高い権限で動かせる分、できることは多少増えますけどね)。

    インストール開始よりも前の段階で何かを行う(ただし、今回検討している移動のような処理はインストーラで行うべきことではありませんが)は、

    1. Custom Actions(カスタムアクション:VSのカスタム動作とは異なる仕組みで動くものです)を使って実装
    2. 事前インストールの形でパッケージを作り、ブートストラッパーに組み込む
    3. 別途バックアップツールとして提供する

    という形を選択します(実装が複雑な順)。

    さて、1のカスタムアクションですが、こちらで実装するという場合、原則として.NET Framework を使うことはできません(全く不可能というわけではありませんが、使わないことをお勧めします)。また、インストール中に不測の事態が発生した場合(たとえば、インストール中に電源が落ちてしまったなど)でも、もう一度呼び出されてしまうため、実装に求められるチェック項目が、単純な移動の数倍に膨れ上がるという問題もあります。そして最大の問題として、VSセットアッププロジェクトがこの仕組みをサポートしていないという点があります。そのため組み込みには、ビルド後にORCAなどを使って、別途追加するという作業が必要になります。もちろん、WiXやInstallShieldを利用してインストーラを作成するという方法もありますけど。

    実際は、2も同じ問題を抱えることにはなるのですが、それでも1よりは検査項目が少ないため(インストール中の不測の事態は避けられますので)、実装にかかる手間はかなり軽減されますし、.NET Framework を使うことも不可能ではない(その代りきちんと依存関係を作り上げておく必要がある)というメリットもあります。

    ほかにも選択肢はあると思いますけど、パッと思い浮かぶのはこの程度かなと思います。

    2006年12月8日 5:12
  • とっちゃんさん、こんばんは。

    お返事が遅くなりましてすみません。

    『下位互換もなくなるのでインストール先を変更すればいいのでは?』に関しましては、やはりプログラムの関係上

    フルパス固定でないといけない為(弊社のみの開発ではなく他社に依頼していた箇所があり、その部分の修正が不可な為)

    今回の様な仕様になった次第です。(人的ミスを防ぐ為でもあります。)

    私の書き方が悪かったと思うのですが、ユーザー様作成のプログラムというのは一般的に言われている『レシピ』の事です。

    Installerクラスについては、とっちゃんさんの『Installerクラスですが、これはこのクラスの実装を抱えるアセンブリ自身が

    インストール対象ファイルとなっています。』の説明で、やっと理解出来ました。

    今までInstallShieldでの作成経験しかなかったので、そのイメージでBeforeInstallを捉えていて、Installerクラスは

    InstallShieldで言うところのスクリプトみたいなものだと思っていたのですが、それが間違いだったようです。

    色々とありがとうございました。

    もう少し調べてみてより最善の方法を探してみます。

    2006年12月8日 9:45
  • フルパス固定ということなので、
    その固定のパスを検索して、ディレクトリがすでにあれば、既存ディレクトリをリネーム、
    その後にmsiexec.exeをキックする。という単純なexeを作ってやればいいのかなと思います。

    難点としては、Windowsインストーラにある起動チェックが動くのは、
    作成したexeから呼び出されるmsiexec.exeの延長なので、
    起動チェックにひっかかるケースでも遠慮なくリネームだけは行っちゃうことですが。

    2006年12月9日 15:16
  • ネットクラゲさん、お返事遅れましてスミマセン。

    ネットクラゲさんのおっしゃるようなやり方もあるんですね。

    色々と勉強になります。

    勉強の為に、その方法でもテストしてみたいと思います。

    ありがとうございました。

    2006年12月11日 8:51