2016-07-06 4 views
3

Я использую следующие методы. После выполнения этого блока кода я обнаружил, что Microsoft Excel все еще работает в фоновом режиме, проверяя диспетчер задач.Excel Interop Объекты не выпускаются

Редактировать: Точно Процесс Microsoft Excel остается в режиме реального времени. Я просто добавляю это, потому что, когда я впервые начал работать с объектами Excel и Interop COM, иногда многие процессы оставались бегущими после завершения функций.

Как я могу гарантировать, что Excel не будет работать в фоновом режиме после выполнения текущей функции?


я объявить эти переменный с глобальной областью, поскольку несколько функций в конечный итоге нуждающихся в них:

private Excel.Application xls = null; 
private Excel.Workbooks workBooks = null; 
private Excel.Workbook workBook = null; 
private Excel.Sheets sheets = null; 
private Excel.Worksheet workSheet = null; 

Этот метод предназначен для проверки, если лист существует в данной книге:

private bool sheetExists(string searchString) 
{ 
    xls = new Excel.Application(); 
    workBooks = xls.Workbooks; 
    workBook = workBooks.Open(workbookPath); // <- Where the workbook is saved 
    sheets = workBook.Sheets; 

    bool isFound = false; 

    foreach (Excel.Worksheet sheet in sheets) 
    { 
     // Check the name of the current sheet 
     if (sheet.Name == searchString) 
     { 
      Marshal.ReleaseComObject(sheet); 
      isFound = true; 
      break; 
     } 

     Marshal.ReleaseComObject(sheet); 
    } 

    cleanUp(true, xls, workBooks, workBook, sheets); 

    return isFound; 
} 

Эта функция предназначена для освобождения COM-объектов:

private void cleanUp(bool saveTrueFalse, params object[] comObjects) 
{ 
    workBook.Close(saveTrueFalse); 

    xls.Application.Quit(); 
    xls.Quit(); 

    foreach (object o in comObjects) 
    { 
     Marshal.ReleaseComObject(o); 
    } 

    workSheet = null; 
    sheets = null; 
    workBook = null; 
    workBooks = null; 
    xls = null; 

    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
} 
+0

Еще один случай, когда вы не понимаете, как работает сборщик мусора. Здесь уже много раз, [как здесь] (http://stackoverflow.com/questions/25134024/clean-up-excel-interop-objects-with-idisposable/25135685#25135685). –

ответ

-1

Я бы хотел найти правильное решение, но этот хак был единственным способом заставить его работать. Кажется, что библиотека interop не очень хороша при закрытии процесса, когда сказано. Если вы работаете в потоках, вы будете запускать процессы для каждого потока. Я бы отслеживал идентификатор процесса после запуска процессов сканирования по имени и отслеживания новых процессов. Я делал это на сервере, поэтому я знал, что все процессы были начаты в режиме interop и не запущены фактическим пользователем. После того, как я закончил с логикой, я бы начал таймер, который будет пытаться убить процесс каждую минуту или около того. В конце концов, это остановило бы его. У меня также был код, который бы убил любые процессы Excel при запуске, если они не были убиты должным образом в последний раз, когда приложение запускалось.

Сообщите мне, если вы хотите использовать образец кода для уничтожения процессов по имени или идентификатору. У меня нет его легкодоступного, или быстрый поиск SO должен приносить хорошие образцы.

+0

Вниз избиратели объясните пожалуйста. Это может быть не идеальное решение, но оно действительно работает. Я даже упомянул, что мне также хотелось бы найти идеальное решение. – ManOVision