Excel все еще работает после закрытия приложения vb.net - PullRequest
0 голосов
/ 17 мая 2018

У меня проблемы с закрытием файлов Excel. Я делаю программу, которая открывает некоторые файлы Excel, использует информацию, а затем закрывает их.
Я пробовал несколько разных кодов, но они не работали, потому что процесс EXCEL все еще выполняется.

Мой первый код:

Dim aplicacaoexcel As New Excel.Application
Dim livroexcel As Object
Dim folhaexcel As Excel.Worksheet

livroexcel = aplicacaoexcel.Workbooks.Open("C:\Users\LPO1BRG\Desktop\Software Fiabilidade\Tecnicos.xlsx", UpdateLinks:=False, ReadOnly:=False, Password:="qmm7", WriteResPassword:="qmm7")
folhaexcel = livroexcel.sheets("Folha1")

aplicacaoexcel.DisplayAlerts = False
aplicacaoexcel.Visible = False
folhaexcel = Nothing
livroexcel.Close()
livroexcel = Nothing
aplicacaoexcel.Quit()
aplicacaoexcel = Nothing

Затем я добавил это: System.GC.Collect(), но он все еще не закрывает процесс Excel.

Сейчас я пытаюсь это:

Dim process() As Process = system.Diagnostics.Process.GetProcessesByName("EXCEL")

For Each p As Process In process
   p.Kill()
Next

На самом деле, этот работает, но он закрывает все файлы Excel (даже те, которые не открыты моей программой).

Что я могу сделать, чтобы закрыть только файлы Excel, открытые моей программой? :)

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

Я немного заржавел на своем VB и сейчас у меня нет доступа к Visual Studio, чтобы проверить это, но я попытаюсь написать код из памяти.

Проблема, с которой вы сталкиваетесь, состоит в том, что установка объекта равным Nothing по-прежнему оставляет объект, выделенный в памяти, и не удаляет объект полностью. Даже методы Close () и Quit () объекта по-прежнему оставляют его выделенным в памяти на случай, если программе понадобится доступ к ним позже. Метод Kill () работает, потому что он просто убивает приложение Excel, работающее в памяти, которое закрывает все открытые документы Excel, а также документы, используемые объектами COM. Что вы хотите сделать, так это избавиться от определенных COM-объектов, которые использует ваше приложение.

Попробуйте это изменение в своем коде.

Dim aplicacaoexcel As New Excel.Application
Dim livroexcel As Object
Dim folhaexcel As Excel.Worksheet

livroexcel = aplicacaoexcel.Workbooks.Open("C:\Users\LPO1BRG\Desktop\Software Fiabilidade\Tecnicos.xlsx", UpdateLinks:=False, ReadOnly:=False, Password:="qmm7", WriteResPassword:="qmm7")
folhaexcel = livroexcel.sheets("Folha1")

aplicacaoexcel.DisplayAlerts = False
aplicacaoexcel.Visible = False

DisposeComObj(folhaexcel)
DisposeComObj(livroexcel)
DisposeComObj(aplicacaoexcel)

Затем добавьте следующее в ваше приложение.

Private Sub DisposeComObj(ByRef Reference As Object)
    Try        
        Do Until _
        System.Runtime.InteropServices.Marshal.ReleaseComObject(Reference)<=0
        Loop
    Catch
    Finally
        Reference = Nothing
    End Try
End Sub

Надеюсь, моя память хорошо мне служит. Я не писал никакого кода на VB или C # более года и чувствую себя очень не на практике. Я видел твой вопрос только потому, что нажал не на ту ссылку и вспомнил, как я боролся со сборкой мусора, когда начинал программировать.

0 голосов
/ 17 мая 2018

Освобождение COM-объекта Excel.Application Interop несколько сложнее, чем другие объекты Office Interop, поскольку некоторые объекты создаются без вашего ведома, и все они должны быть освобождены, прежде чем основное приложение может быть фактически закрыто.

Эти объекты включают в себя:

  • Приложение Excel.
  • Коллекция Excel.Application.WorkBooks
  • Открыта коллекция WorkBooks WorkBook
  • Коллекция WorkBook Sheets
  • Рабочий лист, на который ссылается коллекция Sheets

Все эти объекты должны быть освобождены, чтобы завершить процесс EXCEL.

Простым решением является использование явных объявлений / назначений для всех объектов COM:

Dim ExcelApplication As New Microsoft.Office.Interop.Excel.Application()
Dim ExcelWorkbooks As Workbooks = ExcelApplication.Workbooks
Dim MyWorkbook As Workbook = ExcelWorkbooks.Open("[WorkBookPath]", False)
Dim worksheets As Sheets = MyWorkbook.Worksheets
Dim MyWorksheet As Worksheet = CType(worksheets("Sheet1"), Worksheet)

Когда вы закончите, отпустите их все:

Imports System.Runtime.InteropServices

Marshal.ReleaseComObject(MyWorksheet)
Marshal.ReleaseComObject(worksheets)

MyWorkbook.Close(False)   '<= False if you don't want to save it!
Marshal.ReleaseComObject(MyWorkbook)

ExcelWorkbooks.Close()
Marshal.ReleaseComObject(ExcelWorkbooks)

ExcelApplication.Quit()
Marshal.FinalReleaseComObject(ExcelApplication)

Marshal.CleanupUnusedObjectsInCurrentContext()
0 голосов
/ 17 мая 2018

Попробуйте что-то вроде workbook.Save, workbook.close

...