1

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

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

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

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

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

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

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

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

笔记:

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

2 回答 2

0

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

于 2011-07-18T16:04:41.750 回答
0

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

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

同样,我不确定这些中的任何一个是否会起作用。您试图绕过的障碍是设计使然。

哦,我对你有感觉,不得不处理 Office 自动化......花了太多时间试图解决 Word 自动化的奇怪问题。

于 2011-07-18T11:00:07.790 回答