none
Interop - Application Busy errors while doing Powerpoint operations - 0x8001010A and 0x80004005 - HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)) RRS feed

  • Question

  • Hi,

    I am using following packages to work with MS Office Powerpint 2010 using Interop API for merging powerpoint slides from different presentations and updating the table of contents etc.  The box where I am running the code have MS Office 2010 installed.

    I am getting getting busy errors with following codes when I invoke interop powerpoint methods such slides.count, shape.hastextframe,shape has text or presentation.close etc.

       System.Runtime.InteropServices.COMException (0x8001010A)

       System.Runtime.InteropServices.COMException (0x80004005)

    I am using following packages

       Microsoft.Office.Interop.PowerPoint;
       System.Runtime.InteropServices;

        Microsoft.Office.Core

    When I write a wrapper method for each Interop call and retry for 5 times or so, it is working but it is tedious to wrap every function and retry and had to be a better way.

    I read online in one of the post said these may go away if I just use interop DLLs withouth installing Office on the box.

       1. Please provide a solution on how I can resolve this?

       2. Do we need to install MS Office 2010 for interop to work ?  if not  - What are the Office Interop dlls are required to work with Powerpoint?

    Anyhelp is very much appreciated.

    Thanks


    VM7258

    Friday, May 4, 2012 2:03 PM

Answers

  • Q2. (The easy one) it's as Tx_OfficeDev says for working on interop. However for interop to work you will need Office installed. Also to access VSTO tools you have to install Office.

    Q1. There are unresolved problems in the Office COM approach (interop) that leads to the sorts of errors your experiencing. Assuming someone doesn't find a specific problem with your code, your wrapper's probably the best solution. If you need your application to do other things quickly (i.e. maintain a responsive user interface) you can do it in a multithreaded way, which I describe here.

    Wednesday, May 9, 2012 10:34 AM

