ナレッジ ベース KB0207

Add-in Expressに基づいてアドインを使用するとExcelがクラッシュする

問題

Excelがクラッシュし、Add-in Expressを使用する別のアドインをインストールしました

Add-in Expressに基づくアドインでは、[Excelオプション] ダイアログにadxloader.dllが表示されます([ファイル] → [オプション] → [アドイン])。

原因

think-cellのようなサードパーティーのアドインを追加して使用すると、Add-in Expressの既知のバグがExcelクラッシュの原因になる可能性があります。この問題の要約と詳細な説明は以下のとおりです。

弊社はこの問題をAdd-in Expressに報告しています。Add-in Expressサポートに修正プログラムを依頼する場合は、バグ問い合わせ番号#9291.を使用してください。

要約

Add-in Expressがウィンドウのサブクラスを解除した後も、保存されていたウィンドウ プロシージャ アドレス(まだ最新状態であると想定)を使用してメッセージを送ります。サブクラス解除と保存されたウィンドウのプロシージャ アドレスの使用の間に別のサブクラス解除が発生すると、ウィンドウ プロシージャ アドレスは最新でなくなるため、誤ったウィンドウ プロシージャが呼び出されます。

詳細

この再現では、問題の原因はEXCEL7ウィンドウのサブクラスにあります(トレースHWND=004301e4)。

ウィンドウを開く

まず、think-cellはSetWindowSubclassでサブクラスを作成します。SetWindowLongは中央機関COMCTL32から呼び出され、ウィンドウ プロシージャをEXCELからCOMCTL32に変更します。

TRACE 2016-08-04T09:36:21Z thread 9052 tcaddin\detour\win\safesubclassimpl.cpp(215): 
Module C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.COMMON-CONTROLS_6595B64144CCF1DF_6.0.7601.18837_NONE_41E855142BD5705D\COMCTL32.DLL 6.10.7601.18837+0x1410A 
is subclassing window HWND 004301E4 Caption "Book2" Class EXCEL7 WndProc 
C:\PROGRAM FILES (X86)\MICROSOFT OFFICE\OFFICE15\EXCEL.EXE 15.0.4841.1000+0x21A55 Style 0x570B0000 ExStyle 0x00000000 
to C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.COMMON-CONTROLS_6595B64144CCF1DF_6.0.7601.18837_NONE_41E855142BD5705D\COMCTL32.DLL 6.10.7601.18837+0x2F45C

その後、Add-in ExpressはSetWindowLongを直接呼び出してサブクラスを作成し、ウィンドウ プロシージャをCOMCTL32からAdd-in Express JITed C# code (no module name, got JITed into memory):に変更します。

TRACE 2016-08-04T09:36:21Z thread 9052 tcaddin\detour\win\safesubclassimpl.cpp(215): 
Module 0x06B7FB84 is subclassing window HWND 004301E4 Caption "Book2" Class EXCEL7 
WndProc C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.COMMON-CONTROLS_6595B64144CCF1DF_6.0.7601.18837_NONE_41E855142BD5705D\COMCTL32.DLL 6.10.7601.18837+0x2F45C Style 0x570B0000 ExStyle 0x00000000 to 0x1D47BD7E

ウィンドウを閉じる

Add-in Expressは最後だったので、チェーンで最後になります。SetWindowLongを直接呼び出すとクリーンにサブクラスを解除し、ウィンドウ プロシージャをAdd-in Express JITed C# code back to COMCTL32:から変更できます。

TRACE 2016-08-04T09:36:27Z thread 9052 tcaddin\detour\win\safesubclassimpl.cpp(215): 
Module 0x090CD19C is subclassing window HWND 004301E4 Caption "Book2" Class EXCEL7 
WndProc 0x1D47BD7E Style 0x470B0000 ExStyle 0x00000000 to 
C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.COMMON-CONTROLS_6595B64144CCF1DF_6.0.7601.18837_NONE_41E855142BD5705D\COMCTL32.DLL 6.10.7601.18837+0x2F45C

その後、think-cellはRemoveWindowSubclassでサブクラスを解除します。SetWindowLongは中央機関COMCTL32から呼び出され、ウィンドウ プロシージャをCOMCTL32からEXCELに変更します。

TRACE 2016-08-04T09:36:37Z thread 9052 tcaddin\detour\win\safesubclassimpl.cpp(215): 
Module C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.COMMON-CONTROLS_6595B64144CCF1DF_6.0.7601.18837_NONE_41E855142BD5705D\COMCTL32.DLL 6.10.7601.18837+0x1438F 
is subclassing window HWND 004301E4 Caption "Book2" Class EXCEL7 WndProc 
C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.COMMON-CONTROLS_6595B64144CCF1DF_6.0.7601.18837_NONE_41E855142BD5705D\COMCTL32.DLL 6.10.7601.18837+0x2F45C Style 0x470B0000 ExStyle 0x00000000 
to C:\PROGRAM FILES (X86)\MICROSOFT OFFICE\OFFICE15\EXCEL.EXE 15.0.4841.1000+0x21A55

ここまでは順調です。ただし、ここで問題が生じます。COMCTL32は再びウィンドウ プロシージャを変更します。今回は、EXCEL.EXEからDefWindowProcのアドレスに変わります。

