Link to home
Start Free TrialLog in
Avatar of earseev
earseevFlag for Switzerland

asked on

Release PowerPoint process after SaveAs

The code in the code snippet does not release PowerPoint process.
When I replace
objPres.SaveAs(saveFileName
                        , Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsPresentation
                        , Microsoft.Office.Core.MsoTriState.msoFalse);
with:
objPres.SaveAs("D:\\Data\\Rad\\shared\\workspace\\Test\\data\\!!!!.ppt"
                        , Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsPresentation
                        , Microsoft.Office.Core.MsoTriState.msoFalse);

then PowerPoint process released successfully.
Are there any way to release PowerPoint process without hard coding in SaveAs?
private void mtMultiGradiantButton3_Click(object sender, EventArgs e)
        {
//            string saveFileName = null;
            string saveFileName = "D:\\Data\\Rad\\shared\\workspace\\Test\\data\\!!!!.ppt";
            if (this.saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
 
//                saveFileName = this.saveFileDialog1.FileName;
 
                CultureInfo oldCulture = null;
 
                PowerPoint.ApplicationClass oPPT = null;
                PowerPoint.Presentations objPresSet = null;
                PowerPoint.Presentation objPres = null;
                PowerPoint.Slides slides = null;
 
                try
                {
                    oldCulture = Thread.CurrentThread.CurrentCulture;
                    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us");
                    oPPT = new PowerPoint.ApplicationClass();
                    oPPT.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
                    objPresSet = oPPT.Presentations;
                    objPres = objPresSet.Open(GetTempDirectory() + lvFiles2.Items[0].Text, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoTrue, Microsoft.Office.Core.MsoTriState.msoTrue);
                    slides = objPres.Slides;
//   --------------------- some code here -----------------------
                    //objPres.SaveAs("D:\\Data\\Rad\\shared\\workspace\\Test\\data\\!!!!.ppt"
                    objPres.SaveAs(saveFileName
                        , Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsPresentation
                        , Microsoft.Office.Core.MsoTriState.msoFalse);
                }
                catch (Exception ex)
                {
                    this.label2.Text = "ERROR 4: Exception: " + ex.Message + ". " + ex.StackTrace + ". " + ex.Source;
                }
                finally
                {
                    try
                    {
 
                        saveFileName = null;
 
                        Thread.CurrentThread.CurrentCulture = oldCulture;
 
                        oldCulture = null;
 
                        slides = null;
 
                        Cursor.Current = Cursors.Default;
 
                        objPres.Close();
                        while (System.Runtime.InteropServices.Marshal.ReleaseComObject(objPres) > 0) { };
                        objPres = null;
 
                        while (System.Runtime.InteropServices.Marshal.ReleaseComObject(objPresSet) > 0) { };
                        objPresSet = null;
 
                        oPPT.Quit();
                        while (System.Runtime.InteropServices.Marshal.ReleaseComObject(oPPT) > 0) { };
                        oPPT = null;
 
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                    }
                    catch (Exception ex)
                    {
                        this.label2.Text = "ERROR 5: Exception: " + ex.Message + ". " + ex.StackTrace + ". " + ex.Source;
                    }
                }

Open in new window

Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Working with COM objects in .NET is tricky.  COM uses reference counting, but .NET doesn't.  The wrapper Interop classes handle that COM requirement, but not completely.  The System.Runtime.InteropServices.Marshal class has the ReleaseComObject method that is used to clear the reference counting, so that the object can be released from memory.

Bob
Avatar of earseev

ASKER

Thank you for the answer, Bob. In my code I am already using
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(objPresSet) > 0) { };
This did not help to release an object.
Are you calling quit on oPPT?

Bob
Avatar of earseev

ASKER

Yes, I am calling:
                        objPres.Close();
                        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objPres);
                        objPres = null;

                        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objPresSet);
                        objPresSet = null;

                        oPPT.Quit();
                        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oPPT);
                        oPPT = null;*/

                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
Another possibility is that there is a dialog box that you can't see because the application is invisible.  You might want to debug by setting the Application.Visible property.

Bob
Avatar of earseev

ASKER

Just did the debugging with oPPT.Visible = MsoTriState.true.
No hidden dialog box found.
And, it justs getting deeper and deeper (d'oh).

I am assuming that 'saveFileName' is a valid file name and you have the rights to save to that file.  It is the same as the value that hard-coded, right?

Bob

Avatar of earseev

ASKER

Yes, the value is the same as hard-coded.
Some people laugh when I say that COM in .NET is tricky.  Maybe I should show them this question as proof *BIG GRIN*.

What type of application are you working with?  WinForms or web site?

Bob
Avatar of earseev

ASKER

Yes, looks like that .net has problems with COM.
I am working with WinForms.
Here is a different tack--what are you trying to do here?

Bob
Avatar of earseev

ASKER

I have a directory with single PowerPoint slides.
After button click I am opening SaveFileDialog, type output file name, then add single PPT-slides into 1 big PPT-presentation.
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sample usage:

            PresentationMerger merger = new PresentationMerger();
            string myDocuments = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            merger.ImportSlides(myDocuments, @"C:\Temp\Presentation1.ppt");

Bob
Avatar of earseev

ASKER

Thank you, Bob. Very good solution, as always.