testingExcel是否完成启动/closures序列

我正在使用PowerShell来通过COM脚本通过PowerShell脚本自动完成一些excel任务:

 $xl = new-object -ComObject Excel.Application sleep 5 DO THINGS... $xl.quit() sleep 5 $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl) [GC]::collect() 

我的问题是,如果我省略了第一次sleep呼叫,Excel将不会准备好执行需要加载项的任务,并且对$xl.quit()的调用不起作用,并且该过程无法退出,如下所示:

 PS > Get-Process EXCEL Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 784 104 104008 109380 944 3.21 5996 EXCEL 

同样,如果我省略了第二次sleep ,excel没有时间完成closures,并最终导致出现一个对话框,指出“Microsoft Excel已停止工作…”,并在下一次Excel启动时,另一个对话框状态“Microsoft Excel未能正常closures,在安全模式下启动?

 function XLtest { $xl = new-object -ComObject Excel.Application $xl.quit() $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl) [GC]::collect() } for($i=0;$i -lt 10; $i++){ XLtest } # generates multiple errors 

很明显,这些是我想避免的问题,但调用sleep 5的启发式解决scheme仍然可能失败。 有没有什么办法可以检测到什么时候excel已经完成启动序列,并准备好发出命令(特别是xl.quit() ),当closures序列完成时(也就是说可以调用[System....Marshal]::ReleaseComObject($xl)

虽然你的确切的环境和情况是不可能的,没有一个插件就像DO THINGS …一个提到的, Excel应用程序对象的成员应该能够被利用来获得应用程序状态的一些意识。

似乎可能的候选者是_Application.CalculationState属性 。 如果强制Do While...: DoEvents: Loop完整的重新计算,则处理Do While...: DoEvents: Loop时,伪定时器可能会暂停powershell脚本,而Application.CalculationState不是xlDone ,与Internet.Explorer对象相同直到它完成接收它的网页。

 $xl = new-object -ComObject Excel.Application $xl.Calculate do while $xl.CalculationState <> xlDone: $xl.DoEvents: Loop $xl.quit() ... (do more things?) 

如果在closures(和随后退出)之前保存,则也可以使用_Application.CalculateBeforeSave属性强制重新进行重新计算 。

另一个好的select是简单的_Application.Ready属性 。

 $xl = new-object -ComObject Excel.Application do while not $xl.ready: $xl.DoEvents: Loop $xl.quit() 

请参阅应用程序成员(Excel)以获取可以确定“状态”的潜在属性的完整列表。 有关Excel 2010应用程序对象开发人员指南的更多信息。