PowerPoint, запущенный через C #, не завершается - PullRequest
9 голосов
/ 11 июня 2009

Эй, я автоматизирую PowerPoint и Excel из приложения C # WinForms; я читаю слайды из PowerPoint и сохраняю их в Excel, а затем закрываю оба приложения. Excel успешно завершает работу, но PowerPoints не завершается. Проблема в том, что когда я конвертирую в первый раз, он не завершается, но когда я снова конвертирую, он делает.

Вот мой код

try
{
    PowerPoint.Application ppApp;
    PowerPoint.Presentation ppPres;
    List<Company> companies = new List<Company>();

    ppApp = new PowerPoint.Application();
    ppApp.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
    ppApp.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowMinimized;

    ppPres = ppApp.Presentations.Open(fileTxtBox.Text,
                                      Microsoft.Office.Core.MsoTriState.msoFalse,
                                      Microsoft.Office.Core.MsoTriState.msoFalse,
                                      Microsoft.Office.Core.MsoTriState.msoTrue);

    int slides = ppPres.Slides.Count;

    for (int slide = 1; slide <= slides; slide++)
    {
        int rows = 1;
        PowerPoint.Cell cell;
        int shape = 1;

        for (; shape < ppPres.Slides[slide].Shapes.Count; shape++)
        {
            if (ppPres.Slides[slide].Shapes[shape].HasTable == Microsoft.Office.Core.MsoTriState.msoTrue)
            {
                cell = ppPres.Slides[slide].Shapes[shape].Table.Cell(1, 1);

                if (cell.Shape.TextFrame.TextRange.Text.Trim().ToLower().Contains("realized"))
                {
                    rows = ppPres.Slides[slide].Shapes[shape].Table.Rows.Count;
                    break;
                }
            }
        }

        Company comp = new Company(rows);
        InitializeCompany(ref comp, ppPres.Slides[slide]);
        companies.Add(comp);
    }

    SaveInExcel(companies);

    ppPres.Close();
    ppPres = null;
    ppApp.Quit();
    ppApp = null;

    return;
}

catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

finally
{
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

Ответы [ 6 ]

12 голосов
/ 11 июня 2009

Сначала может показаться сложным завершить работу приложения Microsoft Office, но как только вы установите правильный порядок операций, на самом деле это совсем не сложно.

Выпуск приложения MS Office можно выполнить безопасно и эффективно в два этапа:

(1) Сначала освободите все второстепенные объекты, на которые у вас нет ссылки в именованной переменной. Это делается с помощью вызова GC.Collect () , а затем GC.WaitForPendingFinalizers () . Обратите внимание, что если вы используете Visual Studio Tools for Office (VSTO), вам необходимо вызвать эту пару команд дважды , чтобы получить возможность успешного освобождения объектов COM. Однако вы не используете VSTO, поэтому достаточно вызвать их один раз.

(2) Затем явно освободите объекты, которые вы держите, через именованную переменную, используя вызов Marshall.FinalReleaseComObject () для каждой вашей переменной.

Не забудьте явно освободить все переменные, которые вам нужны для COM-компонентов. Если вы пропустите хотя бы один из них, ваше приложение MS Office будет зависать. В вашем коде, кажется, есть три именованные переменные, которые содержат ссылку на приложение PowerPoint: ppApp, ppPres и cell.

Принимая все это во внимание, я думаю, что ваша очистка должна выглядеть примерно следующим образом, в которой используется using System.Runtime.InteropServices либо в пространстве имен, либо в верхней части документа кода:

// using System.Runtime.InteropServices

// Cleanup:
GC.Collect();
GC.WaitForPendingFinalizers();

Marshal.ReleaseComObject(cell);

ppPres.Close();
Marshal.ReleaseComObject(ppPres);

ppApp.Quit();
Marshal.ReleaseComObject(ppApp);

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

Как правильно очистить объекты взаимодействия Excel в C # .

Надеюсь, это поможет, дайте нам знать, как это происходит ...

- Майк

2 голосов
/ 11 июня 2013

Привет, ребята. В последнее время я заметил, что у меня ничего не получалось, от сбора мусора до выхода и закрытия объектов. поэтому я придумал альтернативу. я узнал о запущенном процессе, как только моя работа была выполнена, и затем убил его с помощью кода.

Код:

 Process[] pros = Process.GetProcesses();
  for (int i = 0; i < pros.Count(); i++)
   {
   if (pros[i].ProcessName.ToLower().Contains("powerpnt"))
        {
          pros[i].Kill();
        }
   }
2 голосов
/ 22 декабря 2009

Вот статья MSDN, которая описывает проблему и решение

http://msdn.microsoft.com/en-us/library/aa679807%28office.11%29.aspx

в основном повторная рекомендация должна быть сделана (Примечание: две итерации GC.Collect ()

 GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers(); 
1 голос
/ 11 июня 2009

Похоже, что вы делаете видимым экземпляр приложения Power Point, но если нет, возможно, существует диалоговое окно, которое вы не видите - возможно, диалоговое окно сохранения изменений. Если приложение работает скрытно, сделайте его видимым, чтобы увидеть, появляются ли какие-либо из таких диалогов, не позволяя закрыть Power Point.

0 голосов
/ 02 февраля 2017

Эта работа для меня

       var app = new PowerPoint.Application();
            PowerPoint.Presentations pres = app.Presentations;
            PowerPoint.Presentation ActivePresentation = pres.Open(fileIn, MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse);
(...)
            ActivePresentation.SaveAs(fileOut, PowerPoint.PpSaveAsFileType.ppSaveAsDefault, MsoTriState.msoTrue);

            ActivePresentation.Close();
            app.Quit();
0 голосов
/ 11 июня 2009

После вызова Quit () для вашего ppApp объекта попробуйте следующее

System.Runtime.InteropServices.Marshal.ReleaseComObject(ppApp);

Никаких обещаний, однако, это может сработать или вообще ничего не сделать. Правильное закрытие Office COM всегда было для меня чем-то вроде вуду.

...