Как правильно закрыть Excel.Application? - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть небольшой скрипт, который позволяет мне объединить несколько .csv в .xlsx:

$path = "C:\Users\FrancescoM\Desktop\CSV\Results\*"
$csvs = Get-ChildItem $path -Include *.csv
$y = $csvs.Count
Write-Host "Detected the following CSV files: ($y)"
Write-Host " "$csvs.Name"`n"
$outputfilename = "Final Registry Results"
Write-Host Creating: $outputfilename
$excelapp = New-Object -ComObject Excel.Application
$excelapp.SheetsInNewWorkbook = $csvs.Count
$xlsx = $excelapp.Workbooks.Add()
for ($i=1; $i -le $y; $i++) {
    $worksheet = $xlsx.Worksheets.Item($i)
    $worksheet.Name = $csvs[$i-1].Name
    $file = (Import-Csv $csvs[$i-1].FullName)
    $file | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation | Clip
    $worksheet.Cells.Item(1).PasteSpecial() | Out-Null
}

$output = "Results.xlsx"
$xlsx.SaveAs($output)
$excelapp.Quit()

Если я запускаю его один раз, он отлично работает и создает мой файл «Results.xlsx».

Но если я тогда удаляю файл "Results.xlsx" и снова запускаю код, я получаю эту ошибку:

Файл с именем «Results.xlsx» уже существует в этом месте. Вы хотите заменить его?

enter image description here

Но очевидно, что файла там больше нет. Я считаю, что я закрываю Excel.Application в неправильном направлении. Как правильно закрыть?

1 Ответ

0 голосов
/ 11 ноября 2018

Как прокомментировал Ансгар Вичерс, для этого фрагмента кода лучше использовать полный путь и имя файла $output = "Results.xlsx" В противном случае выходные данные будут записаны в текущий каталог Excel, и это может быть не там, где вы ожидаете.

Чтобы ответить на вопрос Как правильно закрыть Excel.Application? , вам нужно не только завершить работу Excel, но и освободить объекты Com, использованные в коде. Вы делаете это так:

$excelapp.Quit()

# release the WorkSheet Com object
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsx) | Out-Null
# release the Excel.Application Com object
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excelapp) | Out-Null 
# Force garbage collection
[System.GC]::Collect()
# Suspend the current thread until the thread that is processing the queue of finalizers has emptied that queue.
[System.GC]::WaitForPendingFinalizers()
...