我在工作的服务器有一些计划任务,每天晚上运行。 它们在没有用户login系统时运行。 他们运行batch file打开MS-Access数据库里面的macros。 偶尔这些脚本没有closures,它们的进程仍在运行,并且.ldblocking文件挂起。
我看过他们之前运行,我已经看到一个MS-Access窗口popup,如果它成功完成,然后窗口closures,没有问题。 但是,如果失败,则locking文件和进程将保留。 我假设也许还有一个窗口…我知道在Linux中如果你的程序在XWindows会话中有一个窗口,你可以将它转移到另一个XWindows会话; 在Windows上可能是一样的吗?
改变我的答案,因为你把标签从Server 2008更改为2003年…我的第一个答案是不准确的。
无论configuration哪个帐户来运行计划任务,每次运行任务时都会为该帐户创build一个login会话,为该login创build一个窗口站点,并在该窗口站点/login会话中创build窗口。 当任务完成后,用户帐户被注销…除了系统帐户当然。 他们永远不会注销。
此外,Server 2003没有2008+的会话0隔离。 值得注意的是,2008年和2003年相比,这种方式有很大的不同。2008年,计划任务是由svchost.exe产生的taskeng.exe产生的,意味着计划任务在会话0中运行,而不pipe任务作为SYSTEM或作为普通用户运行。 但是,如果任务设置为在2003年以SYSTEM身份运行,则它与2008年的任务是由Session 0中的svchost.exe创build任务几乎相同。在Server 2003中,会话0仅仅是“控制台”会话,你可以通过/ console(/ Vista在Vista / 2008 +)上通过RDP访问它,然后你将login到会话0,但是它会为你生成一个新的窗口站点,所以你将无法看到预定的系统启动的任务窗口。
在Vista / 2008 +中,这种活动可能会触发交互式服务检测服务,当服务器popup一个交互式对话框时,这个服务就是将您转移到会话0的桌面,但是除非另一个用户同时loginISD服务提醒。
所以请记住,当它从10岁的操作系统迁移的时候。
从NTDebugging博客:
无论如何,Session 0中的所有这些窗口站点和桌面都是什么?
现在我们已经知道如何调整会话视图空间和各种桌面的大小了,值得讨论为什么你有这么多的窗口站点和桌面,特别是在会话0中。首先,你会发现每个WinSta0(交互窗口站)至less有3个桌面,每个桌面使用不同数量的桌面堆。 以前我已经提到过,但是回顾一下,每个交互式窗口站的三个桌面是:
·默认桌面 – 桌面堆大小是可configuration的,如下所述
断开桌面 – 32位系统上的桌面堆大小为64k
·Winlogon桌面 – 32位系统上的桌面堆大小为128k
请注意,WinSta0中可能还会有更多的桌面,因为任何进程都可以调用CreateDesktop并创build新的桌面。
我们来看看与非交互式窗口站点相关的桌面:这些桌面通常与服务有关。 系统创build一个窗口工作站,在该窗口工作站中启动LocalSystem帐户下运行的服务进程。 这个窗口站被命名为service-0x0-3e7 $。 它被命名为LocalSystem帐户的LUID,并包含一个名为Default的桌面。 但是,作为本地系统交互运行的服务进程在Winsta0中启动,以便它们可以与会话0中的用户进行交互(但仍然在LocalSystem上下文中运行)。
任何在显式用户或服务帐户下启动的服务进程都有一个由服务控制pipe理器为其创build的窗口工作站和桌面,除非其LUID的窗口工作站已经存在。 这些窗口站是非交互式窗口站。 窗口站名称基于每个login唯一的LUID。 如果一个实体(系统除外)多次login,则会为每个login创build一个新的窗口站。 示例窗口站名是“service-0x0-22e1 $”。
从一个旧的MS KB:
Microsoft Windows NT,Windows 2000和Windows XP服务具有与之关联的Window工作站和桌面组合。 这是基于哪个帐户服务运行在:
•如果服务在LocalSystem帐户中运行且不是交互式(即服务types不包括SERVICE_INTERACTIVE_PROCESS标志),则服务将使用以下Window工作站和桌面:Service-0x0-3e7 $ \ default其中“ Service-0x0-3e7 $“是Window站的名称,”default“是桌面的名称。
这是一个非交互式的Window站点。
•如果服务正在LocalSystem帐户中运行并与桌面交互(即服务types包括SERVICE_INTERACTIVE_PROCESS标志),则该服务将使用以下Window工作站和桌面:Winsta0 \ default这是一个交互式Window Station。
•如果服务在用户帐户的安全上下文中运行,系统将为该服务创build一个独特的非交互式Window站点和桌面。 窗口站的名称将基于用户的login安全标识符(SID):
Service-0xZ1-Z2 $ \ default其中Z1是高位部分,Z2是loginSID的低位部分。 此外,在同一安全上下文(相同的服务帐户名称)中运行的两个服务将不会收到相同的窗口站和桌面,因为login安全标识符(SID)是该login会话唯一的。
没有办法将一个进程和所有的窗口传递给另一个用户的会话或以某种方式将其注入到他们的桌面上…至less不是没有一些主要的编程…这将是一个非常有趣的程序来尝试。
最后,关于Mark Russinovich博客上这篇文章的评论非常有趣和相关:
问题是一个线程是否可以在窗口pipe理器已经分配给桌面后调用SetThreadDesktop。 我刚刚写了一些testing代码,它证实了我的回忆。 如果一个线程曾经在一个桌面上创build过一个窗口,即使这个窗口已经被销毁了,它也将永远不会被允许SetThreadDesktop()到另一个桌面,并在那里创build窗口。