プロセスハンドルから判定する方法
StackOverflowに回答したやつ。
OfficeアプリのCOMオブジェクトを作成するとプロセスが起動されるので、そのプロセスハンドルを IsWow64Processで判定を行っています。
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
public class ExcelUtility
{
[DllImport("kernel32.dll")]
private static extern bool IsWow64Process(
IntPtr hProcess,
out bool Wow64Process
);
/// <summary>
/// インストールされているExcelが32bitかどうかを取得する。
/// </summary>
/// <returns>true:32bit false:64bit null:インストールされていない等で確認不能。</returns>
/// <remarks>dynamic型のコンパイルが通らない場合、Microsoft.CSharpを参照に追加する。</remarks>
public static bool? IsExcel32Bit()
{
bool? result;
dynamic app = null;
try
{
//ProgIDからOfficeアプリのCOMのTypeを取得する。
//EXCEL:"Excel.Application"
//ACCESS:"Access.Application"
//Word:"Word.Application"
var appType = Type.GetTypeFromProgID("Excel.Application");
if (appType == null)
{
return null;
}
//64bitOSじゃない場合は無条件で32bit
if (!Environment.Is64BitOperatingSystem)
{
return true;
}
//COMオブジェクトを作成し、対象アプリのプロセス名を検索する。
//EXCEL:"EXCEL"
//ACCESS:"MSACCESS"
//WORD:"WINWORD"
app = Activator.CreateInstance(appType);
var procs = Process.GetProcessesByName("EXCEL");
if (procs.Length == 0)
{
return null;
}
//プロセスの実行にWOW64が使用されているかどうか確認する。
//(使用されていたら32bit)
bool bWow64;
if (!IsWow64Process(procs[0].Handle, out bWow64))
{
return null;
}
result = bWow64;
}
catch (COMException)
{
//インストールされていない場合はここにくる
return null;
}
finally
{
if (app != null)
{
//アプリ停止&解放
app.Quit();
Marshal.ReleaseComObject(app);
app = null;
//GCを強制
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
return result;
}
}
レジストリの有無から判定する方法
レジストリから64bitOSに32bit版を入れている場合に存在しないキーをチェックしています。
using Microsoft.Win32;
using System;
using System.Runtime.InteropServices;
public class ExcelUtility2
{
/// <summary>
/// インストールされているExcelが32bitかどうかを取得する。
/// </summary>
/// <returns>true:32bit false:64bit null:インストールされていない等で確認不能。</returns>
public static bool? IsExcel32Bit()
{
try
{
//ProgIDからOfficeアプリのCOMのTypeを取得する。
//EXCEL:"Excel.Application"
//ACCESS:"Access.Application"
//Word:"Word.Application"
var appType = Type.GetTypeFromProgID("Excel.Application");
if (appType == null)
{
return null;
}
//64bitOSじゃない場合は無条件で32bit
if (!Environment.Is64BitOperatingSystem)
{
return true;
}
# pragma warning disable CA1416
//TypeのGUIDから64bit用のレジストリを検索する。
string keyPath = $@"CLSID\{appType.GUID:B}\ProgID";
using (var regRoot = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64))
using (var reg = regRoot.OpenSubKey(keyPath))
{
return (reg == null);
}
# pragma warning restore CA1634
}
catch (COMException)
{
return null;
}
}
}