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

2794
0
08-15-2018 09:58 PM
Labels (1)

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

はじめに

弊社が運営している 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

Labels (1)
Tags (3)
Version history
Last update:
‎12-12-2021 03:42 AM
Updated by: