Implementing Multi-Process PowerPoint Operations in C#
PowerPoint typically operates within a single process, causing sequential blocking when handling multiple large presentations (e.g., >1GB). This often leads to unresponsive instances, hindering all operations. Terminating and restarting unresponsive processes provides limited relief but fails when processing numerous large files concurrently.
A robust solution involves launching PowerPoint under distinct user accounts. Each user session runs in a separate process, enabling parallel operations. This approach requires programmatically creating users (with administrative privileges) or pre-configuring accounts via Windows settings.
Control processes for each PowerPoint instance communicate via inter-process channels (e.g., pipes, WM_COPYDATA). These channels relay commands (open, navigate, media control) to worker processes operating under designated credentials.
Process Initialization with Alternate Credentials
public void LaunchWithCredentials(string executablePath, string username, string password, string arguments)
{
using (var securePassword = new SecureString())
{
foreach (char c in password ?? string.Empty)
securePassword.AppendChar(c);
var processInfo = new ProcessStartInfo
{
FileName = executablePath,
Arguments = arguments,
UserName = username,
Password = securePassword,
Domain = ".",
LoadUserProfile = true,
UseShellExecute = false
};
Process.Start(processInfo);
}
}
PowerPoint Interaction Operations
private Application InitializePowerPoint() => new Application();
private void TerminatePowerPoint(ref Application pptInstance)
{
try
{
pptInstance?.Quit();
}
catch (Exception ex) { /* Log error */ }
finally
{
pptInstance = null;
GC.Collect();
}
}
public void OpenPresentation(Application pptApp, string filePath)
{
if (pptApp == null) return;
filePath = filePath.Replace('/', '\\');
try
{
// Open read-only with placeholder password to prevent lock
Presentation pres = pptApp.Presentations.Open(
$"{filePath}::DummyPassword",
ReadOnly: MsoTriState.msoTrue,
Untitled: MsoTriState.msoTrue,
WithWindow: MsoTriState.msoFalse);
// Extract dimensions and slide count
double width = pres.PageSetup.SlideWidth;
double height = pres.PageSetup.SlideHeight;
int slideCount = pres.Slides.Count;
SlideShowWindow showWindow = pres.SlideShowSettings.Run();
}
catch (Exception ex) { /* Handle error */ }
}
public void CloseShow(SlideShowWindow window)
{
try { window?.View.Exit(); }
catch { /* Ignore */ }
}
public void NavigateToSlide(SlideShowWindow window, int slideIndex)
{
try { window?.View.GotoSlide(slideIndex); }
catch { /* Ignore */ }
}
public void AdvanceSlide(SlideShowWindow window)
{
try { window?.View.Next(); }
catch { /* Ignore */ }
}
public void RetreatSlide(SlideShowWindow window)
{
try { window?.View.Previous(); }
catch { /* Ignore */ }
}
Reference
- Enabling Concurrent PowerPoint Process Execution