##はじめに
業務アプリケーションで、ExcelやWordのアドインをVSTOで開発しています。
ExcelやWordは他の.NETアプリケーションからコマンド起動するのですが、何らかの原因でアドインが無効になってしまう事があり、業務に支障が出ていました。
無効になったアドインを有効化してからExcelやWordを起動する方法をまとめます。
アドインが読み込まれない原因
アドインが読み込まれない場合、以下のいずれかに登録されてしまっている事が原因です。
ExcelやWordの[ファイル]-[オプション]-[アドイン]で確認することができます。
- アクティブでないアプリケーションアドイン
- 無効なアプリケーションアドイン
アクティブでないアプリケーションアドイン
以下が原因で、アクティブでないアプリケーションアドインに登録される事があります。
- アドインの読み込み時にエラーがスローされた
- アドインの動作に時間がかかった
- アドインの動作時にエラーがスローされた
Microsoftのドキュメントでは、ソフトに無効化された VSTO アドインという表現が使われています。
https://docs.microsoft.com/ja-jp/visualstudio/vsto/how-to-re-enable-a-vsto-add-in-that-has-been-disabled#soft-disabled-vsto-add-ins
無効なアプリケーションアドイン
以下が原因で、無効なアプリケーションアドインに登録される事があります。
ExcelやWordがクラッシュする、よほどのエラーケースという事ですね。
- アドインが原因でExcel/Wordが予期せず終了した
Microsoftのドキュメントでは、ハードに無効化された VSTO アドインという表現が使われています。
https://docs.microsoft.com/ja-jp/visualstudio/vsto/how-to-re-enable-a-vsto-add-in-that-has-been-disabled#hard-disabled-vsto-add-ins
アドインが管理されているレジストリ
それぞれ、以下のレジストリエントリで管理されています。
アクティブでないアプリケーションアドイン
アクティブでないアプリケーションアドインに登録されているかどうかは、以下のレジストリを調べることで判断できます。
「Excel」の部分は「Word」「Outlook」でも同様です。
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Excel\Addins\<アドイン名>
LoadBehavior の値が "2"
(アクティブなアプリケーションアドインは"3")
LoadBehavior の値が "3"以外の場合、"3"に更新する、という処理で有効化できます。
参考:LoadBehavior の値
https://docs.microsoft.com/ja-jp/visualstudio/vsto/registry-entries-for-vsto-add-ins#loadbehavior-values
無効なアプリケーションアドイン
無効なアプリケーションアドインに登録されているかどうかは、以下のレジストリを調べることで判断できます。
「Excel」の部分は「Word」「Outlook」でも同様です。
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\<バージョン>\Excel\Resiliency\DisabledItems
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\<バージョン>\Excel\Resiliency\CrashingAddinList
※ <バージョン> には以下の数字が入ります
Outlook 2013 : 15.0
Microsoft 365 Apps / Outlook 2019 / Outlook 2016 : 16.0
これらのレジストリの値の名前はランダムで、値にはアドイン名がバイナリ値で格納されています。
アドイン名の判断が難しい場合は、CrashingAddinList や DisabledItems キーごと削除するでも良いかもしれません。
アドインを有効化するコード
上記のレジストリをチェックし、アドインを有効化するコードです。参考になれば幸いです。
using Microsoft.Win32;
private void checkAddin() {
var app = "Excel";
var addin = "hogeAddin";
//
// 「アクティブでないアプリケーションアドイン」のチェック
//
try
{
var regKey = $@"SOFTWARE\Microsoft\Office\{app}\Addins\{addin}";
using (var key = Registry.CurrentUser.OpenSubKey(regKey, true))
{
if (key == null)
{
MessageBox.Show("アドインがインストールされていません。");
return;
}
if (!int.Equals(key.GetValue("LoadBehavior", -1), 3)) {
// アクティブになっていないので「3」を設定する
key.SetValue("LoadBehavior", 3, RegistryValueKind.DWord);
}
}
}
catch (Exception e)
{
// エラーは無視
Console.Error.WriteLine("レジストリ[LoadBehavior]チェック:Exception\n" + e.ToString());
}
//
// 「無効なアプリケーションアドイン」のチェック
//
try
{
using (var key = Registry.CurrentUser.OpenSubKey($@"SOFTWARE\Microsoft\Office\{getOfficeVer()}\{app}\Resiliency\DisabledItems", true))
{
if (key != null)
{
key.GetValueNames()
.ToList()
.ForEach(val =>
{
var data = (byte[])key.GetValue(val, null);
if (data != null)
{
// キーで読みだした値から「0」を除去して結合。ASCIIから文字列を取得し、アドイン名が含まれている場合は該当のレジストリを消去。
if (System.Text.Encoding.UTF8.GetString(data.ToList().Where(v => v != 0).ToArray()).Contains($"{addin}"))
{
key.DeleteValue(val);
}
}
});
}
}
}
catch (Exception e)
{
// エラーは無視
Console.Error.WriteLine("レジストリ[DisabledItems]チェック:Exception\n" + e.ToString());
}
try
{
using (var key = Registry.CurrentUser.OpenSubKey($@"SOFTWARE\Microsoft\Office\{getOfficeVer()}\{app}\Resiliency\CrashingAddinList", true))
{
if (key != null)
{
key.GetValueNames()
.ToList()
.ForEach(val =>
{
var data = (byte[])key.GetValue(val, null);
if (data != null)
{
// キーで読みだした値から「0」を除去して結合。ASCIIから文字列を取得し、アドイン名が含まれている場合は該当のレジストリを消去。
if (System.Text.Encoding.UTF8.GetString(data.ToList().Where(v => v != 0).ToArray()).Contains($"{addin}"))
{
key.DeleteValue(val);
}
}
});
}
}
}
catch (Exception e)
{
// エラーは無視
Console.Error.WriteLine("レジストリ[CrashingAddinList]チェック:Exception\n" + e.ToString());
}
}