Creating PowerPoint presentations in C# Visual Studio, I realized that my WinForm timer hangs; I can’t even move my Application around the screen. Is there a way to create my PowerPoint in the background?
To illustrate the issue, I have this code example in "C:myPowerPointHangs" for C# Windows Forms .NET
I have added from Reference Manager>COM>Type Libraries the assembly reference "Microsoft Office 16.0 Object Library" (Version 2.8), or also from NuGet: "Microsoft.Office.Interop.PowerPoint" (Version 15.0.4420.1018) added to my project…
I have created two Timers.
-
Timer1 will show 100ms steps counting in the caption of my WinForm, and it will start Timer2 at 2000 milliseconds then continue counting.
-
Timer2 runs once. It creates the slide and the matrix of boxes. This takes several seconds. Finally, it saves the presentation. After that, my WinForm is alive again.
// Project>Add Reference>COM>Type Libraries>Microsoft Office 16.0 Object Library
// Tools>NuGet Package Manager>Manage NuGet Packages for solution>Microsoft.Office.Interop.PowerPoint 15.0.4420.1018
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Office = Microsoft.Office.Core;
using State = Microsoft.Office.Core.MsoTriState;
using System;
using System.Windows.Forms;
namespace myPowerPointHangs
{
public partial class Form1 : Form
{
readonly float u = 72.0f; // Inches
int t = 0;
int t0 { get => (++t); set => t = 0; }
string fileName = @"C:myPowerPointHangsmySlides.ppt";
public Form1() { InitializeComponent(); timer1.Start(); }
private void timer1_Tick(object sender, EventArgs e)
{
this.Text = t0.ToString() + "00ms";
if (t == 20) timer2.Start();
}
private void timer2_Tick(object sender, EventArgs e)
{
timer2.Stop();
PowerPoint.Application pptApplication = new PowerPoint.Application();
PowerPoint.Presentation ppt;
PowerPoint.Slide slide;
PowerPoint.Slides slides;
Office.MsoAutoShapeType shape;
ppt = pptApplication.Presentations.Add(State.msoTrue);
slides = ppt.Slides;
slides.Application.Caption = "mySlides";
slide = slides.Add(1, PowerPoint.PpSlideLayout.ppLayoutBlank);
shape = Office.MsoAutoShapeType.msoShapeFlowchartTerminator;
float left = 6.61f * u;
for (int col = 0; col < 5; col++)
{
float top = 0.1f * u;
for (int row = 0; row < 20; row++)
{
slide.Shapes.AddShape(shape, left, top, 0.77f * u, 0.23f * u);
int i = slide.Shapes.Count;
slide.Shapes[i].Fill.ForeColor.RGB = System.Drawing.ColorTranslator.ToWin32(System.Drawing.Color.White);
slide.Shapes[i].Line.ForeColor.RGB = System.Drawing.ColorTranslator.ToWin32(System.Drawing.Color.FromArgb(58, 58, 58));
slide.Shapes[i].TextFrame.TextRange.Font.Color.RGB = System.Drawing.ColorTranslator.ToWin32(System.Drawing.Color.FromArgb(19, 40, 79));
slide.Shapes[i].TextFrame.TextRange.Font.Size = 6.0f;
slide.Shapes[i].TextFrame.WordWrap = State.msoFalse;
slide.Shapes[i].TextFrame.TextRange.Text = col.ToString("00")+row.ToString("00");
top += slide.Shapes[i].Height + 0.02f * u;
}
left += slide.Shapes[slide.Shapes.Count].Width + 0.05f * u;
}
if (System.IO.File.Exists(fileName)) System.IO.File.Delete(fileName);
ppt.SaveAs(fileName, PowerPoint.PpSaveAsFileType.ppSaveAsPresentation, Office.MsoTriState.msoCTrue);
ppt.Close();
}
}
}
There are similar topics here and there, but do not address my question: how to run Office.Interop.PowerPoint in the background without hanging my WinForm application?
In addition, if for any reason we open a popup message in the PowerPoint App before or while creating the presentation, it generates an Exception as:
System.Runtime.InteropServices.COMException: 'Call was rejected by callee. (Exception from HRESULT: 0x80010001
2
Answers
You can write a simple void function and use multi-threading to create a new thread for power point process.
Notice: First you need to create timer1 manually.
As an answer to joshua-tristancho’s question:
I don’t know anything about powerpoint. But the process is the same as other file-handling.
Hope this will help you to the right way. If there are some errors, my apologies. Having a few glasses of Whisky 😉
Oh, you are using System.Windows.Forms.Timer….There is also a System.Timers.Timer which runs in the background and will not hookup your form. But you have to use Innnvke…Inkoke…Invoke(new action(().. (Just fooling around ;))