Home » Visual StudioRSS

Open Excel with VSTO from C#

Hello. I have pasted all of my code for this below. I have an excel addin built with VSTO. I am trying to start excel with a file from C# and then access the addin that is started in excel from C#. Basically, I couldn't find a way to put excel in my C# application so I built an addin. Then I added a layer which allows me to communicate with excel. The only way I have figured out how to do this is with the BindToMonkier to get the object from the Running Object Table (ROT).

The problem is that the only way I can do this is to throw a MessageBox up to force excel into the ROT. This is described here (http://support.microsoft.com/kb/316126)

This method of opening excel doesn't work to well. I have to throw a message box to get excel to go into the RTO. Also, sometimes the addin object is null which causes problems.

myAddin = (

IMyAddIn)addin.Object;

 

Basically, sometimes it works and sometimes it doesn't. I can't send this code to anyone unless it works 100% of the time. I don't know what to do. Can anyone provide any insight?

 

[ComVisible(true)]
[Guid("11111111-1111-1111-1111-111111111111")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IMyAddIn
{
    void Initialize();
}

[ComVisible(true)]

[ClassInterface(ClassInterfaceType.None)]

[Guid("11111111-1111-1111-1111-111111111112")]

public sealed class AddInUtilities : StandardOleMarshalObject, IMyAddIn {

public void Initialize()

{


}

}

 protected override object RequestComAddInAutomationService()
    {

      if (this.utilities == null)
      {
        this.utilities = new AddInUtilities();
      }            

      IMyAddIn ret = this.utilities;

      return ret;


    }

 

 

publicstaticvoid OpenWorkbook(MyWorkbook workbook)

  {

   

   Process excelProcess = new Process();

   excelProcess.StartInfo.FileName = "Excel.exe";

   excelProcess.StartInfo.Arguments = "\"" + workbook.File + "\"";

   excelProcess.Start();



   Excel.Workbook excelWorkbook = null;

   Microsoft.Office.Interop.Excel.Application app = null;

   try

   {

    excelProcess.WaitForInputIdle();

    MessageBox.Show(""); //only thing that works 

    excelWorkbook = (Excel.Workbook)Marshal.BindToMoniker(workbook.File);

    app = excelWorkbook.Application;    

    app.IgnoreRemoteRequests = true;

   }

   catch

   {

    excelProcess.Kill();

    throw;

   }



   IMyAddIn myAddin = null;



   try

   {



    object addinName = "MY.AddIn.Excel";

    Microsoft.Office.Core.COMAddIn addin = (Microsoft.Office.Core.COMAddIn)app.COMAddIns.Item(ref addinName);

    myAddin = (IMyAddIn)addin.Object;

    myAddin.Initialize();



   }

   catch (Exception e)

   {

    excelProcess.Kill();    

    return;

   }

  } 

 

 

 

5 Answers Found

 

Answer 1

As far as I can tell from this KB article, the behavior you're seeing is unfortunately expected if you're trying to access  the running  instance of Excel with GetActiveObject or BindToMoniker before it loses focus for the first time. I'm not aware of any way to avoid this when attaching to a running instance of Excel; perhaps someone else can chime in with better workarounds than displaying a message  box.

A couple of follow-up questions:

Do you absolutely need to attach to a running instance of Excel? In other words, what is the workflow that users follow in your scenario: do they first run Excel, then they run your application, then they do something in your application  that requires you to access the running instance of Excel to call into the add-in? The application code  you provided actually appears to programmatically start  Excel (Process.Start), which makes me wonder why you aren't just instantiating a Microsoft.Office.Interop.Excel.Application  object  directly to start Excel, which is the simplest way to automate Excel in an early-bound fashion. For more details, see http://blogs.msdn.com/b/andreww/archive/2008/11/30/starting-or-connecting-to-office-apps.aspx. It isn't clear from your code why you have created an add-in at all. Does the AddInUtilities class  in your add-in implement some particular feature that you need to use from your application? If you just need to "communicate with Excel" from your application, which I understand to mean that you need to call into the object model of Excel to perform some automation tasks, your simplest bet would be to stick to automating Excel from the PIAs. In other words, instantiate a Microsoft.Office.Interop.Excel.Application object, use the Workbooks.Open method  to open  the workbook  you want to operate on or use Workbooks.Add to create a new workbook, etc.

Regarding your add-in object being null, depending on what version of the VSTO runtime your add-in targets, this might happen in some cases if you try to get the add-in object too soon after Excel starts. To work  around this, you can try putting some sleeps into your code until a valid add-in object is retrieved. For more information, see http://blogs.msdn.com/b/andreww/archive/2008/08/13/comaddins-race-condition.aspx.


This posting is provided "AS IS" with no warranties, and confers no rights.
 

Answer 2

Hi Stumple,

Instead of launching Excel using Process class  and using BindToMoniker API, I think you should use Microsoft.Office.Interop.Excel.Application class direcly.

Creating an object  of Microsoft.Office.Interop.Excel.Application class will launch the required Excel process, and you can then open  the any file  by using Application.Workbooks.Open API by passing the path to the workbook.

Rest of the logic (accessing the COMAddins collection, and the related Object) can then be performed after handling the Workbook.Open event, that indicates that things are up and running  and it should return  you the required COMAddin.Object without the failure.

HTH,

Manvir Singh
http://www.manvirsingh.net/

 

 

Answer 3

Hi Stumple,

How is this issue going on in your side? Have you solved the problem?

Best Regards,
Amy Li
 

Answer 4

Hi Stumple,

I will mark the answer for the thread. Any further questions, please feel free to follow up. Thank you!

Best Regards,
Amy Li
 

Answer 5

For some reason I wasn't getting alerts until today.

 

I re-wrote everything. I now use three methods to get to excel. I post my own COM object  to the ROT. I look for the excel  addin which excel posts. I also try to get the addin  from the monkier.  All is well now. I just having some COM issues with unwrapping.

 

Thanks.

 
 
 

<< Previous      Next >>


Microsoft   |   Windows   |   Visual Studio   |   Tech Videos   |   Follow us on Twitter