枚举服务上的窗口句柄(从服务创建)以确定其标题

发布于 2024-11-25 02:16:20 字数 605 浏览 1 评论 0原文

我有一项服务需要运行一个应用程序(我们称之为 X),该应用程序通常使用 Excel 自动化。

在自动化 Excel 时,应用程序 X 通常会让 Excel 显示一个对话框。对话框显示的内容和原因并不重要,不幸的是,这超出了我的控制范围。

我只是希望能够关闭 Excel 中的该对话框。

当代码不作为服务运行时,这当然很容易完成。问题是,在枚举窗口以确定对话框是否打开时,任何 win32 窗口调用都会返回 0 作为句柄。我明白为什么会这样,因为服务是独立运行的,并且预期结果为 0。

该服务也不可能在启用了交互式桌面的本地系统下运行。

我希望在 Excel 进程的线程上使用 GetThreadDesktop,然后打开该桌面来枚举这些窗口,但是从服务运行时该 api 也会返回 0。

与此相关的问题有很多,但大多数问题都是关于想要显示来自服务的对话框以供用户交互。我不想那样做。只需找到并关闭一个对话框即可。

有人发现有一个聪明的解决方法来枚举窗口并返回标题吗?

注意:

  • 应用程序 X 不在我的控制范围内。
  • 我知道非交互式环境不支持办公自动化。
  • 无论如何,我并不想与登录用户的桌面进行交互。

I have a service that needs to run an application (lets call it X) that in tern uses Excel automation.

Often application X when automating Excel will have Excel display a dialog. What and why the dialog displays isn't important, unfortunately that is out of my control.

I'd simply like to be able to close that dialog in Excel.

This of course is easily done when the code doesn't run as a service. The problem is that any win32 window call returns 0 for a handle when enumerating the windows to determine if a dialog is up. I understand why this is as the service runs in isolation and the result of 0 is expected.

It's also not possible that the service runs under local system with interactive desktop enabled.

I was hoping to use the GetThreadDesktop on a thread for the Excel process, then open that Desktop to enumerate those windows, however that api also returns 0 when running from a service.

There are plenty of questions regarding this, however most are about wanting to display a dialog from a service for user interaction. I do not want to do that. Merely find and close a dialog.

Is there a clever workaround to this that someone has discovered to enumerate windows and return the captions ?

Notes:

  • Application X is out of my control.
  • I know that office automation is not supported in a non-interactive environment.
  • I'm not trying to interact with a logged-in user's desktop in anyway.

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

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

发布评论

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

评论(2

初与友歌 2024-12-02 02:16:20

我过去曾尝试过这一点,并得出结论,实际上不可能通过服务成功实现办公自动化。

I have attempted this in the past and concluded that it was effectively impossible to achieve successful Office automation from a service.

但可醉心 2024-12-02 02:16:20

我可以想到一些解决方法 - 我没有尝试过,而且我不能确定它们是否真的有效...

  1. 从服务创建您自己的桌面。使用 CreateProcess 运行应用程序 X,并使其使用新创建的桌面。您可能会发现此讨论很有用。
  2. 创建一个小的可执行文件来处理该对话框。创建一个将运行可执行文件的任务(在任务计划程序中)。让任务存储 Excel 在运行时使用的凭据,以便它可以访问该桌面。然后,让服务通过 运行任务任务调度程序API。以这种方式运行,小可执行文件不会在系统上下文中执行,而是在定义的用户上下文中执行。
  3. 安装线程或系统范围的钩子,这将让您在Excel的流程。从那里,你就会知道该怎么做。我怀疑这在你的场景中是否有效,而且它有点黑客攻击,但你可以尝试一下。
  4. 这很丑陋,但可能有效:创建一个小的可执行文件,它将作为常规 exe 在“真实”桌面上运行。让该可执行文件与 X 交互 - 两者都在同一个桌面上,应该没有问题。困难的部分是您的服务与可执行文件交互。这可以通过非常原始的方式(例如文件或套接字)来完成。例如,既监视某个文件夹,又在文件中传递命令和信息。这显然既不稳健也不优雅,但在某些情况下可能就足够了。

再次强调,我不确定这些方法是否有效。您试图绕过的障碍是有意设计的。

哦,我对你感到同情,不得不处理 Office 自动化......花了太多天试图解决 Word 自动化的奇怪问题。

I can think of a few workarounds - none of which I've ever tried, and I can't say for sure if they actually work or not...

  1. Create a desktop of your own from the service. Run Application X using CreateProcess, and make it use that newly create desktop. You might find this discussion useful.
  2. Create a small executable that will take care of the dialog. Create a task (in task scheduler) that will run the executable. Have the task store the credentials used by Excel when it is running, so it can access that desktop. Then, have the service run the task via the task scheduler API. Run this way, the small executable will not execute in the context of the system, but in that of the defined user.
  3. Install a thread or system-wide hook, which will let you run in the Excel's process. From there, you'll know what to do. I doubt this will work in your scenario and it's marginally hacking, but you can give it a try.
  4. This is ugly, but might work: create a small executable that will run as a regular exe, on a "real" desktop. Let that executable interact with X - both being on the same desktop, it should have no problem with that. The hard part is for your service to interact with the executable. This could be done with very primitive means such as files or sockets. For instance, have both watch a certain folder, and pass commands and information in files. This is obviously not robust nor elegant, but on some cases might be sufficient.

Again, I'm not sure any of these will work. The barrier you're trying to bypass is there by design.

Oh, and I feel for you, having to deal with Office automation... Have spent too many days trying to solve weird problems automating Word.

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