C#:Powerpoint没有退出?

时间:2009-10-26 13:52:37

标签: c# visual-studio com powerpoint

我有一个脚本可以从我的应用程序中打开Powerpoint并导出所有幻灯片。 之后,我需要关闭申请。

我试过没有运气。你能帮忙吗?

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Powerpoint = Microsoft.Office.Interop.PowerPoint;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
using System.Runtime.InteropServices;

namespace PresentrBuilder
{


class PowerpointConverter
{

    public static void Convert(String file, String safeFile)
    {
        Powerpoint.Application PP;
        Powerpoint.Presentation Presentation;

        PP = new Powerpoint.ApplicationClass();
        PP.Visible = MsoTriState.msoTrue;
        PP.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowMinimized;
        Presentation = PP.Presentations.Open(file, MsoTriState.msoFalse, MsoTriState.msoTrue, MsoTriState.msoTrue);

            // Voor elke slide, exporteren
            String exportSlidesPath = Path.Combine(Properties.Settings.Default.CacheDir, @"presentatienaam1\slides");

            // Kijk of de directory bestaat
            if (!Directory.Exists(exportSlidesPath))
            {
                Directory.CreateDirectory(exportSlidesPath);
            }

                // Kijk of er al bestanden in de directory staan
                // Zo ja: verwijderen
                String[] files = Directory.GetFiles(exportSlidesPath, "*.png");
                if (files.Length > 0)
                {
                    foreach (string fileName in files)
                    {
                        File.Delete(Path.Combine(exportSlidesPath, fileName));
                    }
                }

            // Elke slide exporteren
            foreach (Slide slide in Presentation.Slides)
            {
                slide.Export(Path.Combine(exportSlidesPath, "slide_" + slide.SlideIndex + ".png"), "PNG", 1024, 768);
                Marshal.ReleaseComObject(slide);
            }


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

        Marshal.ReleaseComObject(PP.Presentations);
        Marshal.ReleaseComObject(Presentation.Slides);

        Presentation.Close();
        Marshal.FinalReleaseComObject(Presentation);

        PP.Quit();
        Marshal.FinalReleaseComObject(PP);

    }

}
}

4 个答案:

答案 0 :(得分:3)

如果其他人正在努力解决这个问题(在浏览幻灯片后无法关闭PPT),即使在完成所有垃圾收集和释放资源之后,我今天也花了很多时间用这个来解决问题。我的解决方案是,而不是使用foreach迭代幻灯片,我做了如下:

        Microsoft.Office.Interop.PowerPoint.Application powerpoint;
        Microsoft.Office.Interop.PowerPoint.Presentation presentation;
        Microsoft.Office.Interop.PowerPoint.Presentations presentations;

        powerpoint = new Microsoft.Office.Interop.PowerPoint.ApplicationClass();
        powerpoint.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
        presentations = powerpoint.Presentations;

        presentation = presentations.Open(localPath, MsoTriState.msoFalse, MsoTriState.msoTrue, MsoTriState.msoTrue);


        //String presentationTitle = objPres.Name;
        Microsoft.Office.Interop.PowerPoint.Slides slides = presentation.Slides;
        **for (int i = 1; i <= slides.Count; i++)
        {
            Microsoft.Office.Interop.PowerPoint.Slide slide = slides[i];
            String slideName = slide.Name;
            releaseCOM(slide);
        }**

这是我的releaseCOM方法:

    private static void releaseCOM(object o)
    {
        try
        {
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(o);
        }
        catch { }
        finally
        {
            o = null;
        }
    }

答案 1 :(得分:2)

请参阅此处有关同一主题的讨论:c# and excel automation - ending the running instance

它涵盖了Excel,但原则完全相同。

摘要:您需要“释放”PresentationsSlides和(多个)Slide个对象。顺便说一下,我不打扰将变量设置为null。这不是必要的或有帮助的。

答案 2 :(得分:0)

作为加里答案的补充: 为了释放集合,您必须将它们分配给临时变量。 (我在下面的例子中使用幻灯片和演示文稿作为临时变量)。

  // removed using statements...

    namespace PresentrBuilder
    {


      class PowerpointConverter
      {

      public static void Convert(String file, String safeFile)
      {
        Powerpoint.Application PP;
        Powerpoint.Presentation Presentation;

        PP = new Powerpoint.ApplicationClass();
        // ...
        var presentations = PP.Presentations;
           try
            {
        Presentation = presentations.Open(file, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);

            // Voor elke slide, exporteren
            // ...

            // Elke slide exporteren
            var slides = Presentation.Slides;

            foreach (Slide slide in slides)
            {
                slide.Export(Path.Combine(exportSlidesPath, "slide_" + slide.SlideIndex + ".png"), "PNG", 1024, 768);
                Marshal.ReleaseComObject(slide);
            }
  Marshal.ReleaseComObject(presentations);
        Marshal.ReleaseComObject(slides);

        Presentation.Close();
        Marshal.FinalReleaseComObject(Presentation);
         }
        catch (System.Exception err){}
        finally{

       // GC.WaitForPendingFinalizers();    

        PP.Quit();
        Marshal.FinalReleaseComObject(PP);
        GC.Collect();
      } 
 } } }

