简体   繁体   English

防止子进程创建可见窗口?

[英]Prevent child process from creating visible windows?

I'm trying to use Office Automation (PIA) to convert some .pptx documents into some other formats. 我正在尝试使用Office Automation(PIA)将一些.pptx文档转换为其他格式。 However, PowerPoint insists on showing a progress bar even the main window is hidden. 但是,即使主窗口被隐藏,PowerPoint也会坚持显示进度条。

Is there any way I can prevent PowerPoint from ever displaying any Windows to the main desktop? 有什么办法可以阻止PowerPoint向主桌面显示任何Windows吗?

Extra information: 额外的信息:

I am mainly using C#, COM PIA for Office interop. 我主要使用C#,COM PIA for Office interop。 But I'm not afraid to dig into C++ :P 但我并不害怕深入研究C ++:P

I start PowerPoint using PIA like this 我像这样使用PIA启动PowerPoint

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();

You can use the CreateDesktop call to create an alternate desktop before invoking the powerpoint process. 您可以在调用powerpoint进程之前使用CreateDesktop调用来创建备用桌面。 This will ensure that windows created by powerpoint are not visible. 这将确保powerpoint创建的窗口不可见。 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 您不想更改主GUI线程上的桌面
  • 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. 最好在具有备用桌面的专用线程上初始化powerpoint一次,并将其保留在同一个线程上,直到您终止为止。 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. 如果powerpoint弹出任何类型的对话框,除非您将它们切换到备用桌面以与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). 如果powerpoint是一个进程外服务器,可能会发生不好的事情(备用桌面上的powerpoint加载,然后用户尝试手动打开powerpoint,此时powerpoint的主UI加载在不可见的备用桌面上)。 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. 通过创建备用Window Station也可以避免此问题,但由于窗口站是进程全局的,因此在这种情况下,您需要生成辅助子进程来处理与powerpoint的交互。

You could also try using a Windows Message Hook to determine when the window is created and keep it invisible. 您还可以尝试使用Windows消息挂钩来确定窗口何时创建并使其保持不可见。 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). 如果powerpoint是进程外服务器,则会有一个窗口,您的挂钩处于活动状态,可能会隐藏错误的进度对话框(即属于另一个进程的对话框)。 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. 为了最大限度地减少这种可能性,请测试powerpoint是否在进行中(在这种情况下,将钩子编程为仅影响您自己的进程),如果不是,则安排钩子仅在抑制所需的最小时间内处于活动状态进度窗口。
  • Future powerpoint releases may break whatever method you use to identify the window of interest. 未来的powerpoint版本可能会破坏您用于识别感兴趣窗口的任何方法。 There's little you can do about this one. 关于这一点你几乎无能为力。

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: 您可以尝试将Application.Visible属性保留为其默认值,并在打开演示文稿时将MsoTriState.msoFalse传递给WithWindow

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. 如果将Application.Visible属性显式设置为MsoTriState.msoFalse ,则会出现“不允许隐藏应用程序窗口”错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM