Create  Edit  Diff  FrontPage  Index  Search  Changes  Login

The Backyard - CreateMsiForVista Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

!Vista用MSIパッケージを作るときのメモ

!!問題点
管理者以外のログオンセッションでは、Windows VistaでASRの標準的なc:\program files\ruby-1.8へのインストールができない。

なぜならば、書き込み権限を得られないため、インストール対象のバッチファイルに含まれるRuby.exeのパスの更新に失敗するからである。

!!!理由

Visual Studio 2005のインストールプロジェクトでは、カスタム動作エディターを利用して、確定時の処理を設定できる。

ASRはこのプロジェクトを利用してインストールの最終時点で、binディレクトリにコピーしたbatファイルのパス名の部分をインストールされたディレクトリに変更している。この処理自体はRubyで記述されていて、bin\post-install.rbとしてパッケージに含まれる。

この処理は、MSIとは独立したプロセスで実行される(ruby.exeが起動されるので当然だ)。そのため、既定でMSIとは異なる権限で実行されることになる。これはインパーソネーション(impersonation)と呼ばれ、この場合はログオンしたユーザーのセキュリティコンテキストが適用される。

ということは、Vistaでは、インストーラ自体には、program filesフォルダへの書き込みのために強い権限が割り当てられているにもかかわらず、カスタムアクションは、ユーザー自身の弱い権限に戻されてしまうということだ。

これは、インストーラを管理者権限で実行しても同じことである。

つまり、Vistaでは、post-install.rbは、program files\ruby-1.8\binへの書き込み権限を持てず、したがってインストールは失敗する。

!!解決方法

[[@IT会議室|http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=41669&forum=7&2]]および、そこからリンクされている[[Anatoly LubarskyのSolution for MSI Error 2869 on Windows Vista|http://blogs.x2line.com/al/archive/2007/07/20/3210.aspx]]で提示されているように、カスタムアクションのType属性に、msidbCustomActionTypeNoImpersonate(ビット:0x00000800)を設定することで、上記の状態を解決できる。

[[カスタムアクション実行オプション|http://msdn2.microsoft.com/en-us/library/Aa368069.aspx]]

というのは、msidbCustomActionTypeNoImpersonateを指定することで、MSIはカスタムアクションに対してインパーソネーションを行わないようになるからである。(この場合、インパーソネーションとは、MSIを実行している強い権限から、元のログインユーザーの弱い権限への降格である。)

!!!必要なツール

カスタムアクションのType属性は、MSIパッケージ内のデータベースを操作できるWiRunSQL.vbsというスクリプトを利用してSQLで操作できる。

!!!WiRunSQL.vbsの入手
WiRunSQL.vbsはSDKに含まれている。

ここでは、Windows Software Development Kit Update for Windows Vistaを利用した。

該当のスクリプトは、SDKのインストールディレクトリのサンプルに含まれる。

既定の位置は、C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\SysMgmt\MSI\scripts である。

!!!最初の状態

実際に、WiRunSQL.vbsを利用して、生成直後のASRのmsiの状態を以下に示す。

cscript wirunsql.vbs  r:\asr\ActiveRuby.msi "SELECT * FROM CustomAction"
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

_8A0EAE83_67CD_4A24_943B_928B36ABBD0C  1554  _B85CAFF5F3984E509CA5AA6600B12DA2 "[TARGETDIR]\bin\post-install.rb" "[TARGETDIR]\bin"
EXEREG_CA__B40A20B147E54C57B9699B577D6E708E  3154 _B40A20B147E54C57B9699B577D6E708E  /REGSERVER
EXEUNREG_CA__B40A20B147E54C57B9699B577D6E708E  3154 _B40A20B147E54C57B9699B577D6E708E  /UNREGSERVER
DIRCA_TARGETDIR  307  TARGETDIR  [ProgramFilesFolder]\ruby-1.8
ERRCA_CANCELNEWERVERSION  19    [VSDVERSIONMSG]
ERRCA_UIANDADVERTISED  19    [VSDUIANDADVERTISED]
VSDCA_FolderForm_AllUsers  51  FolderForm_AllUsers  ALL

ここから、msidbCustomActionTypeNoImpersonateを設定するのは、_8A0EAE83_67CD_4A24_943B_928B36ABBD0Cだということがわかる。(regsverなどは既定でmsidbCustomActionTypeNoImpersonateが立っている)。

!!!更新

ここでは元のType値に引っ掛けて更新を行った。

cscript wirunsql.vbs  r:\public_html\data\asr\ActiveRuby.msi r:\asr\ActiveRuby.msi "UPDATE CustomAction SET Type=3602 WHERE Type = 1554"

元のタイプ値の1554に対してmsidbCustomActionTypeNoImpersonateの0x0800を加えた値を設定している。

!!!確認
以下のようにmsidbCustomActionTypeNoImpersonateが設定されたことを確認。

cscript wirunsql.vbs  r:\public_html\data\asr\ActiveRuby.msi r:\asr\ActiveRuby.msi "SELECT * FROM CustomAction"
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

_8A0EAE83_67CD_4A24_943B_928B36ABBD0C  3602 _B85CAFF5F3984E509CA5AA6600B12DA2
"[TARGETDIR]\bin\post-install.rb" "[TARGETDIR]\bin"
EXEREG_CA__B40A20B147E54C57B9699B577D6E708E  3154 _B40A20B147E54C57B9699B577D6E708E  /REGSERVER
EXEUNREG_CA__B40A20B147E54C57B9699B577D6E708E  3154 _B40A20B147E54C57B9699B577D6E708E  /UNREGSERVER
DIRCA_TARGETDIR  307  TARGETDIR  [ProgramFilesFolder]\ruby-1.8
ERRCA_CANCELNEWERVERSION  19    [VSDVERSIONMSG]
ERRCA_UIANDADVERTISED  19    [VSDUIANDADVERTISED]
VSDCA_FolderForm_AllUsers  51  FolderForm_AllUsers  ALL

!!!インストーラの実行
この状態で、ASRのmsiパッケージを実行すると、最初のインストール権限についての確認ダイアログ(外部由来のパッケージダイアログのことではない)に対する承認のみで、正しくインストールが行われることを確認した。

!!謝辞
Crafさんから上述の@IT会議室について[[教えていただきました|http://arton.no-ip.info/diary/20071002.html#c03]]。どうもありがとうございます。