附加到现有的Excel实例

Sea*_*ean 4 c# excel interop marshalling excel-interop

我正在尝试确定是否打开了运行特定文件的Excel实例,如果是这样,请附加到它以便我可以控制该实例.

我四处搜寻,我得到的大部分内容来自这个问题.它提到了另一个网站,但遗憾的是它已经死了,所以我无法阅读它.

到目前为止我的代码是;

//Is Excel open?
if (Process.GetProcessesByName("EXCEL").Length != 0)
{
    Process[] processes = Process.GetProcesses();
    foreach (Process process in processes)
    {
        //Find the exact Excel instance
        if (process.ProcessName.ToString() == "EXCEL" && process.MainWindowTitle == ("Microsoft Excel - " + fileName))
        {
             //Get the process ID of that instance
             int processID = (int)Process.GetProcessById(process.Id).MainWindowHandle;

             //Attach to the instance...
             Excel.Application existingExcel = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject(process.Id);                 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经设法获取了我想要附加的实例的进程ID,但是在使用该ID时我已经迷失了.

关于如何进行的任何想法?

Ben*_*son 5

Marshal.GetActiveObject()不将进程ID作为参数.你想要的是:

Marshal.GetActiveObject("Excel.Application");
Run Code Online (Sandbox Code Playgroud)

请注意,这根本不需要跟踪过程,只需要一个.

如果您可以拥有多个进程并希望附加到特定进程,则会变得更加复杂.这就是另一个问题的答案.

http://blogs.msdn.com/b/andreww/archive/2008/11/30/starting-or-connecting-to-office-apps.aspx上还有一篇很好的文章,更全面地描述了不同的方式启动excel.请注意,并非所有这些都必须与Excel 2013保持同步,因为对于所有Excel窗口而言,只有一个进程会使事情变得复杂.尽管如此,GetActiveObject解决方案应该没问题.

  • 你没有回答这个问题.启动Excel两次.转到任务管理器,您将发现两个Excel正在运行.在这种情况下,`GetActiveObject`只返回正在运行的实例中的一个(最旧的).返回的实例可能不是OP想要的实例. (2认同)