Home > OS >  C# class instance displays property values but does not allow direct referral
C# class instance displays property values but does not allow direct referral

Time:08-05

Why would outlook.Version display error CS1061: 'Application' does not contain a definition for 'Version' when the value is clearly 16.0.0.14326?

Building on this question: Outlook Interop - 'Class' does not contain a definition for 'Property'

I think I've zeroed in on what the issue is here. Printing the outlook instance in the immediate window yields this:

{Microsoft.Office.Interop.Outlook.ApplicationClass}
    AnswerWizard: '((Microsoft.Office.Interop.Outlook.ApplicationClass)outlook).AnswerWizard' threw an exception of type 'System.Runtime.InteropServices.COMException'
    Application: {Microsoft.Office.Interop.Outlook.ApplicationClass}
    Assistance: {System.__ComObject}
    Assistant: {System.__ComObject}
    COMAddIns: {System.__ComObject}
    Class: olApplication
    DefaultProfileName: "Outlook"
    Explorers: {Microsoft.Office.Interop.Outlook.ExplorersClass}
    FeatureInstall: msoFeatureInstallOnDemand
    Inspectors: {Microsoft.Office.Interop.Outlook.InspectorsClass}
    IsTrusted: false
    LanguageSettings: {System.__ComObject}
    Name: "Outlook"
    Parent: null
    PickerDialog: {System.__ComObject}
    Reminders: {Microsoft.Office.Interop.Outlook.RemindersClass}
    Session: {Microsoft.Office.Interop.Outlook.NameSpaceClass}
    TimeZones: {Microsoft.Office.Interop.Outlook.TimeZonesClass}
    Version: "16.0.0.14326"

But trying to print literally any property of the outlook instance, even ones that should seemingly give straightforward values like outlook.Version, gives me does not contain a definition for errors. Intellisense happily autofills these properties and at least some of them clearly have values. What's going on?


Update, following @SimonMourier's suggestion to use:

dynamic outlook = Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application"));

works, and I'd love to understand more about why it does. For example, it returns exactly the same values when the instance is printed:

{Microsoft.Office.Interop.Outlook.ApplicationClass}
    AnswerWizard: '((Microsoft.Office.Interop.Outlook.ApplicationClass)outlook).AnswerWizard' threw an exception of type 'System.Runtime.InteropServices.COMException'
    Application: {Microsoft.Office.Interop.Outlook.ApplicationClass}
    Assistance: {System.__ComObject}
    Assistant: {System.__ComObject}
    COMAddIns: {System.__ComObject}
    Class: olApplication
    DefaultProfileName: "Outlook"
    Explorers: {Microsoft.Office.Interop.Outlook.ExplorersClass}
    FeatureInstall: msoFeatureInstallOnDemand
    Inspectors: {Microsoft.Office.Interop.Outlook.InspectorsClass}
    IsTrusted: false
    LanguageSettings: {System.__ComObject}
    Name: "Outlook"
    Parent: null
    PickerDialog: {System.__ComObject}
    Reminders: {Microsoft.Office.Interop.Outlook.RemindersClass}
    Session: {Microsoft.Office.Interop.Outlook.NameSpaceClass}
    TimeZones: {Microsoft.Office.Interop.Outlook.TimeZonesClass}
    Version: "16.0.0.14326"

So why do they not return property values in the same way? Why do I get definition errors with new Outlook.Application() but no definition errors with Activator.CreateInstance()?


In making an MVC example for @SimonMourier, I performed the following steps:

  1. New C# .NET Framework 4.7.2 console desktop app project

  2. Add Reference --> COM --> Outlook 16.0 Object Library

  3. Added the below code to Main():

    dynamic outlook2 = Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application"));
    var outlook = new Microsoft.Office.Interop.Outlook.Application();
    Console.WriteLine(outlook.Version);
    
    outlook2.Quit();
    outlook.Quit();
    
  4. Break on outlook2.Quit();

  5. As written, outlook.Version properly returns "16.0.0.14326"

  6. When commenting out Console.WriteLine(outlook.Version);, outlook.Version returns error CS1061: 'Application' does not contain a definition for 'Version'

  7. outlook2.Version always properly returns "16.0.0.14326"

Why does writing a value to the console affect the ability to properly return a property?

CodePudding user response:

I actually cannot reproduce the problem in the question, but another way of calling COM object that support COM Automation (IDispatch interface, typelibs, etc.) such as Microsoft Office Applications is to use the C# dynamic keyword that was introduced with C# 4.

So, in the Outlook example, you can just create the Outlook Application object with this code (without creating any reference or using any PIA, you just need Outlook to be installed correctly):

dynamic outlook = Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application"));

And then call any method or property just as you would if autocompletion did not exist:

Console.WriteLine(outlook.Version); // C# will dynamically call for a property named "Version"

Notes: name resolution happens at runtime, and the main drawback is you don't have autocompletion, so, with big models hierarchies like Outlook, it can be difficult to work with.

  • Related