我已经写了一个小型服务(普通Win32)和我想知道,如果它能运行多个实例,当多个用户登录。

基本上,我们说我们已经有了用户a和用户b供用户a的服务将登录为"域\用户a"和为用户b的服务将登录为"域\用户b"-这是从相同的可执行的课程。我可以改变的动态登录使用的ChangeServiceConfig()功能,但它更改了它的全系统看来,而我想每个用户拥有自己的副本服务运行,只用于他。

谢谢你提前的任何指针。

有帮助吗?

解决方案

Win32服务设计为系统范围,并在任何用户登录之前开始运行。如果您希望按用户运行某些内容,最好将其设计为常规应用程序并从中运行用户的启动组。

其他提示

是否有可能让服务创建子进程然后采用用户凭证(或者用它们启动)?这样,您仍然只能使用该服务的单个实例,但它能够完全执行每个用户的工作。 IIRC Windows任务计划程序服务执行此操作。

服务的整个概念是在任何用户登录之前启动它。所以即使这是可能的,当服务启动时你也无法在userA和userB之间做出选择,因为它们都没有登录。


可能的方向是服务以SYSTEM身份运行并且每隔几分钟检查是否有用户登录,如果有冒充该用户并执行此操作。

是的,这听起来很接近(我正在回答Greg的评论,但评论太短,不适合我的回复)。

我事先并不知道用户列表,但是有一个GUI控件应用程序可用于为每个用户输入用户名/密码对。因此,userA将登录,运行应用程序,输入他的凭据,服务将使用它。同时(在userA已注销但服务仍在使用userA的凭据运行之后)userB登录,使用该应用程序,另一个服务副本开始按用户B登录运行。因此,同时userA和userB服务正在运行。

这可能吗?

你可能是在寻找模拟用户。检查出一些引用我发现了一个快速的谷歌搜索这里:

听起来好像你实际上有两个不同的,相互冲突的要求,关于时间和身份。

  1. 以每个登录用户身份运行
  2. 即使没有用户登录也会自动运行。
  3. 无法做到这一点,而是考虑将您的程序包装在服务中;程序将在启动时为每个用户正常运行(通过启动文件夹或taskscheduler),此外创建一个服务,以系统用户(或您定义的任何其他用户)的身份运行您的应用程序。点击 由于你还需要(你在评论中提到这个)应用程序即使在他注销后仍然作为最终用户运行,你可以让服务为你管理这个过程。

    然而,这可能不是最好的主意,因为用户仍然有效登录。这可能有许多副作用,包括安全性,性能(一次登录的用户太多......)等。

您可以创建服务应用程序和非服务(普通)应用程序,并通过IPC(映射文件,管道,MailSolts ......您为其命名)进行通信。

这样你就可以解决所有麻烦。

注意:相同的应用程序可能有不同的行为 - 当作为进程启动时以及由用户启动时,但最终它是相同的,您仍然有2个应用程序(无论您是否只有一个可执行文件)。

可以使用不同的帐户运行。实际上,这很常见。请参阅svchost.exe,它实现了一堆OS服务。

我只是不知道你如何确定哪些帐户。在一家大公司中,设置了许多PC,因此所有100,000多名员工都可以使用它。您不希望以登录用户身份运行服务,也不想为所有100.000用户运行它。那么对于哪些帐户,我要问?

Windows进程一次只能使用一个用户的权限执行。这适用于服务和其他流程。利用足够的权限,可以“切换”权限。通过使用模拟在不同用户之间。您尝试做的最常见的模式是拥有一个特权服务实例,该服务注册登录/注销事件并相应地创建子进程,每个进程都模拟登录用户。该模式还将简化UI,因为每个进程都在每个单独用户的桌面上运行,就像它是常规应用程序一样。

如果您使特权服务的代码尽可能简单,则此模式具有额外的好处,即您可以最小化代码的攻击面。如果用户在“以用户身份运行”上发现安全问题,您的服务的一面是非问题,而特权服务中的安全问题可能导致权限升级。实际上,在实现Windows消息处理循环的Vista特权服务之前,很容易受到一种名为 Shatter attack ,考虑到你要做的事情你应该知道。

您希望它一直在运行,因此您需要一项服务。

您需要跟踪每个用户的内容,因此您需要一个在用户会话中运行并与服务通信的应用程序(使用命名管道或DCOM或符合您要求的任何内容)。

您不需要多个服务实例。从您对问题的描述来看,您需要的是一个可以模拟用户并代表他们执行作业的服务。

您可以通过实现服务中托管的COM对象来完成此操作。您的客户端应用程序(最终用户运行)将在您的CLSID上调用CoCreateInstanceEx。这将导致在您的服务中创建COM对象的新实例。然后,应用程序可以使用您的某个接口上的方法将收集的用户凭据传递给COM对象(尽管我对收集凭据持谨慎态度,而不是查看是否可以传递用户令牌)。然后,在服务上下文中运行的COM对象可以调用LogonUser()来登录用户并模拟它,因此它可以代表她做任何事情(比如查找用户本地appdata文件夹:-))。其他答案提供了使用凭据或令牌模仿用户的良好链接。

如果您对COM感到满意,我建议您将对象创建为多线程(生活在MTA中),以便COM不会序列化它们的执行。如果没有,默认的单线程模型就足够了。

Visual Studio ATL向导可以生成服务中的COM对象的骨架。您还可以在此处阅读有关使用ATL实现Windows服务的信息: http ://msdn.microsoft.com/en-us/library/74y2334x(VS.80)的.aspx

如果您根本不了解COM,可以使用其他通信渠道将凭据传递给您的服务。

在任何情况下,一旦您的服务获得凭据,代表用户的所有工作都必须在后台线程上执行,以便不阻止以用户身份运行的应用程序。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top