尝试使用Microsoft.Office.Interop.PowerPoint打开PPT文件,并将其保存为PDF(或其他文件类型)以用于大批量作业。适用于没有密码的文件。对于有密码的文件,我永远不会知道,我只想优雅地失败。但是,PowerPoint将打开对话框提示,即使我的代码中止了该线程我不能使用PowerPoint的开放线程,直到该提示被手动关闭,因此阻止了对其他文件的进一步处理。
连连呢?
我的代码的基础如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using Microsoft.Office;
using Microsoft.Office.Interop.PowerPoint;
using MT = Microsoft.Office.Core.MsoTriState;
namespace PowerPointConverter
{
public class PowerPointConverter : IDisposable
{
Application app;
public PowerPointConverter()
{
app = new Microsoft.Office.Interop.PowerPoint.Application();
app.DisplayAlerts = PpAlertLevel.ppAlertsNone;
app.ShowWindowsInTaskbar = MT.msoFalse;
app.WindowState = PpWindowState.ppWindowMinimized;
}
public bool ConvertToPDF(FileInfo sourceFile, DirectoryInfo destDir)
{
bool success = true;
FileInfo destFile = new FileInfo(destDir.Name + "\\" +
Path.GetFileNameWithoutExtension(sourceFile.Name) + ".pdf");
Thread pptThread = new Thread(delegate()
{
try
{
Presentation ppt = null;
ppt = app.Presentations.Open(sourceFile.FullName, MT.msoTrue, MT.msoTrue, MT.msoFalse);
ppt.SaveAs(destFile.FullName, PpSaveAsFileType.ppSaveAsPDF, MT.msoFalse);
ppt.Close();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ppt);
}
catch (System.Runtime.InteropServices.COMException comEx)
{
success = false;
}
});
pptThread.Start();
if (!pptThread.Join(20000))
{
pptThread.Abort();
success = false;
}
return success;
}
public void Dispose()
{
Thread appThread = new Thread(delegate()
{
try
{
if (null != app)
{
app.Quit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(app);
}
}
catch (System.Runtime.InteropServices.COMException) { }
});
appThread.Start();
if (!appThread.Join(10000))
{
appThread.Abort();
}
}
}
}
答案 0 :(得分:5)
将此VBA翻译成[无论如何]你应该好好去。
Dim oPres As Presentation
On Error Resume Next
Set oPres = Presentations.Open("c:\temp\open.pptx::BOGUS_PASSWORD::")
If Not Err.Number = 0 Then
MsgBox "Blimey, you trapped the error!" _
& vbCrLf & Err.Number & vbCrLf & Err.Description
End If
更一般地说:
Presentations.Open "filename.ext::open_password::modify_password"
如果您将密码错误的密码传递给passworded文件,则会出现可捕获的错误,但PPT不会弹出对话框。如果您向非密码文件传递密码,则只会打开。
这应该适用于新的或旧的二进制格式文件,我被告知它早在2003年就可以使用。
答案 1 :(得分:0)
感谢史蒂夫的回答。这实际上有效。
在我们尝试将ProtectedViewWindow用于此目的之前,但在某些情况下这实际上无法正常工作:
try {
windowId = pptApp.ProtectedViewWindows.Open(pptPath,
PRESENTATION_FAKE_PASSWORD).HWND;
} catch (Exception ex) {
if (!ex.Message.Contains("could not open")) {
// Assume it is password protected.
_conversionUtil.LogError(
"Powerpoint seems to be password protected.",
_conversionRequest, ex);
}
}
基于您的解决方案的代码运作良好,并且不需要为PP打开一个不必要的时间进行验证:
Presentation presentation;
try {
presentation = pptApplication.Presentations.Open(_localPptPath +
"::" + PRESENTATION_FAKE_PASSWORD + "::", MsoTriState.msoTrue,
MsoTriState.msoFalse, MsoTriState.msoFalse);
} catch (Exception e) {
// if error contains smth about password -
// assume file is password protected.
if (e.Message.Contains("password")) {
throw new ConversionException(
"Powerpoint seems to be password protected: " + e.Message,
ConversionStatus.FAIL_PASSWORD_PROTECTED);
}
// otherwice rethrow it
throw;
}