当服务器运行计划任务时,Windows 会去哪里?

当服务器运行计划任务时,Windows 会去哪里?

我工作服务器上有一些计划任务,每天晚上都会运行。它们在没有用户登录系统时运行。它们运行批处理文件,打开包含宏的 MS-Access 数据库。有时这些文件不会被脚本关闭,它们的进程仍在运行,并且它们的.ldb锁定文件会挂起。

我以前看过它们的运行,我看到一个 MS-Access 窗口弹出,如果成功完成,则窗口关闭,没有问题。但是,如果失败,则锁定文件和进程仍然存在。我假设也许某个地方也有一个窗口……我知道在 Linux 中,如果您的程序在 XWindows 会话中有一个窗口,您可以将其传输到另一个 XWindows 会话;在 Windows 上也可以做同样的事情吗?

答案1

由于您将标签从 Server 2008 更改为 2003,因此我更改了我的答案...并且我的第一个答案并不准确。

无论配置哪个帐户来运行计划任务,每次运行任务时都会为该帐户创建一个登录会话,为该登录创建一个窗口站,并在该窗口站/登录会话中创建窗口。任务完成后,用户帐户将被注销……当然,系统帐户除外。它们永远不会注销。

此外,Server 2003 没有 2008+ 所具有的会话 0 隔离。值得注意的是,2008+ 中的隔离与 2003 中的隔离大不相同。在 2008 中,计划任务由 taskeng.exe 生成,而 taskeng.exe 又由 svchost.exe 生成,这意味着计划任务在会话 0 中运行,无论任务是以 SYSTEM 身份运行还是以普通用户身份运行。但是,如果将任务设置为在 2003 上以 SYSTEM 身份运行,则它的工作方式几乎与 2008 中相同,其中任务由会话 0 中的 svchost.exe 创建。在 Server 2003 中,会话 0 只是“控制台”会话,您可以通过 RDP 使用 /console(Vista/2008+ 中的 /admin)访问它,您将登录到会话 0,但它会为您生成一个新的窗口站,因此您将无法看到由系统启动的计划任务的窗口。

在 Vista/2008+ 中,这种活动可能会触发交互式服务检测服务,该服务旨在当弹出交互式对话框时将您转移到会话 0 的桌面,但除非另一个用户同时登录,否则 ISD 服务不会发出警报。

因此,当您要迁移已有 10 年历史的操作系统时,请记住这一点。

来自NTDebugging博客:

那么,会话 0 中的这些窗口站和桌面到底是什么呢?

现在我们知道如何调整会话视图空间和各种桌面的大小,值得讨论一下为什么会有这么多窗口站和桌面,特别是在会话 0 中。首先,您会发现每个 WinSta0(交互式窗口站)至少有 3 个桌面,并且每个桌面都使用不同数量的桌面堆。我之前曾提到过这一点,但回顾一下,每个交互式窗口站的三个桌面是:

· 默认桌面 - 桌面堆大小可按如下所述配置

· 断开桌面 - 32 位系统上的桌面堆大小为 64k

· Winlogon 桌面 - 在 32 位系统上,桌面堆大小为 128k

请注意,WinSta0 中也可能有更多桌面,因为任何进程都可以调用 CreateDesktop 并创建新的桌面。

让我们继续讨论与非交互式窗口站相关的桌面:这些桌面通常与服务相关。系统会创建一个窗口站,其中启动在 LocalSystem 帐户下运行的服务进程。此窗口站名为 service-0x0-3e7$。它以 LocalSystem 帐户的 LUID 命名,并包含一个名为 Default 的桌面。但是,以 LocalSystem 交互式身份运行的服务进程在 Winsta0 中启动,以便它们可以在会话 0 中与用户交互(但仍在 LocalSystem 上下文中运行)。

任何以明确用户或服务帐户启动的服务进程都会由服务控制管理器为其创建一个窗口站和桌面,除非其 LUID 的窗口站已经存在。这些窗口站是非交互式窗口站。窗口站名称基于 LUID,每次登录时该名称都是唯一的。如果实体(系统除外)多次登录,则每次登录都会创建一个新的窗口站。窗口站名称的示例为“service-0x0-22e1$”。

来自旧的 MS KB:

Microsoft Windows NT、Windows 2000 和 Windows XP 服务具有与之关联的 Window 工作站和桌面组合。这取决于服务在哪个帐户中运行:

•如果服务在 LocalSystem 帐户下运行且不是交互式的(即服务类型不包含 SERVICE_INTERACTIVE_PROCESS 标志),则服务将使用以下 Windows 站和桌面:Service-0x0-3e7$\default,其中“Service-0x0-3e7$”是 Windows 站的名称,“default”是桌面的名称。

这是一个非交互式窗口站。

•如果服务在 LocalSystem 帐户下运行并且正在与桌面交互(即服务类型包括 SERVICE_INTERACTIVE_PROCESS 标志),则服务将使用以下窗口站和桌面:Winsta0\default 这是一个交互式窗口站。

•如果服务在用户帐户的安全上下文中运行,系统将为该服务创建一个唯一的非交互式窗口站和桌面。窗口站的名称将基于用户的登录安全标识符 (SID):

Service-0xZ1-Z2$\default,其中 Z1 是登录 SID 的高位部分,Z2 是低位部分。此外,在相同安全上下文(相同服务帐户名)中运行的两个服务将不会接收相同的 Window 站和桌面,因为登录安全标识符 (SID) 对于该登录会话是唯一的。

没有办法将一个进程及其所有窗口传递到另一个用户的会话中,或者以某种方式将其注入到他们的桌面中……至少在没有一些主要编程的情况下……那将是一个非常有趣的程序,值得尝试。

最后,这篇文章的评论Mark Russinovich 的博客非常有趣且相关:

问题是,当线程已被窗口管理器分配到桌面后,是否可以调用 SetThreadDesktop。我刚刚写了一些测试代码,证实了我的记忆。如果线程曾经在一个桌面上创建过窗口,即使该窗口后来被销毁,也永远不会允许它调用 SetThreadDesktop() 到另一个桌面并在那里创建窗口。

相关内容