2011-04-02 91 views
1

我设计了定期检查特定的应用程序是否安装,当它发现它没有安装,下载它从共享网络位置的Windows服务安装包的问题,​​该文件是一个无声无息地安装exe(自行安装)。C#Windows服务运行

我有运行安装程序问题,所以我决定,而不是试图运行安装程序,运行一个小的hello world Windows窗体应用程序,只是为了看看这个简单的事情的作品。

几个困惑小时后我终于发现的hello world应用程序不会在实际上运行,但不同的用户下 - 特别是本地机器。在接下来的几个小时里,我发现我必须关闭UAC(Vista/7)并允许该服务与桌面交互。在此之后,我终于在桌面上得到了一个提示,表明服务正在尝试运行某些内容,而且我必须决定是否允许它。

当我按下允许 - 我带到另一个GUI(从我的桌面不同)和世界你好此后正常运行。

现在,尽管这当然是一个进步,但我仍然远离在当前用户帐户下安装应用程序。

我遇到的一个问题是将windows服务设置为以特定用户身份运行,当我在该类型的WS上使用installutil.exe时,它提示我输入用户名和密码,输入正确的(管理员特权)数据并且无法安装。

我想要实现的是让Windows服务以任何方式安装无提示安装程序包而不中断用户,测试无提示安装程序包是net framework 2.0 - 我需要安装它,就好像用户单击它一样本人。

我不要求任何代码(但是这会受到欢迎),只是点我朝着正确的方向,在此先感谢!

+0

我不确定问题是什么,但Windows服务,屏幕保护程序和其他系统进程运行在不同的UI环境或不同的桌面。据我所知,可以使GUI在登录用户的上下文中运行(如果有的话)。 – kenny 2011-04-02 11:11:48

回答

1

我不知道它是如何在C#中完成的,但我会解释这个概念。

当您在Windows服务是你的应用程序运行系统用户,由于已经进行的任何登录甚至在应用程序运行。

此外,从win7本地服务帐户不能显示GUI,因为主要的安全问题,如导致应用程序运行cmd.exe任何类型的资源管理器,允许用户执行他/她不应该做的事情(我认为你可以绕过这一点,不确定,但不建议反正,所以不要)。

所以,你有2种选择:

  1. 创建将用户的会话中运行其他应用程序,你可以使用RPC(如.Net远程)与它通信。您可以将应用程序放置在用户的启动中。我认为更好的方法是使用CreateProcessAsUser()(我不知道它是如何在C#中调用的)。每个用户都有一个令牌,因为你是一个服务,你有权获得用户的主令牌,这将允许你在用户帐户下创建进程。 CreateProcessAsUser()创建一个进程,它也获得一个令牌来以该用户身份运行进程。

关于令牌的一些更多的事情,对于CreateProcessAsUser你需要获得用户的令牌。使用WTSQuestUserToken从Windows服务(仅限Windows服务)执行此操作的最简单方法是使用WTSQuestUserToken。您为该函数提供用户会话的sessionID,并返回主令牌。

这种方法并不完美,但它很容易适用于大多数情况。如果在同一个会话ID(sessionID ==终端服务器会话ID)下有两个用户,则可以使用从资源管理器运行时完成。但我想我得到的答案足够复杂,所以如果你的WTSQueryUserToken()对你来说不够好,让我知道,我会更彻底地解释(显然它会更复杂)。

祝你好运!

+0

管理层认为这将是最好的解决方案 - 我从一开始就反对。与此同时,我确实设法向管理层强调,由于时间是第一问题,我们必须重构整个逻辑。 – BrunoBozic 2011-04-04 07:45:59

+0

因此,我将一个小应用程序作为无人照管的静默Inno安装程序包进行部署,此帮助程序应用程序向计划任务添加一个计划事件(在用户登录时) - 启动我需要的应用程序。 – BrunoBozic 2011-04-04 07:47:13

+0

另一个额外的好处是 - 能够通过多台机器上的VBScript推送这样的软件包(Inno Setup)。所以基本上我们通过使用不同的方法来达到同样的目的。当然,管理层希望我继续用windows服务来调查这个问题,因为这些问题仍然是他们感兴趣的问题,因为某些原因,他们认为它们是100%可靠的东西(相对于任务调度程序的例子) – BrunoBozic 2011-04-04 07:49:12

1

为什么你所看到的行为,你的描述我的答案herehere你会发现足够详细的解释,如果你很好奇。

但无论如何,解决方案是找到一种替代方法。 Windows服务无法显示用户界面,并且无法在特定用户的上下文中运行。他们根本不是你想要做的事情的可行选择。禁用UAC也是而不是是一个可接受的选项。

很难想象为什么您需要首先从Windows服务中执行此操作。用户登录时运行的后台进程似乎是更好的方法。它根本不需要任何界面,但它仍然可以弹出一个窗口,或者在用户选择时与用户进行交互。

+0

我同意。特别是禁用UAC部分。 – BrunoBozic 2011-04-04 07:54:01

+0

有人认为,Windows服务是最好的地方放置一个应用程序,检查一个exe文件的网络驱动器,如果该exe文件符合某些reqs,下载并安装它。我们这里没有AD,因此管理层希望我们设计一种通过网络部署应用的方式。他们设计了Windows服务定期检查文件网络位置的规范,如果需要的话将其下载并安装(另一个考虑是运行带有进度条的GUI)。 – BrunoBozic 2011-04-04 07:56:54

+0

@布鲁诺:不幸的是,那个认为是错误的人*。这不会起作用。当你让那些对编程一无所知的人开发你的规范时,会发生这种情况。与真实世界完全脱节的规格对任何人都没有任何好处,即使是写这些的人也是如此。在Windows服务上有一个GUI(有或没有进度条)是简单的**不可能**。这不是他们设计的。阅读你的其他评论,我更加确信后台流程就是答案。改为实施;如果有必要,写下你自己的规范 – 2011-04-04 09:23:08