cominterop.net-4.0c#-4.0.net-4.0-beta-2

Is PIA embedding broken in .NET 4.0 beta 2?


A while ago, I wrote some Word interop examples in Visual Studio beta 1, and set the reference to Microsoft.Office.Interop.Word to be embedded (set the "Embed Interop Types" = true in the reference properties). These worked fine, and I haven't run them for a while... until today.

Of course, now I'm running under beta 2 of both Visual Studio 2010 and .NET 4.0 - and it seems to be somewhat broken.

Here's the code in question (just dummy example code):

using Microsoft.Office.Interop.Word;

class WordImprovement1
{
    static void Main()
    {
        Application app = new Application { Visible = true };
        app.Documents.Add();
        Document doc = app.ActiveDocument;            
        Paragraph para = doc.Paragraphs.Add();
        para.Range.Text = "Thank goodness for C# 4";

        object filename = "demo.doc";
        object format = WdSaveFormat.wdFormatDocument97;
        doc.SaveAs(FileName: ref filename, FileFormat: ref format);
        doc.Close();
        app.Quit();
    }
}

Here's the exception I get most of the time, when "Embed Interop Types" is set to "true" or I link with "/l" on the command line:

System.MissingMethodException: Method not found:
'Void Microsoft.Office.Interop.Word._Application.set_Visible(Boolean)'.
   at WordImprovement1.Main()

Very occasionally, it works - which is even more bizarre.

If I set "Embed Interop Types" to "false" (or use /r on the command line instead of /l) it all works fine.

If I remove the "Visible = true" property setter it works too... but I know that property's there... it's even suggested by IntelliSense!

While I haven't done exhaustive testing on multiple boxes, I can confirm that my netbook (running Windows 7 instead of Vista, but still .NET 4.0 beta 2) sees the same problem.

Any suggestions as to whether it's me that's broken or .NET 4.0 beta 2?


Solution

  • Great catch! This looks like a bug in our code generation for indexed properties (not a known one, so thanks for reporting this!) I've tried on the latest internal build of VS 2010 and it reproduces as well.

    What happens is that if you use an object initializer, then the following code is generated:

    Application <>g__initLocal19 = (Application) Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("000209FF-0000-0000-C000-000000000046")));
    <>g__initLocal19.set_Visible(true);
    

    However if you set Visible = true in a separate statement (without the object initializer), then the following code is emitted:

    Application application = (Application) Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("000209FF-0000-0000-C000-000000000046")));
    application.Visible = true;
    

    The PIA only defines the bottom one, hence it fails when you're using an object initializer. The workaround for now is to set Visible in a separate statement which should work fine.

    I've logged a bug about this. Thanks again!