简体   繁体   English

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

[英]PowerPoint Launched via C# does not Quit

Hey I'm automating PowerPoint and Excel from a C# WinForms application; 嘿,我从C#WinForms应用程序自动化PowerPoint和Excel; what I do is read slides from PowerPoint and save them in Excel and then quit both apps. 我所做的是从PowerPoint中读取幻灯片并将其保存在Excel中,然后退出这两个应用程序。 Excel quits successfully but PowerPoints doesn't quits. Excel已成功退出,但PowerPoints未退出。 The problem is when I convert first time it doesnt quits, but when I convert again it does. 问题是,当我第一次转换它不退出时,但当我再次转换时它确实。

Here is my code 这是我的代码

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();
}

Shutting down your Microsoft Office application can seem tricky to get right at first, but once you establish the correct order of operations, it's actually not very hard at all. 关闭你的Microsoft Office应用程序起初看起来很难,但是一旦你建立了正确的操作顺序,它实际上并不是很难。

Releasing your MS Office application can be done safely and effectively in two stages: 释放MS Office应用程序可以分两个阶段安全有效地完成:

(1) First release all the minor objects to which you do not hold a reference within a named variable. (1)首先释放在命名变量中没有引用的所有次要对象。 You do this via a call to GC.Collect() and then GC.WaitForPendingFinalizers() . 您可以通过调用GC.Collect()然后调用GC.WaitForPendingFinalizers()来完成此操作 Note that if you are using Visual Studio Tools for Office (VSTO), then you need to call this pair of commands twice in order to get the COM objects to successfully release. 请注意,如果您使用的是Visual Studio Tools for Office(VSTO),则需要调用此对命令两次才能使COM对象成功释放。 You are not using VSTO, however, so calling them once is sufficient. 但是,您没有使用VSTO,因此调用它们就足够了。

(2) Then explicitly release the objects which you hold via a named variable using a call to Marshall.FinalReleaseComObject() on each variable you have. (2)然后使用对每个变量的Marshall.FinalReleaseComObject()调用,通过命名变量显式释放您保存的对象。

Remember to explicitly release all variables that you have to COM components. 请记住明确释放COM组件的所有变量。 If you miss even one, then your MS Office application will hang. 如果您错过了一个,那么您的MS Office应用程序将挂起。 In your code, you seem to have three named variables that hold a reference to your PowerPoint application: ppApp , ppPres , and cell . 在您的代码中,您似乎有三个命名变量,它们包含对PowerPoint应用程序的引用: ppAppppPrescell

Taking this all into account, I think that your cleanup should look something like the following, which makes use of using System.Runtime.InteropServices either within the namespace or at the top of the code document: 考虑到这一点,我认为您的清理应该类似于以下内容,它使用在命名空间内或代码文档顶部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);

Give it a try, I think this should work for you... (If not, you might have to show even more of your code.) For further information, I give a detailed explanation on how to properly release an Excel application here: 尝试一下,我认为这应该对你有用...(如果没有,你可能需要显示更多代码。)有关详细信息,我将详细说明如何在此处正确发布Excel应用程序:

How to properly clean up Excel interop objects in C# . 如何在C#中正确清理Excel互操作对象

Hope this helps, let us know how it goes... 希望这有帮助,让我们知道它是怎么回事......

-- Mike - 迈克

Hie folks.lately i have observed that nothing worked out for me from garbage collect to quitting and closing objects. Hie folks.lately我发现从垃圾收集到退出和关闭物体对我来说没有任何效果。 so i came up with an alternative. 所以我提出了另一种选择。 i found out the running process once my job was done,and then killed it through code. 我的工作完成后,我发现了正在运行的进程,然后通过代码将其杀死。

Code: 码:

 Process[] pros = Process.GetProcesses();
  for (int i = 0; i < pros.Count(); i++)
   {
   if (pros[i].ProcessName.ToLower().Contains("powerpnt"))
        {
          pros[i].Kill();
        }
   }

Here is a MSDN article that describes the problem and solution 这是一篇描述问题和解决方案的MSDN文章

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

basically recomondation is to do(Note : two iterations of GC.Collect() 基本上是重做(注意:GC.Collect()的两次迭代

 GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers(); 

It looks like you are making the Power Point application instance visible, but if not, it's possible that there is a dialog being presented that you don't see - perhaps a save changes dialog. 看起来您正在使Power Point应用程序实例可见,但如果没有,则可能会出现一个您看不到的对话框 - 可能是保存更改对话框。 If the app is running hidden, make it visible to see if any such dialogs are popping up, preventing Power Point from closing. 如果应用程序正在隐藏运行,请将其显示以查看是否弹出任何此类对话框,从而阻止Power Point关闭。

This Work for me 这对我有用

       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();

After invoking Quit() for your ppApp object try the following 在为ppApp对象调用Quit()之后 ,请尝试以下操作

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

No promises however, it might work, or it might do nothing at all. 然而,没有承诺,它可能会起作用,或者它根本不会做任何事情。 Properly closing down Office COM stuff has always been a bit like voodoo for me. 正确关闭Office COM的东西对我来说一直有点像伏都教。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM