Home » excel » C# .NET Error Attaching to Running Instance of Office Application

C# .NET Error Attaching to Running Instance of Office Application

Posted by: admin April 23, 2020 Leave a comment

Questions:

I am working on an Excel Addin using C#, Visual Studio 2012. I am trying to get the instance of Excel’s Application object so as to keep track of the currently active workbook and worksheet (ActiveWorkbook, ActiveWorksheet).

I see that most other related questions on SO have replies suggesting to use the following:

(Excel.Application)Marshal.GetActiveObject("Excel.Application");

I have also tried using this:

(Excel.Application)Globals.ThisAddIn.Application;

In both of the cases I get NullReferenceException. After looking at the workaround suggested here: http://support.microsoft.com/kb/316125/en-us, I tried the following to test both methods.

public CurrentSpreadSheet()
    {
        try
        {
            this.CurrentApplication = (Excel.Application)Globals.ThisAddIn.Application;

        }
        catch (NullReferenceException)
        {
            MessageBox.Show("Excel application object not registered. Trying plan B..");

            //Getting Excel's application object instance
            int iSection = 0, iTries = 0;

        tryAgain:
            try
            {
                iSection = 1; //Attempting GetActiveObject
                this.CurrentApplication = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
                iSection = 0; //GetActiveObject succeeded so resume or go for normal error handling if needed
                this.CurrentApplication.Visible = true;
            }
            catch (Exception err)
            {
                System.Console.WriteLine("Visual C# .NET Error Attaching to Running Instance of Office Application .. yet.");
                if (iSection == 1)
                {
                    //GetObject may have failed because the
                    //Shell function is asynchronous; enough time has not elapsed
                    //for GetObject to find the running Office application. Wait
                    //1/2 seconds and retry the GetObject. If we try 20 times
                    //and GetObject still fails, we assume some other reason
                    //for GetObject failing and exit the procedure.
                    iTries++;
                    if (iTries < 20)
                    {
                        System.Threading.Thread.Sleep(500); // Wait 1/2 seconds.
                        goto tryAgain; //resume code at the GetObject line
                    }
                    else
                    {
                        MessageBox.Show("GetObject still failing.  Process ended.");
                    }

                }
                else
                {
                    //iSection == 0 so normal error handling
                    MessageBox.Show(err.Message);
                }
            }
        }


    }

The output is:

Excel application object not registered. Trying plan B..
GetObject still failing.  Process ended.

In some rare cases “plan B” does work; I don’t see the second message box.
CurrentSpreadSheet is a singleton and I intend to update it during startup from the provided class ThisAddIn.

In ThisAddIn I have something like:

private CurrentSpreadSheet css = CurrentSpreadSheet.Instance;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        ///...Some code
        css.updateCurrentSpreadSheet();
}

Is there a better way of getting the Application object? If this is not possible right during the startup, is there a better way by which I can keep track of currently active worksheet/workbook right from the startup of excel/my add-in? Currently I am depending on the Application object (e.g. (Excel.Workbook)this.CurrentApplication.ActiveWorkbook;) and some event handlers to keep track of the current workbook and worksheet.

I tried using ExcelDNA:

this.CurrentApplication = (Excel.Application)ExcelDna.Integration.ExcelDnaUtil.Application;

This works some of the times but mostly gives this error:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> ExcelDna.Integration.XlCallException: Exception of type 'ExcelDna.Integration.XlCallException' was thrown.
How to&Answers:

Keep in mind that an Office add-in runs inside the Office process. So you never want to find an external process. The boilerplate ThisAddIn class that you get when you use a Office project template hands you the Application object you are looking for on a silver platter, use its Application property. The first time you can get to it is in the Startup event, make sure you don’t try it earlier. So don’t do anything drastic in your constructor and don’t initialize class members with initialization expressions, wait until Startup fires.

The relevant MSDN page is here, “Accessing the Object Model of the Host Application” section.

Answer:

You might take a closer look at http://netoffice.codeplex.com/ There you can find more stuff about Add-In’s for Word/Excel/Powerpoint.
Also keep in mind the GuidAttribute when you load your Add-In, because depending on your Office version it won’t work anymore and also, check to kept your project whether 32/64-bit, best is Any CPU. Also, keep in mind to register your Add-In into the registry for further usage. If you want further information, don’t hesitate to write me a mail.

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.guidattribute.aspx