读取幻灯片时powerpoint Interop的例外情况

时间:2013-07-08 08:21:16

标签: c# interop powerpoint office-interop

我有一段代码,它读取powerpoint幻灯片并为它们创建xml。一切正常在我的本地机器上工作。但是在服务器上,当读取第二张幻灯片时。我得到例外: EXCEPTION:The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)) for Powerpoint Interop

功能投掷错误:

public string AddPPTPages(long templateid, long pptFileId)
    {
        string strPptFilePath = "";
        string strSuccess = "";

        using (var dc = new DataContext())
        {
            var template = dc.Templates.GetByID(templateid);
            template.ExtendedData = "<template><pptfileid>" + pptFileId + "</pptfileid></template>";
            template.Save();
            dc.SubmitChanges();
            var file = dc.FileHandles.GetByID(Convert.ToInt64(pptFileId));
            file.EnsureUrlFiles();
            strPptFilePath = file.GetPhysicalPath(file.FileName);//get path of original ppt file 
        }
        try
        {
            using (new Impersonator(Installs.Current.PPTUser, null, Installs.Current.PPTPassword))
            {

                PowerPoint.Application PowerPoint_App = new PowerPoint.Application();//Open PowerPoint app/process
                PowerPoint.Presentation presentation = null;//initialize presentation to null
                try
                {
                    PowerPoint_App.Visible = MsoTriState.msoTrue;//set app visibility to true
                    presentation = PowerPoint_App.Presentations.Open(strPptFilePath, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoTrue);//open powerpoint presentation using path strPptFilePath

                    templateID = templateid;//required for readslide function

    /////////ERROR is THROWN FOR BELOW LINE//////////////////
                    for (int i = 0; i < presentation.Slides.Count; i++)
                    {
                        ReadSlides(presentation, i);//call to read current slide
                    }
                    using (var dc = new DataContext())
                    {
                        var template = dc.Templates.GetByID(templateID);
                        template.FixPageIndexes();
                        template.Save();
                        dc.SubmitChanges();
                    }
                    presentation.Close();//close presentation
                    PowerPoint_App.Quit();//quit opened powerpoint app/process
                }
                catch (Exception ex)
                {
                    strSuccess = ex.ToString();

                }
                finally
                {
                    while (Marshal.FinalReleaseComObject(presentation) != 0) { }
                    presentation = null;
                    while (Marshal.FinalReleaseComObject(PowerPoint_App) != 0) { }

                    PowerPoint_App = null;
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    KillPPTProcess();//find ppt process in taskmanager and kill it
                }
            }
        }
        catch (Exception e)
        {
            strSuccess = e.ToString();
            MindMatrix.Libraries.Entities.ExceptionMessage.HandleException(e, null);
            Loggers.HandleException2(e);
        }
        return strSuccess;
    }

private void ReadSlides(PowerPoint.Presentation presentation, int i)
    {
        try
        {
            string strPptXml = "";
            //get number of objects(text and image) present in current slide
            foreach (var item in presentation.Slides[i + 1].Shapes)
            {
                var shape = (PowerPoint.Shape)item;
                strPptXml += ReadShape(shape);//read object and add it to xml
            }
            int height = ConvertToPixel(presentation.Slides[i + 1].Master.Height);//get height of current slide
            int width = ConvertToPixel(presentation.Slides[i + 1].Master.Width);//get width of current slide

            strFileImage = Installs.Current.GetTempDirectory(DirectoryType.PPT);//get the temporary folder path for current loggedin user in machine

            if (System.IO.Directory.Exists(strFileImage) == false)
            {
                System.IO.Directory.CreateDirectory(strFileImage);
            }
            strFileImage = strFileImage + "\\" + (i + 1) + ".png";//create image path for slide snapshot
            presentation.Slides[i + 1].Export(strFileImage, "png", width, height);//create snapshot as png image to temp folder
            strPptXml = "<slides datasourceid='0' repeaterid = '0' id='" + presentation.Slides[i + 1].SlideID + "' >" + strPptXml + "</slides>";//create slide xml using slideid and ppt xml(contains text and image objects of slide)

            MemoryStream ms = new MemoryStream();
            System.Drawing.Image imageIn;
            imageIn = System.Drawing.Image.FromFile(strFileImage);//Creates an Image from location strFileImage.
            imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

            using (var dc = new DataContext())
            {
                var template = dc.Templates.GetByID(templateID);
                //template.createPptPage(strPptXml, height, width, ms);//call to create ppt page for current slide
                template.createPptPage(RemoveTroublesomeCharacters(strPptXml), height, width, ms);//call to create ppt page for current slide
                dc.SubmitChanges();
            }
        }
        catch (Exception e)
        {

            Loggers.HandleException2(e);
        }
    }

任何帮助人员?

3 个答案:

答案 0 :(得分:0)

您是否尝试将DisplayAlert设为false?

 PowerPoint_App.DisplayAlerts = Powerpoint.PpAlertLevel.ppAlertsNone

当Office打开对话框时,您通常会收到此异常,并且您的应用程序无法继续。

答案 1 :(得分:0)

我的猜测是 ReadSlides 正在更改 presentation.Slides.Count 的值。如果您要在 ReadSlides 中向幻灯片中添加幻灯片或从中删除幻灯片,就会发生这种情况。

我会把它拉到它自己的变量中,然后在for循环中使用这个变量,如下所示:

var slideCount = presentation.Slides.Count;

for (int i = 0; i < slideCount; i++)
{
    //etc etc

答案 2 :(得分:0)

引述您的问题:

  

在我的本地计算机上一切正常。但在服务器上,当读取第二张幻灯片时。我得到例外

如果您的应用确实在无人值守的服务器环境中运行,请注意Microsoft特别支持支持COM for Office。他们的警告相当explicit。这是一个片段:

  

如果从服务器端解决方案使用Office应用程序,则应用程序将缺少许多成功运行的必要功能。此外,您将承担整体解决方案稳定性的风险。