2

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();
        }
    }
    }
}
4

2 に答える 2

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;
        }
于 2014-06-06T16:06:55.957 に答える