运行安装包问题的C#Windows服务

运行安装包问题的C#Windows服务,c#,windows,windows-services,service,C#,Windows,Windows Services,Service,我设计了一个windows服务,定期检查是否安装了特定的应用程序,当它发现没有安装时,会从共享网络位置下载,该文件是静默且无人参与的安装exe(自安装) 我在运行安装程序时遇到问题,所以我决定不运行安装程序,而是运行一个小的hello world windows窗体应用程序,看看这个简单的东西是否有效 在困惑了几个小时后,我终于发现hello world应用程序实际上是在另一台用户专用的本地机器下运行的。在接下来的几个小时里,我发现我必须关闭UAC(Vista/7)并允许该服务与桌面交互。在这之

我设计了一个windows服务,定期检查是否安装了特定的应用程序,当它发现没有安装时,会从共享网络位置下载,该文件是静默且无人参与的安装exe(自安装)

我在运行安装程序时遇到问题,所以我决定不运行安装程序,而是运行一个小的hello world windows窗体应用程序,看看这个简单的东西是否有效

在困惑了几个小时后,我终于发现hello world应用程序实际上是在另一台用户专用的本地机器下运行的。在接下来的几个小时里,我发现我必须关闭UAC(Vista/7)并允许该服务与桌面交互。在这之后,我终于在我的桌面上得到一个提示,一个服务正在尝试运行一些东西,我必须决定是否允许它

当我按下allow-时,我被带到另一个GUI(与我的桌面不同),hello world随后正常运行

现在,虽然这确实是一个进步,但我离在当前用户帐户下安装应用程序还有很长的路要走

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

我想要实现的是让windows服务安装一个静默安装包,而不以任何方式中断用户,测试静默安装包是net framework 2.0-我需要安装它,就像用户自己点击它一样


我不需要任何代码(但这将是受欢迎的),只要告诉我正确的方向,提前感谢

我不知道C#是如何实现的,但我会解释这个概念

当您使用windows服务时,您的应用程序运行的是系统用户,因为该应用程序甚至在执行任何登录之前就已运行

此外,从win7本地服务帐户无法显示GUI,因为存在重大的安全问题,例如导致应用程序运行cmd.exe任何类型的浏览器,允许用户执行他/她不想执行的操作(我认为您可以绕过它,不确定,但无论如何都不建议这样做,所以不要)

因此,您有两种选择:

  • 创建另一个将在用户会话下运行的应用程序,您可以使用RPC(如.Net远程处理)与它通信。您可以将应用程序放在用户的启动中

  • 在我看来,更好的方法是使用CreateProcessAsUser()(我不知道它在C#中是如何调用的)。每个用户都有一个令牌,因为您是一个服务,所以您有权获取用户的主令牌,该令牌将允许您在用户帐户下创建进程。 CreateProcessAsUser()创建一个进程,它还获取一个令牌以作为该用户运行该进程

  • 关于令牌的更多内容,要创建ProcessAsUser,您需要获取用户的令牌。从windows服务(并且只有windows服务)执行此操作的最简单方法是使用WTSQuestUserToken。您将用户会话的sessionID赋予函数,并返回一个主令牌

    这种方法并不完美,但它很简单,适用于大多数情况。如果在同一个sessionID(sessionID==终端服务器会话ID)下有2个用户,那么它将不起作用,这可以使用runas from explorer完成。但我想我得到的答案已经够复杂了,所以如果您对WTSQueryUserToken()不够满意,请告诉我,我会更详细地解释(显然它会更复杂)


    祝你好运

    你会在我的回答中找到一个足够详细的解释,解释为什么你会看到你描述的行为,如果你好奇的话

    但无论如何,解决办法是找到另一种方法。Windows服务无法显示用户界面,也无法在特定用户的上下文中运行。对于你想做的事情来说,它们根本不是一个可行的选择。禁用UAC也是不可接受的选择


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

    我不确定问题是什么,但Windows服务、屏幕保护程序和其他系统进程在不同的UI环境或不同的桌面上运行。我记得,可以让GUI在登录用户的上下文中运行(如果有)。管理层认为这是最好的解决方案-我从一开始就反对。同时,我也设法向管理层强调,由于时间是这里的首要问题,我们只需重构整个逻辑。因此,我部署了一个小应用程序作为无人值守的静默Inno安装包,这个助手应用程序添加了一个计划事件(在用户登录时)任务调度器-这启动了我需要的应用程序。另一个额外的好处是-能够通过VBScript在许多机器上推送这样的包(Inno设置)。因此,基本上我们通过使用不同的方法实现了相同的目标。当然,管理层希望我继续调查windows服务的问题,因为这些仍然是他们感兴趣的问题,出于某种原因,他们认为windows服务是100%可靠的(例如,与任务调度程序相反)。在我们的特定情况下,我们的用户不会使用“运行方式”,因为他们不知道如何执行此操作(这对我们有好处)而且因为当前的政策禁止他们这样做(至少它应该这样做,必须问管理员)。因此-WTSQueryUserToken应该足以满足我们的需要。叹气..win32API再次…对它的复杂感觉-一方面,它像一个魅力,摇滚稳定,有良好的文档记录和