为了扩展@DylanCorriveau 所说的内容,我发现您需要采用以下方法之一来避免此问题。
方法一
我发现在某些情况下(Excel 2010)首先启动 excel 可以解决这个问题。您需要调整路径并等待适合您的需求和版本。
string pathToTheVersionOfExcel = @"C:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE";
System.Diagnostics.Process.Start(pathToTheVersionOfExcel);
Thread.Sleep(5000); //"WaitForInputIdle" waits for way too long, generally it takes 5 seconds to start for me
方法二
我过去采用的另一种方法是以不同的方式调用 Excel:
var oExcelApp = new Microsoft.Office.Interop.Excel.Application();
方法三
最后在我的应用程序中(对于 excel 2010 和 2016),我使用了一些解决方法:
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
//In your method...
string pathToTheVersionOfExcel = @"C:\Program Files (x86)\Microsoft Office\root\Office16\EXCEL.EXE";
Application oExcelApp = null;
Process process = new Process();
process.StartInfo.FileName = pathToTheVersionOfExcel;
process.Start();
Thread.Sleep(5000);
//Opening a closing notepad seems to "register" excel 2016, not needed for excel 2010 though...
Process processNotepad = new Process();
processNotepad.StartInfo.FileName = @"C:\Windows\system32\notepad.exe";
processNotepad.Start();
ShowWindow(process.MainWindowHandle, 2); //Minimize
ShowWindow(process.MainWindowHandle, 3); //Maximize
Thread.Sleep(5000);
processNotepad.CloseMainWindow();
oExcelApp = (_Application)Marshal.GetActiveObject("Excel.Application");
如果您在 RDP 会话中在 Excel 2016 中运行此代码,它可能非常挑剔,我发现您需要自定义 RDP 以忽略它的最小化状态。我发现这篇文章很有帮助。
如果您尝试通过远程服务器上的某种自动构建/发布平台(例如 TFS/Azure DevOps)调用 excel,则需要使用autologin。我自己还没有那个工作。