Prevent child process from creating visible windows?
Asked Answered
G

2

6

I'm trying to use Office Automation (PIA) to convert some .pptx documents into some other formats. However, PowerPoint insists on showing a progress bar even the main window is hidden.

Is there any way I can prevent PowerPoint from ever displaying any Windows to the main desktop?

Extra information:

I am mainly using C#, COM PIA for Office interop. But I'm not afraid to dig into C++ :P

I start PowerPoint using PIA like this

var app = new PowerPoint.Application();
var ppt = app.Presentations.Open("my.pptx");

// This line will show a progress dialog
ppt.SaveAs("out.pdf",
    PowerPoint.PpSaveAsFileType.ppSaveAsPDF,
    MsoTriState.msoTrue);

app.Quit();
Grecoroman answered 24/2, 2011 at 14:22 Comment(2)
Hi, c++ or c#? can you show us how you are creating and using the powerpoint application?Hispania
@Davide Piras: Here's the updated detailsGrecoroman
B
4

You can use the CreateDesktop call to create an alternate desktop before invoking the powerpoint process. This will ensure that windows created by powerpoint are not visible. However, there are a number of caveats here:

  • You will need to do this in an alternate thread; you do not want to change the desktop on your main GUI thread
  • It's probably best to initialize powerpoint once, on a dedicated thread with an alternate desktop, and keep it on that same thread until you terminate. This ensures it won't be confused by being called from multiple desktops.
  • If powerpoint pops up any kind of dialog, the user will not be able to answer it unless you switch them to the alternate desktop to interact with powerpoint.
  • If powerpoint is an out-of-process server, bad things may happen (powerpoint loads on alternate desktop, then user tries to open powerpoint manually, at which point powerpoint's main UI loads on the invisible alternate desktop). This is probably something you'll need to test carefully. This problem may be avoidable by creating an alternate Window Station as well, but as window stations are process-global, you'd need to spawn a helper child process to deal with interactions with powerpoint in this case.

You could also try using a Windows Message Hook to determine when the window is created and keep it invisible. This also has a number of caveats:

  • You'll have to find some reliable way of identifying the window of interest (window class name?)
  • If powerpoint is an out-of-process server, there will be a window in which your hook is active and might hide the wrong progress dialog (ie, one belonging to another process). To minimize this chance, test to see if powerpoint is in-process (in which case program the hook to only affect your own process), and if not, arrange for the hook to only be active for the minimum amount of time necessary to suppress the progress window.
  • Future powerpoint releases may break whatever method you use to identify the window of interest. There's little you can do about this one.
Backplate answered 24/2, 2011 at 15:6 Comment(2)
Thanks, your answer was very comprehensive. I gave up after some long trials: CreateDesktop doesn't work. It's a peculiarity with PowerPoint, but it just insists to show on WinSta0\Default; I havne't tried alternate Windows stations in depth but it requires elevated privileges which breaks my requirement :(Grecoroman
@kizzx2, try the hook technique as well, you may have more luck with it.Backplate
G
1

You can try to leave Application.Visible property with it's default value and pass MsoTriState.msoFalse to WithWindow paremeter when you open a presentation:

var application = new Application();
var document = application.Presentations.Open(fileName, MsoTriState.msoFalse, MsoTriState.msoFalse, 
    WithWindow: MsoTriState.msoFalse);

If you explicitly set Application.Visible property to MsoTriState.msoFalse you will get "Hiding the application window is not allowed" error.

Guitarist answered 28/11, 2018 at 8:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.