2010-08-26 104 views
1

请让我知道如何在服务中以当前登录用户的身份运行应用程序。从Windows服务启动winform应用程序

为了给你提供背景,我有一个VB.NET Windows服务,它的唯一功能是在指定的时间运行一个Winform应用程序。除此之外,它还设置了一个系统唤醒定时器,以便系统可以在指定的时间被唤醒,如果它进入待机/睡眠状态以运行应用程序。该服务必须满足我们网络上的XP/Vista/Win7桌面。此服务不会在服务器和笔记本电脑上运行。

Winform应用程序显示用户界面,用于提供一些输入。如果用户在15分钟内未提供输入,则默认值,然后进入系统托盘图标。用户可以点击图标并稍后更改值(在指定的时间范围内并且也只有两次)。

除了启动应用程序的服务之外,服务和winform应用程序之间完全没有交互。它还监视应用程序是否已被用户杀死/坠毁。如果它已被杀死/坠毁,则在前一次运行30分钟后运行一个新实例。

如果没有用户登录,那么我也希望应用程序在指定的时间运行。正如我之前所说,该应用程序有一个默认计时器。因此,如果某个用户刚从系统注销,则默认值将由winform应用程序设置。

现在来谈谈为什么我坚持使用此设计 - 我无法使用TaskScheduler,因为它已在所有机器上禁用,并且安全团队不愿意更改它。 TaskScheduler可以选择将机器从睡眠和其他事物中唤醒。所以基本上我最终创建了一个类似于任务调度程序的服务。

当前当我通过process.start()在服务中运行app.exe时,它在SYSTEM帐户下作为服务运行也在LOCAL SYSTEM下运行。所以基本上我没有得到任何用户界面。无论如何在当前登录的用户下运行它?我不担心多用户登录,因为我们不会在服务器上运行它,并且我们的桌面上未启用切换用户。即使有人通过mstsc进行了远程登录,我也需要运行应用程序并向用户显示UI。

请让我知道如何在服务中以当前登录用户的身份运行应用程序。

感谢 askids

回答

1

有报道说,我发布了一些补充意见。但不知何故,我无法看到它:(

现在回到原来的问题,我可以几个试错后,看着办吧。我会把它的细节。

在Vista及以上,服务运行从其他用户会话隔离。他们会运行1 0运行用户会话及以上。所以基本上你需要模拟登录的用户的过程电流。

  1. 使用WTSEnumerateSessions和 GET会议。检查会话 状态是否处于活动状态。将当前登录的用户会话为 。如果 没有活动会话,则表示 表示没有登录用户。在我的情况下,在 我的情况下,用户只会记录1个登录 。所以我不需要弄清楚 的活动会话(像其他人可能需要做的 )。
  2. 使用WTSQueryUserToken在活动会话中获取用户令牌。 创建使用DuplicateTokenEx
  3. 主要用户令牌使用CreateEnvironmentBlock
  4. 使用上面的CreateProcessAsUser

为什么它在XP的工作,而不是在Vista的原因的信息创建一个环境是因为它看起来像启动默认信息是不同的。在我设置了startupinfo结构的wShowWindow标志之后,GUI将开始出现。

Dim StartupInfo As New STARTUPINFO() 
StartupInfo.cb = Marshal.SizeOf(StartupInfo) 
StartupInfo.dwFlags = STARTF_USESHOWWINDOW 
StartupInfo.wShowWindow = WINDOW_STATUS.SW_SHOWNORMAL 

还有一个附加信息。我试图使用
StartupInfo.lpDesktop = "WinSta0\\Default"
设置默认桌面,因为应用程序在启动时会崩溃。所以我评论说。

我还有一个最后的问题。推出的应用程序并不重点。 GUI出现,但在后台。但我在想,它将再次与上面的一些参数有关。一旦我弄清楚了,我会补充细节。

+1

嗨,我有完全相同的问题。你能发布一个完整的示例代码吗?谢谢! – user670186 2012-05-27 16:09:15