开发者

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;

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