PowerShell的:如果Excel已经运行,获取实例,否则启动它 – exception处理

使用Powershell,我想导入一些制表符分隔的Ascii文件到MS Excel中。 我使用一个循环来完成,现在我有一个简单的解决scheme:

for each file: start Excel , import tsv file, close Excel. 

假设Excel是在path中,这是Excel,Excel 2010的正确版本

现在我想切换到更高效的版本:保持excel打开。

对于每个文件:抓取excel的运行实例,如果没有,则尝试启动excel。 处理文件。 保持开放。 最后,保持打开状态(我想在脚本运行的时候查看excel文件,这可能需要一段时间。烦恼的是,在当前版本的脚本中,excel正在closures,而我正在查看输出)。

我还没有find一个全面的解决scheme,无论是在这里或互联网上的其他地方。 “全面”是指“exception处理”。 在Powershell中,这有点令人困惑。 有两种处理exception的方法:使用陷阱和try-catch块。

这里是我的代码,从几个互联网来源一起扔,我怎么能改善它?

我想包装它在一个函数,但COM对象作为返回值是有问题的。 (我想要的是“简单工厂”和“单身人士”的组合)。

 [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Excel") try { $excelApp = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application") } catch [System.Runtime.InteropServices.COMException], [System.Management.Automation.RuntimeException]{ write-host write-host $("TRAPPED: " + $_.Exception.GetType().FullName); write-host $("TRAPPED: " + $_.Exception.Message); write-host "Excel is not running, trying to start it"; $excelApp = New-Object -ComObject "Excel.Application" if (-not $excelApp){ # excel not installed, not in path Write-Error "Excel not running, and cannot be started, exiting." # Todo: test if excel version is correct, eg english Excel 2007 or 2010., if not set outfile extension xls. exit; } } catch [System.Exception]{ write-host $("EXCEPTION: " + $_.Exception.GetType().FullName); write-host $("EXCEPTION: " + $_.Exception.Message);c Write-Error 'Something went wrong during creation of "Excel.Application" object, => Exit.' exit; } 

自从你问这个问题已经有一段时间了,但是我遇到了同样的问题。 您的代码似乎只是一个合理解决scheme的好例子。 但是,我确实质疑你的担忧。 具体来说,一旦Excel运行,是否需要再次调用这个例程在一个函数? 也就是说,一旦Excel打开,那么你可以把它作为一个服务来打开/closures工作簿,访问它们中的工作表,最后是$ excelApp.Quit()应用程序(尽pipe在Powershell v1.0中.Quit()不会退出应用程序…但是,因为我正在抓取正在运行的实例,所以没关系)。

下面的链接讨论了启动和抓取Excel实例的PID的方法,以便在需要时明确地杀死它。

从Powershell中退出/closuresExcel的讨论

所有variables必须为空。 Excel.Workbooks – 所有打开的书。 检查工作簿的数量。 如果count = 0,退出。 Powershell Excelclosures后也将closures。

$Workbook.Close() $WorkSheet = $null; $Workbook = $null; If($excelApp.Workbooks.Count -eq 0) {$excelApp.Quit()} $excelApp = $null;