答案 3 :(得分:0)

我有代码从我的vb.net应用程序打开powerpoint,运行幻灯片放映,然后关闭它。在臀部找到我之后不得不放弃的所有com对象真是太痛苦了。这是代码:

Imports MSWord = Microsoft.Office.Interop.Word
Imports MSPowerPt = Microsoft.Office.Interop.PowerPoint
Imports MSExcel = Microsoft.Office.Interop.Excel

Dim MSPowerPtApp As MSPowerPt.Application
Dim MSPowerPtPresentation As MSPowerPt.Presentation
Dim MSPowerPtPresentations As MSPowerPt.Presentations
Dim MSPowerPtSettings As MSPowerPt.SlideShowSettings
Dim MSPowerPtSlideShowWindow As MSPowerPt.SlideShowWindow
Dim MSPowerPtSlideShowWindows As MSPowerPt.SlideShowWindows

Function Display_PowerPoint_Show(ByVal filename As String)
  Dim MSPowerPtSlides As MSPowerPt.Slides
  Display_PowerPoint_Show = True
  Try
    If (Not FileExists(filename)) Then
      Display_PowerPoint_Show = False
      MsgBox("Display_PowerPoint_Show: Text file: " & filename & " not found", MsgBoxStyle.Information, "File Not Found")
      GoTo Exit_Display_PowerPoint_Show
    End If

    MSPowerPtApp = New MSPowerPt.Application
    MSPowerPtApp.Visible = True
    MSPowerPtApp.WindowState = MSPowerPt.PpWindowState.ppWindowMinimized

    'Create a new presentation that is based on the specified template.
    MSPowerPtPresentations = MSPowerPtApp.Presentations
    MSPowerPtPresentation = MSPowerPtPresentations.Open(lbFiles.SelectedValue, True)
    MSPowerPtSlides = MSPowerPtPresentation.Slides

    If (MSPowerPtSlides.Count = 0) Then
      MsgBox("This Powerpoint file has no slides", MsgBoxStyle.Information, "No Slides in File")
      GoTo ClosePowerPointFile
    End If

    MSPowerPtSettings = MSPowerPtPresentation.SlideShowSettings
    MSPowerPtSettings.StartingSlide = 1
    MSPowerPtSettings.EndingSlide = 1

    ''Run the slide show and wait for the slide show to end.
    MSPowerPtSlideShowWindow = MSPowerPtSettings.Run()
    MSPowerPtSlideShowWindows = MSPowerPtApp.SlideShowWindows

    Do While MSPowerPtSlideShowWindows.Count >= 1
      System.Windows.Forms.Application.DoEvents()
    Loop

    'Close the presentation without saving changes and then quit MSPowerPt.
    MSPowerPtPresentation.Saved = True
    MSPowerPtPresentation.Close()

    RemoveComObjRef(MSPowerPtSlideShowWindow)
    RemoveComObjRef(MSPowerPtSlideShowWindows)
    RemoveComObjRef(MSPowerPtSettings)

ClosePowerPointFile:
    RemoveComObjRef(MSPowerPtSlides)
    RemoveComObjRef(MSPowerPtPresentation)
    RemoveComObjRef(MSPowerPtPresentations)

    'Quit MSPowerPt.
    MSPowerPtApp.Quit()
    RemoveComObjRef(MSPowerPtApp)
    GC.Collect()

  Catch ex As Exception
    Display_PowerPoint_Show = False
    MsgBox("Display_PowerPoint_Show - File: " & filename & ", Error: " & ex.Message & " reading file", _
           MsgBoxStyle.Information, "Error Reading File")
  End Try

Exit_Display_PowerPoint_Show:
End Function

'RemoveComObjRef function to remove reference.
Private Sub RemoveComObjRef(ByVal ComObject As Object)
  Try
    System.Runtime.InteropServices.Marshal.ReleaseComObject(ComObject)
  Catch
  Finally
    ComObject = Nothing
  End Try
End Sub

我希望这可以帮助别人省下我必须付出的额外努力。