C#.NET错误附加到运行Office应用程序的实例

我正在使用C#,Visual Studio 2012的Excel插件工作。我试图获取Excel的应用程序对象的实例,以跟踪当前活动的工作簿和工作表(ActiveWorkbook,ActiveWorksheet)。

我看到大多数其他相关的问题都有回复,build议使用以下内容:

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

我也尝试过使用这个:

 (Excel.Application)Globals.ThisAddIn.Application; 

在这两种情况下,我得到NullReferenceException。 看看这里build议的解决方法后: http : //support.microsoft.com/kb/316125/en-us ,我试着以下testing两种方法。

 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); } } } } 

输出是:

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

在一些罕见的情况下,“B计划”确实有效; 我没有看到第二个消息框。 CurrentSpreadSheet是一个单例,我打算在启动时从提供的类ThisAddIn中更新它。

在ThisAddIn我有这样的东西:

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

有没有更好的方法来获取应用程序对象? 如果在启动过程中这是不可能的,是否还有更好的方式让我可以从excel / my插件的启动中直接跟踪当前活动的工作表/工作簿? 目前,我依赖于Application对象(例如(Excel.Workbook)this.CurrentApplication.ActiveWorkbook; )和一些事件处理程序来跟踪当前工作簿和工作表。

我尝试使用ExcelDNA:

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

这在某些时候是有效的,但主要是出现这个错误:

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

请记住,Office加载项在Office进程运行。 所以你永远不想find一个外部的过程。 您在使用Office项目模板时获得的样板ThisAddIn类可将您正在寻找的应用程序对象放在银盘上,并使用其Application属性。 第一次你可以到达它是在启动事件,请确保你不要尝试它。 因此,不要在构造函数中做任何激烈的操作,也不要用初始化expression式初始化类成员,等到启动时触发。

相关的MSDN页面在这里 ,“访问主机应用程序的对象模型”部分。

你可以仔细看看http://netoffice.codeplex.com/在这里你可以find更多关于Word / Excel / Powerpoint插件的东西。 还要记住GuidAttribute当您加载您的加载项,因为取决于您的Office版本,它不会工作了,而且,检查保持您的项目是否32/64位,最好是任何CPU。 另外,请记住将您的加载项注册到registry以供进一步使用。 如果你想了解更多信息,请不要犹豫,给我写邮件。

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