2009-10-26 40 views
4

我有一个脚本,可以从我的应用程序打开Powerpoint并导出所有幻灯片。之后,我需要关闭应用程序。C#: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); 

    } 

} 
} 
+0

您已经编辑上面的代码,但它仍然是不正确的。您可以调用PP.Presentations(和Presentation.Slides)两次,一次使用它们,然后一次释放参考。然而,它不会像那样工作 - 每次调用它们时,都会创建另一个参考。您需要调用它们一次,然后将该参考存储在一个变量中,然后您可以释放它(根据Andre的答案)。 – 2009-10-26 15:46:33

+1

[通过C#发起的PowerPoint不会退出]可能重复](http://stackoverflow.com/questions/981547/powerpoint-launched-via-c-sharp-does-not-quit) – 2012-08-07 18:17:52

+0

尝试调用另一个收集并等待方法,在完成这个方法后,调用 – nawfal 2014-02-05 14:58:19

回答

2

查看同一主题在这里讨论:c# and excel automation - ending the running instance

它涵盖了Excel中,但原则是完全一样的。

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

+0

ell,我试图释放所有有Powerpoint引用的对象,似乎没有任何帮助......我将所有Slide对象与Marshal.ReleaseComObject(幻灯片)一起释放, ;。 – MysticEarth 2009-10-26 14:07:16

+1

您是否正在发布PP.Presentations和Presentation.Slides对象?人们经常忘记使用的集合。 – 2009-10-26 14:20:03

+0

是的,我也发布了这些。 – MysticEarth 2009-10-26 14:23:37

0

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

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

我编辑了我的代码与您的例子,但没有运气。我不明白,因为它似乎发布每个Powerpoint的参考。 – MysticEarth 2009-10-26 15:03:29

+0

只是一个猜测:发布演示文稿和PP后是否尝试调用GC.Collect? – 2009-10-26 15:10:38

+0

刚刚尝试过;没有成功... 我放弃:( – MysticEarth 2009-10-26 15:17:03

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; 
     } 
    } 
0

我,从我的VB打开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 

我希望这可以帮助别人跳过额外的努力,我不得不把在