【问题标题】:3rd Party Application Fails when run from Service从服务运行时第 3 方应用程序失败
【发布时间】:2016-01-25 02:06:24
【问题描述】:

我正在尝试构建一个自动运行第 3 方应用程序的 Windows 服务,我们称之为 BlackBox.exe。 BlackBox.exe 从当前用户的会话运行时运行良好,但从服务执行时失败。 BlackBox.exe 有一个 UI,但它可以通过传递命令行参数来自动化。在自动化模式下,它会显示一些 UI,读取输入文件,写入输出文件,然后在没有任何用户交互的情况下退出。我们只有 BlackBox.exe 的二进制文件。

该服务配置为使用与安装并注册 BlackBox.exe 相同的用户。

我比较了 Process Monitor 交互式会话与服务会话捕获的事件。没有注册表或文件操作在服务会话中失败并在服务会话中成功。值得注意的是,在这两种情况下都可以成功读取许可证激活的注册表项。

当从服务运行时,BlackBox.exe 在任务管理器中可见,CPU 为 0%,并且会一直保持在那里直到被杀死。

我猜想无法访问桌面导致 BlackBox.exe 失败 - 也许有一种方法可以让 BlackBox.exe 认为它可以在没有用户登录的情况下访问桌面?

如何从服务运行 BlackBox.exe?

更新: 如果我:

  • 启动“交互式服务检测”服务,
  • 在交互式服务检测对话框中单击“查看消息”,
  • 观看 BlackBox.exe gui 执行其处理,直到我看到交互式服务检测消息“应用程序不再需要您的关注”
  • 点击“立即返回”

...它工作正常。所以可能和Session 0 isolation有关

【问题讨论】:

  • 为什么是服务,而不是计划任务(参见Task Scheduler)?
  • 您使用的是什么版本的 Windows?
  • 所以要明确一点——如果交互式服务检测服务停止,它就不起作用?如果 ISD 服务正在运行但您没有点击“查看消息”怎么办?
  • 您是否在服务属性中勾选了“允许服务与桌面交互”?
  • 也许这可能有用 (stackoverflow.com/questions/3128017/…) 这 (blogs.msdn.com/b/winsdk/archive/2009/07/14/…) 也可以提供帮助。

标签: windows windows-services


【解决方案1】:

你能基本上运行一个弹出窗口阻止程序吗?这里的假设是 CloseMainWindow() 将具有与“查看消息”相同的效果,并且您允许服务与桌面交互。下面的示例代码;适应您的特定场景并作为独立于您的服务的线程运行。

public class Program
{
    public static void Main(string[] args)
    {
        while (true)
        {
            DestroyAllBobs();
            Thread.Sleep(100);
        }
    }

    private static void DestroyAllBobs()
    {
        Process[] bobs = Process.GetProcessesByName("robert");
        foreach (Process bob in bobs)
        {
            if ("Microsoft Visual C++ Runtime Library".Equals(bob.MainWindowTitle))
            {
                bob.WaitForInputIdle();
                if ("Microsoft Visual C++ Runtime Library".Equals(bob.MainWindowTitle)
                    && "robert".Equals(bob.ProcessName))
                {
                    try
                    {
                        bob.CloseMainWindow();
                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }
    }
}

【讨论】:

  • 值得一试。你的假设是基于什么?
  • 这是我过去在第 3 方 COM 自动化 exe 中使用的一种技术,它违反了“在无窗口模式下不弹出窗口”的合同。我们从桌面应用程序而不是服务内部运行这样的代码(以更紧凑的方式)。我一直假设您在这里有类似的东西,而且它不像使用 .NET 的 ProcessStartInfo.CreateNoWindow 标志那么简单。但是,当我重新阅读您的问题时,我想知道 CreateNoWindow 是否实际上是缺少的全部?
  • 用 ProcessStartInfo.CreateNoWindow=true 试过,没有任何变化。
  • 在等待 30 秒后尝试 CloseMainWindow 并且没有影响。 MainWindowTitle=="" 即“如果关联进程没有主窗口”的情况
  • 嗯。 Process 的 Component.Events 枚举中可能有一些你可以挂钩的东西,但我现在只是猜测。不幸的是,与这样的第三方二进制文件集成可能有点艺术。
【解决方案2】:

最好的猜测答案是 BlackBox.exe 无法在不访问桌面的情况下运行,并且 Session 0 Isolation 会阻止服务启动的 BlackBox.exe 访问桌面。所以它不能从服务中运行。

为了完整起见,如果能够使用诊断工具来识别使用 Process Monitor 或类似工具对 Windows API 的哪些调用失败,那就太好了。但是,我不确定要在那里寻找什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 2020-11-06
    • 1970-01-01
    • 2021-09-11
    相关资源
    最近更新 更多