Windows服务与UI交互

前一段在用WAMP的时候,发现一个问题:PHP中的exec函数无法运行本地的GUI程序。而用另一个suite,XAMPP,就没有问题。

网上倒是能搜到不少人有同样的问题,但是大多数都驴头不对马嘴(有的说是safe mode,这个几百年前就从PHP里删除了;有的说是function被disable了,默认的disable明明就是空的)。稍微研究了一下终于搞了清楚,下面简单记录一下。

首先先说说为什么XAMPP能:XAMPP是用你当前的账户来直接运行Apache的。而WAMP则是通过服务。相信有人大概会想:既然账户不同,自然就无法交互?毕竟大多Service的默认账户是LocalSystem。但是把Service的Log On As改成当前用户,依然不行。

其实,一个服务如果想和UI交互,他首先必须是一个Interactive Service。默认的服务是noninteractive的,无法和用户交互。如果想将一个服务改成interactive Service,首先这个服务必须是Log On于LocalSystem的[*];然后,在Service管理中勾选“Allow service to interact with desktop”:

2016-08-03

[*]注:只有LocalSystem能interactive是微软官方的说法:

If the service type specifies SERVICE_INTERACTIVE_PROCESS, the service must run in the LocalSystem account.

来自这里(另参见这里)。不过根据另外一篇文章的说法,通过修改对应服务注册表项中“Type”键的数值从10(二进制,下同)到110,可以对Log on到任意User的Service启用interactive。

这个服务以后应该就是interactive的了。但是等等,到这步还没完:从win8起,默认所有的interactive service都被禁用了,必须要去注册表将以下键值:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows

里的 NoInteractiveServices

改成“0”才行。

在这之后,你还得手动去把相关的支持服务,“Interactive Service Detection”(又名UI0Detect)给打开(如果你忘了修改注册表项,会提示“Error 1: Incorrect Function”)。

到这里,你终于可以成功地启动一个interactive service了——不过我们想要的结果,通过服务打开一个GUI程序,还是无法简单地实现的。因为从Vista起,微软引入了所谓“Session 0 隔离”的设定。所有的服务,都会被运行在Session 0上;而第一个登录用户的所有程序以及UI交互,都在session 1里(第二个是2,以此类推)。而不同session之间有无法跨越的鸿沟。正确的方式应该是,在用户的session里同时保留一个隐藏的application,然后通过诸如pipe之类的方式和你的service通讯(详情可见这里或者上面MSDN的Interactive Services的文章)。也就是说,即使你用上述方法搞好了interactive service,开启某个GUI程序之后那个程序也是在session 0里,用户根本看不到。

当然,对于已有的老旧软件的service,微软保留了一定的legacy兼容。其方法是,建立一个虚拟的“interactive desktop”——实际上在session 0中——然后把他显示给用户,就像虚拟机一样。不过会有烦人的提示,用户体验当然不会好啦:

2016-08-03 (1)

(虚拟桌面里面就不截图了,不知道为啥我一进去整个电脑就死机完全无反应…可以参见这里

什么,你问我最后问题怎么解决的?显然是换用XAMPP啦!

其他参考文献:

  1. MSDN Blog: Troubleshooting Interactive Services Detection
  2. MSDN Blog: What is Interactive Services Detection and Why is it Blinking at Me?
  3. Stack Overflow: windows service (allow service to interact with desktop)
  4. White paper: Impact of Session 0 Isolation on Services and Drivers in Windows
  5. Session Isolation from Microsoft [PPT]
  6. Code project:  Subverting Vista UAC in Both 32 and 64 bit Architectures
  7. Channel9: Session 0 Changes and Vista Compatibility for Services running as Interactive with Desktop
  8. MSDN: Application Compatibility: Session 0 Isolation
  9. StackExchange: Why can’t Windows services have a GUI?

 

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s