powershell: if excel already running, get instance, otherwise start it - with exception handling
Using Powershell, I want to import some tab-separated Ascii files into MS Excel. I use a loop for doing so, and right now I have a simple solution that works:
for each file: start Excel , import tsv file, close Excel.
..assuming Excel is in the Path, it's the right version of Excel, Excel 2010
Now I want to switch to a more efficient version: keep excel open.
for each file: grab running instance of excel if there is one, if not, try to start excel. Process file. Keep excel open. At the end, keep it open ( I want to look at the excel files while the script is running, which could take a while. Annoyingly, in the current version of the script excel is being closed while I am looking at the output).
I haven't found a comprehensive solution for this, neither here nor elsewhere on the internet. With "comprehensive" I mean "Exception Handling". In Powershell, it's a bit confusing. There are two ways of dealing with exceptions: using trap and a try-catch block.
Here is my code, thrown together from several internet sources , how can I improve it?
I want to wrap it in a function, but COM objects as return values are problematic. ( What I want is a combination of "simple factory" and "singleton".)
[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开发者_如何学C "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, e.g. 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;
}
It's been a while since you asked this, but I have run into the same problem. Your code appears to be only good example of a reasonable solution. I do question your concern, however. Specifically, once Excel is running is there a need to call this routine again in a function? That is, once Excel is open, then you can treat it as a service to open/close workbooks, access worksheets within them, and eventually $excelApp.Quit() the application (although in Powershell v1.0 the .Quit() won't exit the app... but that is OK since I am grabbing a running instance anyways).
The link below discusses a way of starting up and grabbing the PID of Excel instance in order to explicitly kill it if needed.
Discussion on Quiting/Killing Excel from within Powershell
All variables must be null. Excel.Workbooks - all open book. Check count of Workbooks. If count = 0, quit. After close of Powershell Excel will be close too.
$Workbook.Close()
$WorkSheet = $null;
$Workbook = $null;
If($excelApp.Workbooks.Count -eq 0)
{$excelApp.Quit()}
$excelApp = $null;
精彩评论