[C#] インストールされているOfficeアプリのBit数を判定する


# プロセスハンドルから判定する方法
StackOverflowに回答したやつ。
OfficeアプリのCOMオブジェクトを作成するとプロセスが起動されるので、そのプロセスハンドルを [IsWow64Process](https://docs.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-iswow64process)で判定を行っています。

https://ja.stackoverflow.com/questions/78142/


```cs
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版を入れている場合に存在しないキーをチェックしています。

```cs
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;
        }
    }
}
```