Exception for powerpoint Interop while reading slides

1

I have a block of code which reads powerpoint slides and creates xml for them.Everything is working fine on my local machine.but on server,when second slide is read.I Get the exception: EXCEPTION:The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)) for Powerpoint Interop

Function Throwing Error:

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

Any help guys??

c#
interop
powerpoint
office-interop
asked on Stack Overflow Jul 8, 2013 by Milind Anantwar • edited Jul 8, 2013 by Milind Anantwar

3 Answers

0

Have you tried setting DisplayAlert to false?

 PowerPoint_App.DisplayAlerts = Powerpoint.PpAlertLevel.ppAlertsNone

You normally get this exception when Office opens a dialogue, and your application is unable to continue.

answered on Stack Overflow Jul 8, 2013 by SvenPam • edited Jul 8, 2013 by SvenPam
0

My guess is that ReadSlides is changing the value of presentation.Slides.Count. This would happen if you were adding slides to, or removing slides from your presentation within ReadSlides.

I would pull this out into it's own variable and then use this variable in your for loop, like so:

var slideCount = presentation.Slides.Count;

for (int i = 0; i < slideCount; i++)
{
    //etc etc
answered on Stack Overflow Jul 8, 2013 by JMK • edited Jul 8, 2013 by JMK
0

Quoting from your question:

Everything is working fine on my local machine.but on server,when second slide is read.I Get the exception

If your app is truly running in an unattended server environment, be aware that Microsoft specifically does not support COM for Office. Their warnings are fairly explicit. Here's a snippet:

If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.

answered on Stack Overflow Jan 14, 2017 by decaffeinated

User contributions licensed under CC BY-SA 3.0