Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过C#启动的PowerPoint不会退出_C#_Com_Powerpoint - Fatal编程技术网

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

通过C#启动的PowerPoint不会退出,c#,com,powerpoint,C#,Com,Powerpoint,嘿,我正在从一个C#WinForms应用程序自动化PowerPoint和Excel;我要做的是从PowerPoint中读取幻灯片并将其保存在Excel中,然后退出这两个应用程序。Excel成功退出,但PowerPoints不会退出。问题是当我第一次转换时它不会退出,但当我再次转换时它会退出 这是我的密码 try { PowerPoint.Application ppApp; PowerPoint.Presentation ppPres; List<Company&g

嘿,我正在从一个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();
}
试试看
{
ppApp应用程序;
PowerPoint.演示文稿ppPres;
上市公司=新上市公司();
ppApp=新的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;

对于(int slide=1;slide看起来您正在使Power Point应用程序实例可见,但如果不可见,则可能存在您看不到的对话框-可能是保存更改对话框。如果应用程序运行时处于隐藏状态,则使其可见,以查看是否有任何此类对话框弹出,从而阻止Power Point关闭。

ppApp对象调用Quit()后,请尝试以下操作

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

但是,没有承诺,它可能会起作用,或者可能什么都不起作用。正确关闭Office COM东西对我来说一直有点像巫毒。关闭Microsoft Office应用程序一开始可能看起来很棘手,但一旦确定了正确的操作顺序,实际上一点也不难

发布MS Office应用程序可以分两个阶段安全有效地完成:

(1) 首先释放命名变量中未包含引用的所有次要对象。可以通过调用和来执行此操作。请注意,如果使用Visual Studio Tools for Office(VSTO),则需要调用这对命令两次,以便成功释放COM对象。但是,您没有使用VSTO,因此只需调用一次即可

(2) 然后使用对每个变量的调用,通过命名变量显式释放所持有的对象

请记住显式释放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应用程序:

希望这有帮助,让我们知道它是如何进行的


--Mike

这是一篇MSDN文章,描述了问题和解决方案

基本上需要重新编译(注意:GC.Collect()的两次迭代)


大家好。最近我发现从垃圾收集到退出和关闭对象对我来说没有任何效果。所以我想出了一个替代方案。我在工作完成后发现了正在运行的进程,然后通过代码终止了它

代码:

 Process[] pros = Process.GetProcesses();
  for (int i = 0; i < pros.Count(); i++)
   {
   if (pros[i].ProcessName.ToLower().Contains("powerpnt"))
        {
          pros[i].Kill();
        }
   }
Process[]pros=Process.getprocesss();
for(int i=0;i
这是我的工作

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

不,没有这样的事:(嘿,迈克,谢谢,但这不起作用。我想告诉你的一件事是,当我关闭自己的WinForm应用程序时,PowerPoint也会关闭。是的,当你关闭WinForm应用程序时,它会关闭是正常的,因为当运行时被拆除时,你未能释放的任何对象最终都会被释放。你可以尝试调用GC.Collect()和GC.WaitForPending()终结器两次。如果您没有使用VSTO,这应该无关紧要,但不会造成伤害。您需要考虑这里还有哪些其他变量…(请参阅下一条注释)。您需要考虑这里还有哪些其他变量,然后释放它们。例如:(1)任何地方有其他静态变量吗?(2)您的InitializeCompany(ref comp,ppPres.Slides[slide])调用的作用是什么?如果它在您的公司对象中存储对PowerPoint幻灯片的引用,则此调用将与companys.Add(comp)一起创建对PowerPoint引用的永久引用。必须通过调用Marshal.FinalReleaseComObject()来断开这些调用否则PowerPoint将挂起。我不知道是否发生了这种情况,但您需要释放所有PowerPoint引用。底线。将office代码与Winform类分开。不要直接从窗体的类调用它。否则COM对象会被卡在内存中,直到您杀死窗体。使用这些InteropService是非常困难的很有压力,但这个解决方案奏效了,所以谢谢你。有趣的是,多年后它仍然有同样的问题/困难。它对我也有效,但我不明白为什么这两个电话改变了我的生活。
       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();