All replies

  • Hi VM7258,

    Thanks for posting int he MSDN Forum.

    I would recommend you create a simple project to reproduce your issue then share the snippet here. It will help use to aware of where has errors.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    Monday, May 7, 2012 4:32 AM
    Moderator
  • Tom,

    Here is the code.

    I can't share the sample pptx docs but these documents have editable tables & charts and all all the slides have a text with name SlideTitle" which are used to update TableOfContents table at the end.

    I get the errors I mentioned intermittently and looking for help on how to handle Application Busy error. if I create a wrapper for each Interop method and rety for 5 times, then these errors are going way but need to create for each Interop call which is tediou work. it is like creating extended Interop API with retry. is there any easy wayt to handle these errors?

    Thanks

    ---- code-----

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using PPT = Microsoft.Office.Interop.PowerPoint;
    using System.Runtime.InteropServices;
    using System.IO;
    namespace pptmerge
    {
        class Program
        {

            static bool PPT_APP_EXISTS = false;
            static string outputfile = @"c:\newreports\output.pptx";
            static string inputfileslocation = @"c:\newreports\input\";
            static string TABLE_OF_CONTENTS_NAME = "TableOfContents";
            static string SLIDE_TITLE_NAME = "SlideTitle";
            static void Main(string[] args)
            {
                PPT.Application ppApp = null;
                try
                {
                    //get the PowerPoint application
                    ppApp = getPPTApp();

                    ProcessReport(ppApp);

                }
                catch (Exception e)
                {
                    Console.WriteLine("exception :" + e);
                }
                finally
                {
                    //clean the powerpoint APP
                    cleanPPTApp(ppApp);
                }

                //wait for key press to see the output on Console
                Console.ReadKey();

            }

            public static void ProcessReport(PPT.Application ppApp)
            {


                Console.WriteLine("\n####### Merging Reports :");
                MergeReportComponents(inputfileslocation, ppApp);


                Dictionary<string, int> slideTitles = null;

                slideTitles = getSlideTitles(outputfile, ppApp);


                updatePPTs(outputfile, slideTitles, ppApp);
            }


            public static PPT.Application getPPTApp()
            {
                PPT.Application ppApp = null;
                try
                {
                    //check and see if powerpoint is running and get the reference.
                    ppApp = (PPT.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("PowerPoint.Application");
                    PPT_APP_EXISTS = true;
                }
                catch (Exception ex)
                {

                    Console.WriteLine("Couldn't find the existing PowerPoint App and Creating new one");

                    ppApp = new PPT.Application();
                    PPT_APP_EXISTS = false;
                }
                return ppApp;
            }

            public static void cleanPPTApp(PPT.Application ppApp)
            {
                if (!PPT_APP_EXISTS)
                {
                    if (ppApp != null)
                    {
                        Console.WriteLine("Cleaning up PowerPoint App....");
                        ppApp.Quit();
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(ppApp);
                        ppApp = null;
                    }

                    GC.Collect();

                }

            }

            public static void MergeReportComponents(string inputLocation,
                                     PPT.Application ppApp)
            {
                string outputfileM = null;

                outputfileM = outputfile;


                // Microsoft.Office.Interop.PowerPoint.Application ppApp = null;
                Microsoft.Office.Interop.PowerPoint.Presentations ppSet = null;
                Microsoft.Office.Interop.PowerPoint.Presentation ppMergedPresM = null;
                Microsoft.Office.Interop.PowerPoint.Slides ppMergedSlidesM = null;
                Microsoft.Office.Interop.PowerPoint.Presentation ppPres = null;
                //get all the files for this end document
                try
                {
                    var inputFilePaths = Directory.GetFiles(inputLocation, "*.pptx");
                    if (inputFilePaths != null && inputFilePaths.Length != 0)
                    {
                        //ppt docs exist


                        //initialize Powerpoint app.
                        // ppApp = new Microsoft.Office.Interop.PowerPoint.Application();
                        ppSet = ppApp.Presentations;
                        ppMergedPresM = ppSet.Add(Microsoft.Office.Core.MsoTriState.msoFalse);
                        ppMergedSlidesM = ppMergedPresM.Slides;


                        //merge all files
                        foreach (string pptname in inputFilePaths)
                        {

                            string inputPresentation = Path.GetFileName(pptname);

                            Console.WriteLine("merging file:" + inputPresentation);
                            //open input prsentation for merge
                            ppPres = ppSet.Open(pptname, Microsoft.Office.Core.MsoTriState.msoTrue, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoFalse);

                            ppMergedSlidesM.InsertFromFile(pptname, ppMergedSlidesM.Count, 1, ppPres.Slides.Count);

                            ppPres.Close();
                        }

                        ppMergedPresM.SaveAs(outputfileM);
                        Console.WriteLine("The merge process completed for monthly file:" + outputfileM);

                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("exception happened while merging using interop merge" + ex);

                    throw ex;
                }
                finally
                {

                    if (ppMergedPresM != null)
                    {
                        ppMergedPresM.Close();
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(ppMergedPresM);
                        ppMergedPresM = null;
                    }
                    if (ppSet != null)
                    {

                        System.Runtime.InteropServices.Marshal.ReleaseComObject(ppSet);
                        ppSet = null;
                    }
                    /*    if (ppApp != null)
                        {
                            ppApp.Quit();
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(ppApp);
                            ppApp = null;
                        }*/

                    GC.Collect();
                }

            }



            public static void updatePPTs(string fileName, Dictionary<string, int> slideTitles, PPT.Application ppApp)
            {

                Console.WriteLine("Updating table of contents with slide titles in filename:" + fileName);

                Microsoft.Office.Interop.PowerPoint.Presentations ppSet = null;
                Microsoft.Office.Interop.PowerPoint.Presentation ppMergedPres = null;
                try
                {

                    ppSet = ppApp.Presentations;
                    ppMergedPres = ppSet.Add(Microsoft.Office.Core.MsoTriState.msoFalse);

                    ppMergedPres = ppSet.Open(fileName, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoFalse);

                    for (int i = 0; i < ppMergedPres.Slides.Count; i++)
                    {
                        foreach (var item in ppMergedPres.Slides[i + 1].Shapes)
                        {
                            Microsoft.Office.Interop.PowerPoint.Shape shape = (Microsoft.Office.Interop.PowerPoint.Shape)item;
                            if (shape.HasTable == Microsoft.Office.Core.MsoTriState.msoTrue)
                            {
                                string shapeName = shape.Name;
                                //Console.WriteLine("table shape name:" + shapeName);
                                if (shapeName != null && shapeName.Equals(TABLE_OF_CONTENTS_NAME))
                                {
                                    //Update Table of Conetnts
                                    //check Number rows
                                    int rowCount = shape.Table.Rows.Count;
                                    int slidesCount = slideTitles.Count;
                                    if (rowCount < slidesCount)
                                    {
                                        //add rows
                                        int rowsToAdd = slidesCount - rowCount;
                                        for (int rc = 0; rc < rowsToAdd; rc++)
                                        {
                                            shape.Table.Rows.Add();
                                            //Console.WriteLine("Adding row:" + rc);
                                        }
                                    }
                                    else
                                    {
                                        //remove rows
                                        int rowsToremove = rowCount - slidesCount;
                                        for (int rc = 0; rc < rowsToremove; rc++)
                                        {
                                            //shape.Table.LastRow
                                            PPT.Table mytable = shape.Table;

                                            //Console.WriteLine("deleting row:" + rc);
                                        }

                                    }

                                    //Add slide titles to table
                                    int rowNbr = 0;
                                    foreach (string title in slideTitles.Keys)
                                    {
                                        rowNbr++;  //increment row#
                                        //Console.WriteLine("title:" + title + " slide#" + slideTitles[title]);
                                        //update cell 1
                                        var cell1shape = shape.Table.Cell(rowNbr, 1).Shape;
                                        cell1shape.TextFrame.TextRange.Text = title;
                                        //update cell 2
                                        var cell2shape = shape.Table.Cell(rowNbr, 2).Shape;
                                        cell2shape.TextFrame.TextRange.Text = slideTitles[title] + "";

                                    }

                                }
                            }
                        }
                    }

                    ppMergedPres.Save();

                }
                catch (Exception ex)
                {
                    Console.WriteLine("exception happened while merging using interop " + ex);

                    throw ex;
                }
                finally
                {
                    if (ppMergedPres != null)
                    {
                        ppMergedPres.Close();
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(ppMergedPres);
                        ppMergedPres = null;
                    }
                    if (ppSet != null)
                    {

                        System.Runtime.InteropServices.Marshal.ReleaseComObject(ppSet);
                        ppSet = null;
                    }
                    GC.Collect();
                }

            }

            // Retrieve a list of slide titles
            public static Dictionary<string, int> getSlideTitles(string fileName, PPT.Application ppApp)
            {
                Dictionary<string, int> titlesList = new Dictionary<string, int>();

                Console.WriteLine("get slide titles for the filename:" + fileName);


                Microsoft.Office.Interop.PowerPoint.Presentations ppSet = null;
                Microsoft.Office.Interop.PowerPoint.Presentation ppMergedPres = null;

                try
                {

                    ppSet = ppApp.Presentations;
                    ppMergedPres = ppSet.Add(Microsoft.Office.Core.MsoTriState.msoFalse);

                    ppMergedPres = ppSet.Open(fileName, Microsoft.Office.Core.MsoTriState.msoTrue, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoFalse);



                    for (int slidecount = 0; slidecount < ppMergedPres.Slides.Count; slidecount++)
                    {
                        foreach (var item in ppMergedPres.Slides[slidecount + 1].Shapes)
                        {
                            Microsoft.Office.Interop.PowerPoint.Shape shape = (Microsoft.Office.Interop.PowerPoint.Shape)item;
                            if (shape.HasTextFrame == Microsoft.Office.Core.MsoTriState.msoTrue)
                            {
                                if (shape.TextFrame.HasText == Microsoft.Office.Core.MsoTriState.msoTrue)
                                {
                                    string shapeName = shape.Name;
                                    if (shapeName != null && shapeName.Equals(SLIDE_TITLE_NAME))
                                    {
                                        var textRange = shape.TextFrame.TextRange;
                                        var title = textRange.Text;
                                        if (titlesList.ContainsKey(title))
                                        {
                                            // Console.WriteLine("Title already exist in the list and discarding it:" + title);
                                        }
                                        else if (slidecount != 0)
                                        {
                                            //add for all the slides except for first one.
                                            titlesList.Add(title, slidecount + 1);
                                        }


                                    }
                                }
                            }
                        }
                    }


                    ppMergedPres.Close();

                }
                catch (Exception ex)
                {
                    Console.WriteLine("exception happened while merging using interop " + ex);

                    throw ex;
                }
                finally
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(ppMergedPres);
                    ppMergedPres = null;
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(ppSet);
                    ppSet = null;
                    GC.Collect();

                }

                return titlesList;
            }

        }
    }


    VM7258

    Tuesday, May 8, 2012 1:44 PM
  • Hi VM7258,

    2. Do we need to install MS Office 2010 for interop to work ?  if not  - What are the Office Interop dlls are required to work with

    Interop will be installed when Visual Studio install.

    Have a good day,

    T.X.

    Wednesday, May 9, 2012 7:42 AM
  • Q2. (The easy one) it's as Tx_OfficeDev says for working on interop. However for interop to work you will need Office installed. Also to access VSTO tools you have to install Office.

    Q1. There are unresolved problems in the Office COM approach (interop) that leads to the sorts of errors your experiencing. Assuming someone doesn't find a specific problem with your code, your wrapper's probably the best solution. If you need your application to do other things quickly (i.e. maintain a responsive user interface) you can do it in a multithreaded way, which I describe here.

    Wednesday, May 9, 2012 10:34 AM