2009-10-26 140 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 

我希望這可以幫助別人跳過額外的努力,我不得不把在