我设计了一个Windows服务,定期检查是否安装了特定的应用程序,当它发现它没有安装时,它从共享网络位置下载,该文件是一个无声的无人值守安装exe(自安装)
我在运行安装程序时遇到问题所以我决定不再尝试运行安装程序,而是运行一个小的hello world windows forms应用程序,只是为了看看这个简单的事情是否有效。
经过几个小时的困惑后,我终于发现hello world app确实在不同的用户下运行 - 特别是本地机器。在接下来的几个小时里,我发现我必须关闭UAC(Vista / 7)并允许该服务与桌面交互。在此之后,我终于在我的桌面上得到一个提示,即服务正在尝试运行某些内容,而我必须决定是否允许它。
当我按下允许时 - 我被带到另一个GUI(与我的桌面不同),之后hello world正常运行。
现在,虽然这肯定是一个进步,但我仍然远离在当前用户帐户下安装应用程序。
我遇到的一个问题是将Windows服务设置为以特定用户身份运行,当我在那种WS上使用installutil.exe时它会提示我输入用户名和密码,我输入了正确的(admin privilige)数据它无法安装。
我想要实现的是让Windows服务安装一个静默安装包而不以任何方式打断用户,测试静默安装包是net framework 2.0 - 我需要安装,好像用户自己点击它一样
我不需要任何代码(但这是受欢迎的),请指出我正确的方向,提前谢谢!
答案 0 :(得分:1)
我不知道它是如何在C#中完成的,但我会解释这个概念。
当您在Windows服务中时,您的应用程序运行SYSTEM用户,因为应用程序甚至在执行任何登录之前都会运行。
此外,从win7本地服务帐户无法显示GUI,因为主要的安全问题,如导致应用程序运行cmd.exe任何类型的浏览器,允许用户执行他/她不想做的事情(我认为你可以绕过它,不确定,但不建议不管怎样,所以不要这样做。
所以你有两个选择:
创建另一个将在用户会话下运行的应用程序,您可以使用RPC(如.Net远程处理)与它进行通信。您可以将应用程序放在用户的启动中。
在我看来,更好的方法是使用CreateProcessAsUser()(我不知道它是如何在C#中调用的)。每个用户都有一个令牌,因为您是一个服务,您有权获得用户的主令牌,允许您在用户的帐户下创建进程。 CreateProcessAsUser()创建一个进程,它还获得一个令牌来以此用户身份运行该进程。
关于令牌的更多内容,对于CreateProcessAsUser,您需要获取用户的令牌。从Windows服务(仅限Windows服务)执行此操作的最简单方法是使用WTSQuestUserToken。您为该函数提供了用户会话的sessionID,并且您将获得一个主令牌。
这种方法并不完美,但它很容易适用于大多数情况。如果在同一个sessionID(sessionID ==终端服务器会话ID)下有2个用户,则可以使用它,这可以使用资源管理器中的“运行方式”完成。但是我觉得我的答案太复杂了,所以如果你对WTSQueryUserToken()不够好,请告诉我,我会更彻底地解释(显然会更复杂)。
祝你好运!
答案 1 :(得分:1)