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:\myPowerPointHangs\mySlides.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
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.
// 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;
using System.Threading;
namespace myPowerPointHangs
{
public partial class Form1 : Form
{
public Form1() { InitializeComponent(); timer1.Start(); }
readonly float u = 72.0f; // Inches
int t = 0;
string fileName = @"C:\myPowerPointHangs\mySlides.ppt";
int cnt = 0;
Thread trd;
private void timer1_Tick(object sender, EventArgs e)
{
Text=cnt.ToString() + "00ms";
if (cnt++ >= 20) { cnt = 0; trd = new Thread(power_point); trd.Start(); timer1.Stop(); }
}
void power_point()
{
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();
trd.Abort();
}
}
}