通过C#启动的PowerPoint不会退出

aki*_*kif 9 c# com powerpoint

嘿,我是从C#WinForms应用程序自动化PowerPoint和Excel; 我所做的是从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();
}
Run Code Online (Sandbox Code Playgroud)

Mik*_*lum 12

关闭你的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);
Run Code Online (Sandbox Code Playgroud)

尝试一下,我认为这应该对你有用...(如果没有,你可能需要显示更多代码.)有关详细信息,我将详细说明如何在此处正确发布Excel应用程序:

如何在C#中正确清理Excel互操作对象.

希望这有帮助,让我们知道它是怎么回事......

- 迈克

  • 你需要考虑其他变量在这里发挥作用,并释放它们.例如:(1)在任何地方都有其他静态变量吗?(2)您的InitializeCompany(ref comp,ppPres.Slides [slide])调用有什么作用?如果它存储对公司对象中PowerPoint幻灯片的引用,则此调用以及companies.Add(comp)将创建对PowerPoint引用的永久引用.必须使用对Marshal.FinalReleaseComObject()的调用来切断这些,否则PowerPoint将挂起.我不知道这是不是发生了什么,但你需要释放*ALL*你的PowerPoint参考. (2认同)