Orca 不要 - MSI や MSP へ C# でアクセス

Document created by shinji_katayaesrij-esridist Employee on Aug 15, 2018Last modified by masanobu_hiranoesrij-esridist on Oct 3, 2018
Version 7Show Document
  • View in full screen mode

はじめに

弊社が運営している ArcGIS Blog で 紹介した「ArcGIS Desktop 楽々インストール ~バッチ ファイルの作成方法をご紹介~」、「ArcGIS Desktop 10.6, Pro 2.1 楽々インストール – バッチ ファイルを追加」では、ArcGIS Desktop, Engine, Pro 用のバッチファイルの作り方を紹介するとともに、サンプルのバッチファイルを GitHub 上で公開しています。

上記の記事中では触れませんでしたが、実は [Unistall_Batchfiles] の階層下にアンインストール用のサンプル バッチファイル、[Ps_Scripts] の階層下にメンテナンス用の PowerShell スクリプトも密かに公開しています。

本記事では、上記のメンテナンスで使用している PowerShell のスクリプトのように、MSI や MSP のアンインストール用コマンドを取得する C# のコードとツールをご紹介します。

通常、MSI や MSP のファイル内の情報へアクセスするには、Windows SDK に含まれる orca をインストールして利用することが多いと思いますが、本記事のようにツールを作成しておけば、msi や msp のアンインストール コマンドを、orca なしで作成することができます。

 

MSIファイルの アンインストールコマンド

Windows Installer(*.msi)のアンインストールのコマンドは次の通りです。

msiexec.exe /x <xxxx\xxxx.msi>

もしくは
msiexec.exe /x <ProductGUID>
ここで必要になのは msi ファイルか、product-code の GUID です。msi ファイルをインストール終了後に、ファイルを保持しておかなくてもよいという点において、GUID で指定するコマンドの方が汎用的に利用できます。
MSI の GUID の値については、「orca」を使ってアクセスした場合には、 *.msiを開き、[Tables] > [Property] > [ProductCode]の値を確認することが可能です。
一方で、C# でアクセスする方法は、次のようなコードになります。
///        
/// 呼び出し側で、Unistallのコマンド取得するには、propertyの引数に"ProductCode"を指定。
///

/// <summary>
/// Msi ファイルからアンインストール時に必要な情報を取得するメソッド
/// </summary>
/// <param name="msiFile"></param>
/// <param name="property"></param>
/// <returns></returns>
public static string GetMsiProperty(string msiFile, string property)
{
      string retVal = string.Empty;


      // インストーラのインスタンスを作成
      Type classType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
      Object installerObj = Activator.CreateInstance(classType);
      Installer installer = installerObj as Installer;

      // 読み込みのために msi ファイルをオープン
      // OpneDatabase method
      // 0 - Read, 1 - Read/Write
      Database database = installer.OpenDatabase(msiFile,0);

      // SQL文でプロパティをクエリして取得
      // OpneView method
      string sql = String.Format(
           "SELECT Value FROM Property WHERE Property ='{0}'", property);
            WindowsInstaller.View view = database.OpenView(sql);

      // Execute method and Fetch method
      view.Execute(null);
      // 取得したレコードの読み込み
      Record record = view.Fetch();

      // StringData property
      if (record != null)
           // プロパティの値を返す
           //retVal = string.Format("{0}: {1}", property, record.get_StringData(1));

           // アンインストール用のコマンドの形式で返す
           // mxiexec /X <PruductGUID>
           retVal = string.Format("mxiexec /X '{0}'", record.get_StringData(1));
           retVal = retVal.Replace("'", "\"");

      return retVal;
}

MSP ファイルの アンインストールコマンド

Windows Installer Patch(*.msp)のアンインストールのコマンドは次の通りです。

 

msiexec.exe /I <ProductGUID> MSIPATCHREMOVE=<PatchGUID>

 

 

msp の GUID の値は、「orca」を使ってアクセスした場合は、 *.mspを開き、[View]メニュー > [Summary Information] の画面の [Patch Code]=<PatchGUID>、[Targets]=<ProductGUID> の値を指定します。

 

 

一方で、C# でアクセスする場合は次のようなコードになります。

/// <summary>
/// MSP ファイルからアンインストール時に必要な情報を取得するメソッド
/// </summary>
/// <param name="mspFile"></param>
/// <returns></returns>
public static string GetMspSummaryInfo(string mspFile)
{
      string retVal = string.Empty;

      Type classType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
      Object installerObj = Activator.CreateInstance(classType);
      Installer installer = installerObj as Installer;

      // 読み込みのために msp ファイルをオープン
      // OpneDatabase method
      // 32 - msiOpenDatabaseModePatchFile
      Database database = installer.OpenDatabase(mspFile, 32);

      // orca での 「Patch Summary Information」画面
      //
      // Summary Property IDsの解説:
      // https://docs.microsoft.com/en-us/windows/desktop/Msi/summaryinfo-summaryinfo
      // 

      // プロパティの値を返す
      //int propCnt = database.SummaryInformation.PropertyCount;
      //retVal = string.Format("Targets: {0}", database.SummaryInformation.Property[7]); // [7]は Targets:
      //retVal += " , " + string.Format("Patch Code: {0}", database.SummaryInformation.Property[9]); // [9]は Patch Code:

      // アンインストール用のコマンドの形式で返す
      // msiexec / I < ProductGUID > MSIPATCHREMOVE =< PatchGUID >
      retVal = string.Format("msiexec /I '{0}' MSIPATCHREMOVE='{1}'", database.SummaryInformation.Property[7], database.SummaryInformation.Property[9]);
      retVal = retVal.Replace("'", "\"");

      return retVal;
}

 

完成形

上記のような msi および msp のアンインストール用のコマンドの取得を、GUI 画面から操作可能なようにした実行ファイル、および ソースコードは GitHub 上で公開しています。
orca なしでアンインストールのコマンドを取得したい場合などにご利用ください。

 

参考サイト

なお、PowerShell および C# での msi や msp にアクセスする方法は、以下のようなサイトを参考にさせてもらいました。

参考1 : Enumerating installed MSI products with PowerShell and msi.dll
https://marcinotorowski.com/2018/03/04/enumerating-installed-msi-products-with-powershell/

参考2 : [VB.NET] MSI Manipulation 
https://www.neowin.net/forum/topic/968772-vbnet-msi-manipulation/

参考3 : Read Properties from an MSI File
http://www.alteridem.net/2008/05/20/read-properties-from-an-msi-file/

参考4 : 1で COM Microsoft Windows Installer Object Library を参照しようとした時のエラー回避方法

 

http://www.reinholdt.me/2015/07/29/problem-adding-a-c-reference-to-windowsinstaller-com-object/
%WINDIR%\system32\msi.dll をかわりに追加するとよい


参考5 : Windows SDK Components for Windows Installer Developers に含まれる View Installer Script の解説
https://docs.microsoft.com/en-us/windows/desktop/Msi/view-installer-script

Attachments

    Outcomes