Hello everybody,
Because my application has to target multiple versions of Office I've chosen to use late binding. I don't want to hard code the constants (for example Outlook.OlItemType.olMailItem) but to get them at runtime through late binding.
How could I do this from C# or Visual Basic .NET
Best regards,
Gabriela

Office automation - getting a built-in constant with late binding from .NET
BellaTrenkova
Hi folks!
I had quite a similar problem lately, and I maybe found quite an easy way to "hard-code" these things.
Take a look at http://www.aurigma.com/Products/COMtoNET/. These guys made something similar to TlbImp.exe, but it works a bit better.
Give it a try, you have nothing to lose, I guess
CU
Q
Tan Phan
Hi Geoff,
Yes, you understood me right. With Type.GetTypeFromCLSID I can activate the type and as you said I can't use it further, or maybe we don't know how to do it.
Thank you very much for posting my question to the other forums. I'll keep an eye on them too.
Best Regards,
Gabriela
Paul Ruth
Hi Gabriela,
I didn't actually post your question to the other forums (I don't have an easy way of doing that), so if you'd like get some additional opinions, you'll need to make the posts there yourself.
One thing I meant to mention is that you can always search the typelib yourself using Com Interop to call the ITypeLibrary or ITypeInfo interfaces.
Sincerely,
Geoff Darst
Microsoft VSTO Tools
Allen Lewis
Hi Gabriela,
I understand what you are trying to do. You want to know how to use reflection to access Outlook.OlItemType.olMailItem via COM interop without having to provide metadata.
To clear up some of the confusion from earlier posts, COM interop does not require metadata (i.e a PIA) to late bind to COM types via reflection. However, if you don't have metadata, you have limited options for late-bound activation. Basically, the only way you can activate a type is through Type.GetTypeFromProgID or Type.GetTypeFromCLSID. Furthermore, the RCW that is created for the type is the generic __ComObject, so you can't reflect on it to get any useful information. So the problem as I see it is that while you can activate certain CoClasses within the Outlook OM, there is no way to get from there to the constants that you need. So my conclusion is that you can't do this without metadata.
However, before taking my word for it, I would try posting this question in a couple of other places. I'd try the Common Language Runtime Forum on MSDN and the interop newsgroup. Maybe somebody else out there knows a way of doing this that I'm not aware of. Links are below.
http://forums.microsoft.com/MSDN/ShowForum.aspx ForumID=44&SiteID=1
http://groups.google.com/group/microsoft.public.dotnet.framework.interop lnk=sg&hl=en
Sincerely,
Geoff Darst
Microsoft VSTO Team
Christian B
Babriela, you can do this by using reflection. Here is a sample. BTW: you need to use FlattenHierarchy to make things like constants appear (I wrote this example about glass, because I have a brother-in-law who is an expert glass blower. Great Christmas gifts.).
namespace TestReflection
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender,EventArgs e)
{ Glass glass = new Glass();
System.Reflection.FieldInfo fieldInfo = this.GetType()
.GetField("GlassType");
Type t = typeof(Glass);
FieldInfo info = t.GetField("GlassType",
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.FlattenHierarchy);
Console.WriteLine(info.GetValue(null));
}
}
}
class Glass
{
public const string GlassType = "Clear";
}
HTH!
John.
Umapathy
Hi John,
Of course with reflection....but I mean the Office constants there and this means another assembly to which I get access through COM Interop.
To be more clear, here a bit of code:
Type outlookType;
outlookType = Type.GetTypeFromProgID("Outlook.Application");
outlookApplication = Activator.CreateInstance(outlookType);
parameters =
new object[1];parameters[0] = 0; //instead of 0 i would like to get the Outlook.OlItemType.olMailItem constant with Reflection
outlookMessage = outlookApplication.GetType().InvokeMember( "CreateItem",
BindingFlags.InvokeMethod, null, outlookApplication, parameters );
I've tried in many ways and I also got to a point where it was working but only with the Office 2003 PIAs installed :-(
Regards,
Gabriela
Cam.sanchez
Misha,
I understood your "static binding" solution and I considered this solution before ending up using late binding. Even if late binding appears to be kind of a black sheep it's an easy solution and on my opinion the best if one needs to provide just a basic Office integration but staying version independent, starting with a particular Office version, of course.
I totally agree with you that hardcoding is very ugly :-)
Best regards,
Gabriela
EdMellor
Hi John,
Because for Office 2000 there are no PIAs and my application must work with any Office version starting with Office 2000. So my only solution was late binding.
Is there any way to get the constants at run time with reflection Hardcoding them doesn't sound very safe to me.
Regards,
Gabriela
phensahw
Gabriela,
Why are you trying to do this without the PIAs installed
John.
kundalani
Misha,
As I said previously, unfortunately I can't rely on PIA and I have no early binding there. And the point is exactly to get the type.
Regards,
Gabriela
Winman
John,
I just need a hint about how to get a constant value as in my example code.
I know that late binding is the last solution of all but in my case it's the only one. I've spent three weeks on researching and trying and late binding is the solution to meet the requirements.
Hopefully you can help me with this bit of info.
Best Regards,
Gabriela
Bill Gammill
OlItemType is an enum. One can not use COM's dynamic type discovery on it because enums are not IDispatch-derived classes. You either need to load a type-library or you will need to ship with 3 Outlook Interop Assemblies (one for Outlook 2000, one for Outlook 2002 and one for Outlook 2003 - you can pre-create those using the tlbimp utility). At runtime you can dynamically determine which version of IA you need load, then reflect on the type in the assembly and get the definition.
All this sounds like a lot of work and may be you are better off just using the hard-coded values.
Derrix Sture-Tucker
Gabriela,
I see your problem. As you know, Office 2000 has no PIAs, but if you are going to create .NET applications for Office 2000, you still need to create your own wrapper of sorts for the Office 2000 OMs that you are going to use. Just know that you are in unsupported territory there, so there is no guarantee that anything is going to work even if your code seems to be correct.
With this wrapper around the COM lib you can use reflection to inspect the properties, methods, events, enums etc. of the various object types. But, again, this may not work with Office 2000, and we do not recommend this approach because it is unsupported.
Let me know if you need further help on this. I'll wait another week or so and count this post as the answer unless I hear some news from you.
Thanks for being so enthused about .NET/Office development, Gabriela!
John.
Juan Pablo-MCAD
Hi Gabriela,
I am not clear what you want to reflect on, but suppose you know how to load the PIAs dynamically and you want to reflect on this PIA. I guess you could use System.Enum.Parse method to get to the actual value. Here is some code
System.
Type t = typeof(Outlook.OlItemType); int olMailItemValue = (int)System.Enum.Parse(t, "olMailItem");If you are interested to learn more the relevant article is http://msdn.microsoft.com/msdnmag/issues/01/10/net/