【问题标题】:Run Windows forms app from Windows service从 Windows 服务运行 Windows 窗体应用程序
【发布时间】:2012-12-12 10:24:02
【问题描述】:

我们有一个需要从服务运行的第三方遗留软件,我们希望使用窗口消息来自动化它,以单击按钮、抑制消息框等。

问题是我似乎无法在表单处于活动状态时启动进程,我可以使用 Process.GetProcessesByName("ProcessName"); 检索进程,但 MainWindowHandleMainWindowTitle 为空。

有没有办法从服务启动 Windows 客户端程序以便正确创建表单?

【问题讨论】:

  • Windows 服务在没有桌面的用户上下文中运行。这就是为什么您不能从服务中使用窗口的原因。请尝试将服务使用的用户更改为您希望打开窗口的用户。
  • 我不想向真实用户展示表单,我想以编程方式与表单交互,换句话说,我想让旧的遗留软件作为服务工作,以便我们的后端可以交谈使用 MQ 或 WCF 等现代技术
  • 好吧,我认为这行不通 - 正如我所说的,Windows 服务默认情况下不托管桌面,因此您无法创建 Windows。 ://
  • 好的,但是像 AutoMate 这样的商业工具是如何做到的呢?他们可以在没有用户登录的情况下调用表单并与之交互。networkautomation.com
  • 我想知道是否可以从服务中登录用户?这样我就可以登录用户并从该帐户运行程序。

标签: c# winapi windows-services


【解决方案1】:

服务在与用户桌面不同的会话中运行,即臭名昭著的会话 0。由于长期存在破碎攻击的问题,它自 Vista 以来被隔离,谷歌“会话 0 隔离”以了解更多信息。

会话 0 仍然有桌面,只是无法切换到它。获取 null MainWindowHandle 的最典型诊断方法是等待时间不够长以允许进程创建它。您至少需要 Process.WaitForInputIdle()。

这并不能完全保证解决方案,您仍然有一个非常严重的问题,即检测到程序行为不端。或者就此而言, MainWindowHandle 实际上是启动屏幕的句柄而不是主窗口,因此由于启动屏幕被关闭,因此为 null。或者程序因为使用不同的用户帐户或不常见的工作目录而无法正常工作而崩溃。等等,在您尝试将其作为服务运行之前,您需要先使用控制台模式程序来解决这些问题。

此时最好将其保留为控制台模式应用程序。因为故障是完全无法诊断的,所以当 IT 人员打电话给您时,您的后端会一直感到痛苦,因为它停止工作并且您也没有什么可看的。

【讨论】:

  • 这是一个旧的业务分析软件,我无法访问源代码,所以我害怕使用 Winforms 应用程序:/
  • 顺便说一句,我无法获得任何进程来获取主窗口或任何窗口。你确定它为会话 0 中的表单创建句柄吗?
  • 我特别警告过无法检测到应用程序的彻底故障。一旦您将其投入生产,您将不得不处理的预览。您确实必须首先使其与控制台应用程序一起使用。
  • 您的意思是控制台应用程序而不是服务,或者从服务而不是表单应用程序运行控制台应用程序?我制作了一个 SPIKE/POC,并成功地使用来自控制台应用程序的消息控制了 Forms 应用程序。那是工作,现在我只需要在未登录时让它工作
  • 我实际上让它工作,不得不使用 Win32 FindWindow 而不是 C# 内置版本。如果我在交互模式下运行服务,我可以登录并查看寡妇的行动,如果事情没有按预期进行,那就太好了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多