前提として、Excelバージョンに依存しない様にラッパークラスであるMicrosoft.Office.Interop.Excelは利用せずに、遅延バインディングしたいと思っております。
64ビットビルドすると、
Type.GetTypeFromProgID("Excel.Application")
で取得したTypeからGetEventsメソッドやGetMethodsメソッドを呼んでも
Microsoft.Office.Interop.Excel.Applicationクラスの
のイベントやメソッドが取得できません。
ここでイベントが取れない為、イベントハンドラーが登録できず困りました。
まさに下記ページの方法を行おうとしておりますが、64ビットビルドだとGetEventメソッドの戻り値がnullになってしまいイベントが取れません。32ビットビルドでは正常に動作します。
https://littlepower-suesan.hatenadiary.org/entry/20110628/1309266642
このページの方法は試しておりませんが、GUID指定によりExcelバージョンに依存してしまう為除外しています。
https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/dc59b406-3f86-4fac-817a-f4fafd3ffdb9/36933243101249612452125311248712451125311246412391excel1239812452?forum=csharpgeneralja
見識のある方がいらっしゃいましたら、よろしくお願いします。
2020年1月5日18時00分追記
環境検証、ソースコード、実行結果を記載します。
検証環境
OS:Windows10 20H2
ビルド環境:Microsoft Visual Studio Professional 2019 Version 16.11.3
フレームワーク:.NET Framework4.8
Excel2013 15.0.5381.1000 32ビット
C#
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Reflection; 5using System.Threading.Tasks; 6using System.Windows.Forms; 7using System.Threading; 8namespace WindowsFormsApp13 { 9 10 static class Program { 11 12 [STAThread] 13 static void Main() { 14 Console.WriteLine("ビルド:"+(IntPtr.Size==4?"32ビット":"64ビット")); 15 16 Type objeType = Type.GetTypeFromProgID("Excel.Application"); 17 18 dynamic _APPLICATION = Activator.CreateInstance(objeType); 19 20 _APPLICATION.Visible = true; 21 22 EventInfo eventInfo = _APPLICATION.GetType().GetEvent("SheetSelectionChange"); 23 24 if(eventInfo!=null){ 25 Console.WriteLine("OK"); 26 27 Type eventType = eventInfo.EventHandlerType; 28 29 Type type = typeof(Program); 30 31 MethodInfo methodInfo = type.GetMethod("SheetSelectionChangeEvent"); 32 33 Delegate d = Delegate.CreateDelegate(eventType, methodInfo); 34 35 eventInfo.AddEventHandler(_APPLICATION, d); 36 }else{ 37 Console.WriteLine("NG"); 38 } 39 Console.ReadKey(); 40 } 41 42 public static void SheetSelectionChangeEvent(object sheet, object range){ 43 Console.WriteLine("SheetSelectionChangeEvent"); 44 } 45 } 46}
実行結果はビルド毎に下記の通りとなりました。
・32ビットビルド時
※起動したエクセルで新規ファイルを開いてセル選択を何度か実行
ビルド:32ビット
OK
SheetSelectionChangeEvent
SheetSelectionChangeEvent
SheetSelectionChangeEvent
SheetSelectionChangeEvent
・64ビットビルド時
ビルド:64ビット
NG
2020年1月6日15時00分追記
現象が出るマシンと出ていないマシンがあり、
環境に依存して現象が発生しているようです。
現象が出るマシンと出ていないマシンの違いは次の通りでした。
現象が出ているマシンで64ビットビルドしたものは、
Type.GetTypeFromProgID("Excel.Application")で
Typeとして、「System.__ComObject」が返って来ていました。
しかし32ビットビルドだと
Typeとして、「Microsoft.Office.Interop.Excel.ApplicationClass」が
返って来ます。
現象が出ていないマシンでは、
32ビットと64ビットのどちらでも、
Typeとして、「Microsoft.Office.Interop.Excel.ApplicationClass」が返って来ます。
COMオブジェクトの場合はGetType()をすると「System.__ComObject」という
クラスで取得されることもあるようです。
どのようなケースでそうなるか明確な情報は見つけられませんでした。
下記URLでも類似の現象が出ており、
Excel(ストアアプリ)→ オフィス2016のデスクトップ版
の変更により解消した様です。
しかしストアアプリでも遅延バインディングは利用できる為、今回現象とは関係ないかもしれません。
https://social.technet.microsoft.com/Forums/Windows/ja-JP/77942146-7be9-4409-81cc-aa19e1ba4ad9/1245012503125221236312425excel12364216281240320986123791239412356?forum=Office2016ITProJP
回答3件
あなたの回答
tips
プレビュー