我有一个脚本可以从我的应用程序中打开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 :(得分: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,但原则完全相同。
摘要:您需要“释放”Presentations
,Slides
和(多个)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
我希望这可以帮助别人省下我必须付出的额外努力。