powershell: если excel уже запущен, получите экземпляр, иначе запустите его - с обработкой исключений - PullRequest
1 голос
/ 19 июля 2011

Используя Powershell, я хочу импортировать некоторые файлы Ascii, разделенные табуляцией, в MS Excel. Для этого я использую цикл, и сейчас у меня есть простое решение, которое работает:

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

.. при условии, что Excel находится на пути, это правильная версия Excel, Excel 2010

Теперь я хочу перейти на более эффективную версию: держать Excel открытым.

для каждого файла: захватить запущенный экземпляр Excel, если он есть, если нет, попробуйте запустить Excel. Файл процесса. Держите Excel открытым. В конце держите его открытым (я хочу посмотреть на файлы Excel во время работы скрипта, что может занять некоторое время. Досадно, что в текущей версии скрипта Excel закрывается, пока я смотрю на вывод).

Я не нашел всеобъемлющего решения для этого ни здесь, ни где-либо еще в Интернете. Под «всеобъемлющим» я подразумеваю «Обработка исключений». В Powershell это немного сбивает с толку. Есть два способа работы с исключениями: использование trap и блок try-catch. * * 1010

Вот мой код, собранный из нескольких интернет-источников, как я могу его улучшить?

Я хочу обернуть его в функцию, но 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, 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;
    }

Ответы [ 2 ]

0 голосов
/ 07 сентября 2015

Все переменные должны быть нулевыми.Excel.Workbooks - все открытая книга.Проверьте количество рабочих книг.Если count = 0, выход.После закрытия Powershell Excel тоже будет закрыт.

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

0 голосов
/ 16 февраля 2013

Прошло много времени с тех пор, как вы спросили об этом, но я столкнулся с той же проблемой. Ваш код, кажется, только хороший пример разумного решения. Однако я сомневаюсь в вашей озабоченности. В частности, после запуска Excel нужно ли снова вызывать эту процедуру в функции? То есть после открытия Excel вы можете рассматривать его как службу для открытия / закрытия рабочих книг, доступа к рабочим листам внутри них и, в конечном итоге, к приложению $ excelApp.Quit () (хотя в Powershell v1.0 победил .Quit () не выходить из приложения ... но это нормально, так как я все равно получаю запущенный экземпляр).

Ссылка ниже обсуждает способ запуска и захвата PID экземпляра Excel для явного уничтожения его при необходимости.

Обсуждение выхода / убийства Excel изнутри Powershell

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...