12

I try to implement a reflection-based late-bound library to Microsoft Office. The properties and methods of the Offce COM objects are called the following way:

Type type = Type.GetTypeFromProgID("Word.Application");
object comObject = Activator.CreateInstance(type);
type.InvokeMember(<METHOD NAME>, <BINDING FLAGS>, null, comObject, new object[] { <PARAMS>});

InvokeMember is the only possible way because Type.GetMethod / GetProperty works improperly with the COM objects.

Methods and properties can be called using InvokeMember but now I have to solve the following problem:

Method in the office-interop wrapper:

Excel.Workbooks wb = excel.Workbooks;
Excel.Workbook firstWb = wb[0];

respectively

foreach(Excel.Workbook w in excel.Workbooks)
  // doSmth. 

How can I call the this[int index] operator of Excel.Workbooks via reflection?

tobias-kutter
  • 269
  • 2
  • 10

3 Answers3

9

I might have missunderstood your question, but hopefully this helps some.

This gets the n:th workbook when you have a workbook:

typeof(Workbooks).GetMethod("get_Item").Invoke(excel.Workbooks, new object[] { n });

GetMethod seems to work spendidly for me though, what version of .NET are you using?

Otherwise this might work:

typeof(Workbooks).InvokeMember("Item", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, excel.Workbooks, new object[] { n });

This one (Count) is also highly useful:

typeof(Workbooks).InvokeMember("Count", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, excel.Workbooks, null).

To get the workbooks if type is the excel type:

type.InvokeMember("Workbooks", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, excel.Workbooks, null)
flindeberg
  • 4,887
  • 1
  • 24
  • 37
0

Try invoking "get_Item".

Thats how indexed properties are compiled, as members called get_Item.

CSharpie
  • 9,195
  • 4
  • 44
  • 71
0

I have solved my problem by enumerating the COM object:

public Workbook this[int iIndex]
{
 get
 {
  int c = 0;
  foreach (Workbook wb in this)
  {
   if (c == iIndex)
     return wb;
   c++;
  }
  return null;
 }
}

// ...

// The Workbook object is a wrapper for the COM object Excel.Workbook
IEnumerator<Workbook> IEnumerable<Workbook>.GetEnumerator()
{
 foreach (var obj in (IEnumerable)m_COMObject)
  yield return obj == null ? null : new Workbook(obj, this);
}

I know it's an unpleasant solution but it works. :-)

thanks for your help

tobias-kutter
  • 269
  • 2
  • 10
  • You solved your issue but you did NOT answer your question correctly. When someone searches for your specific problem he may find this question but the answer which is marked as correct is not the one he is looking for. Please refactor your question/answer. – Felix K. Nov 05 '12 at 13:20