TRACE 2016-08-04T09:36:41Z thread 9052 tcaddin\detour\win\safesubclassimpl.cpp(215): 
Module C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.COMMON-CONTROLS_6595B64144CCF1DF_6.0.7601.18837_NONE_41E855142BD5705D\COMCTL32.DLL 6.10.7601.18837+0xDEC4C 
is subclassing window HWND 004301E4 Caption "Book2" Class EXCEL7 WndProc 
C:\PROGRAM FILES (X86)\MICROSOFT OFFICE\OFFICE15\EXCEL.EXE 15.0.4841.1000+0x21A55 Style 0x470B0000 ExStyle 0x00000000 
to C:\WINDOWS\SYSWOW64\NTDLL.DLL 6.1.7601.23455+0x22FBD (=DefWindowProc)

think-cellのみでは、これは発生しません。問題なのは、COMCTL32がなぜこのような動作をするかという点です。ウィンドウ プロシージャをEXCEL.EXEから取り上げるのは明らかに誤っています。ここで、SetWindowLongを呼び出すCOMCTL32につながるコール スタックが使われます。

tcaddin.dll!SetWindowLongPtrW (HWND__ * __formal, int __formal, long __formal) 
with hWnd=004301e4, which is our EXCEL7 window, and dwNewLong= 77102FBD=DefWindowProc
comctl32.dll!_SubclassDeath@16 () Unknown
COMCTL32 realizes that it gets called for a window that it is no longer associated 
with. It must think this is happening from a subclassing chain and reacts in panic by SetWindowLong(DefWindowProc) to ensure this never happens again.

comctl32.dll!_MasterSubclassProc@16 () Unknown
user32.dll!_InternalCallWinProc@20 () Unknown
user32.dll!_UserCallWinProcCheckWow@32 () Unknown
user32.dll!_CallWindowProcAorW@24 () Unknown

user32.dll!_CallWindowProcW@20 () Unknown
Someone (presumably Add-in Express) calls CallWindowProc with lpPrevWndFunc=6e32f45c, which is COMCTL::MasterSubclassProc hWnd=004301e4, which is our EXCEL7 window, Msg=00000002=WM_DESTROY, wParam=00000000, lParam=00000000
This is clearly wrong, COMCTL32 is no longer associated with our EXCEL7 window.

090c6dba() Unknown
[Frames below may be incorrect and/or missing]
090c1cce() Unknown
06b7fe7c() Unknown

081dd1ce() Unknown
code with no module is entered here from the CLR, probably JIT'ed code of 
Add-in Express

clr.dll!UM2MThunk_Wrapper(void *) Unknown
clr.dll!Thread::DoADCallBack(struct ADID,void (*)(void *),void *,int) Unknown
clr.dll!_UM2MDoADCallBack@16 () Unknown
081dd227() Unknown
user32.dll!_InternalCallWinProc@20 () Unknown
user32.dll!_UserCallWinProcCheckWow@32 () Unknown
user32.dll!_DispatchClientMessage@24 () Unknown
user32.dll!___fnDWORD@4 () Unknown
ntdll.dll!_KiUserCallbackDispatcher@12 () Unknown
user32.dll!_NtUserDestroyWindow@4 () Unknown

結論

Add-in Expressがウィンドウのサブクラスを解除した後、保存されていたウィンドウ プロシージャ アドレス(まだ最新状態であると想定)を使用してメッセージを送ります。サブクラス解除と保存されたウィンドウのプロシージャ アドレスの使用の間に別のサブクラス解除が発生すると、ウィンドウ プロシージャ アドレスは最新でなくなるため、誤ったウィンドウ プロシージャが呼び出されます。

サポートに問い合わせ

KB0091で説明されているように、Add-in Expressを使用するアドインを一時的に非アクティブ化してください。

  • Add-In Expressを使用しているアドインがアクティブな場合にのみこの問題が発生するのであれば、このアドインのベンダーに連絡してください。通常、お客様がベンダーとサポート ケースを開始するのが最も効果的です。

  • 他のアドインを非アクティブ化した後もthink-cellで問題が発生する場合は、弊社のサポート チームに連絡してください

    think-cellログ ファイルを送ってください。このためにはPowerPointを開き、[挿入] → [think-cell] → [その他] その他のメニュー→ [サポートのリクエスト] を選択します。ログ ファイルは自動的に新しい電子メールに添付されます。

    これがうまくいかない場合、ログ ファイルは下記の方法で見つけられます。

    • 新しいWindows Explorerウィンドウを開き、

      %LOCALAPPDATA%\think-cell

      と入力してEnterを押します。

    • ディレクトリを参照したいのに表示されない場合は、おそらく非表示に設定されています。これは以下をチェックすると、Windows Explorerで変更できます。

      • Windows VistaおよびWindows 7:
        整理、 → フォルダーと検索オプション、 → 表示、 → 非表示のファイルとフォルダーを表示する
      • Windows 8、Windows 8.1、Windows 10:
        表示、 → 表示/非表示、 → 非表示の項目
    • このフォルダーに含まれており、拡張子が「.log」のファイルをすべて、弊社のサポート チームにお送りください。以下のファイルのいずれでも構いません:POWERPNT_log.log, EXCEL_log.log, TCMAIL_log.log, TCUPDATE_log.log, TCRUNXL_log.log, PPTTC_log.log, setup_think-cell_xxxxx_log.log.