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

发布于 2024-10-18 17:36:10 字数 502 浏览 3 评论 0原文

我正在尝试使用办公自动化 (PIA) 将一些 .pptx 文档转换为其他格式。然而,即使主窗口被隐藏,PowerPoint仍然坚持显示进度条。

有什么方法可以阻止 PowerPoint 在主桌面上显示任何 Windows?

额外信息:

我主要使用 C#、COM PIA 进行 Office 互操作。但我并不害怕深入研究 C++ :P

我像这样使用 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();

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

难以启齿的温柔 2024-10-25 17:36:10

您可以使用 CreateDesktop 在调用 powerpoint 进程之前调用创建备用桌面。这将确保由 powerpoint 创建的窗口不可见。但是,这里有一些警告:

  • 您需要在备用线程中执行此操作;您不想更改主 GUI 线程上的桌面
  • 最好在具有备用桌面的专用线程上初始化 powerpoint 一次,并将其保留在同一线程上,直到终止。这确保了它不会因从多个桌面调用而感到困惑。
  • 如果 powerpoint 弹出任何类型的对话框,用户将无法回答它,除非您将他们切换到备用桌面与 powerpoint 交互。
  • 如果 powerpoint 是进程外服务器,则可能会发生不好的事情(powerpoint 加载到备用桌面上,然后用户尝试手动打开 powerpoint,此时 powerpoint 的主 UI 加载到不可见的备用桌面上)。这可能是您需要仔细测试的事情。通过创建备用 Window Station 可以避免此问题 同样,但由于窗口站是进程全局的,因此在这种情况下,您需要生成一个辅助子进程来处理与 powerpoint 的交互。

您还可以尝试使用 Windows 消息挂钩 确定窗口何时创建并保持其不可见。这也有一些注意事项:

  • 您必须找到一些可靠的方法来识别感兴趣的窗口(窗口类名称?)
  • 如果 powerpoint 是进程外服务器,则会有一个窗口,您的钩子在其中活动并可能隐藏错误的进度对话框(即属于另一进程的对话框)。为了最大限度地减少这种机会,请测试 powerpoint 是否处于进程中(在这种情况下,将挂钩编程为仅影响您自己的进程),如果不是,请安排挂钩仅在抑制所需的最短时间内处于活动状态进度窗口。
  • 未来的 powerpoint 版本可能会破坏您用来识别感兴趣窗口的任何方法。对此你无能为力。

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.
沉默的熊 2024-10-25 17:36:10

您可以尝试将 Application.Visible 属性保留为默认值,并在打开演示文稿时将 MsoTriState.msoFalse 传递给 WithWindow 参数:

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

如果您将 Application.Visible 属性显式设置为 MsoTriState.msoFalse 您将收到“不允许隐藏应用程序窗口”错误。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文