【问题标题】:Programmatically grant local user rights to start a service with .Net以编程方式授予本地用户权限以使用 .Net 启动服务
【发布时间】:2018-07-22 14:01:25
【问题描述】:

我想在我的应用程序中实现更新服务(这样用户在安装服务后就不需要管理员权限来更新我的应用程序,就像 Google 或 Mozilla 进行更新一样),我想我找到了一个好方法使用 WCF 执行此操作。

我有一个 WCFServiceLibrary-Project,其中包含 ServiceContract 和核心功能(下载/安装更新)和一个将 WCFServiceLibrary 实现为 Windows 的 Windows Service-Project服务。 此外,还有一个 Visual Studio 安装程序-项目,用于安装服务和我的应用程序,它应该能够使用 NamedPipes 启动/停止/与服务通信。

服务配置为使用 LocalSystem-Account 手动启动。 现在安装服务后,我可以使用 services.msc (可能已提升)启动/停止它,但当我使用 net start Servicename (错误 5:访问被拒绝)或我的应用程序尝试它时不能,这告诉我本地用户可能没有启动/停止服务的权限。

我需要以更高权限运行该服务才能执行更新安装,因此我想授予本地用户权限以启动我的服务,在第一次安装服务时服务第一次启动时(因为我也可以在安装过程中触发)。

但是,我将如何使用 VB.NET(或 C#)来实现这一点?我找到了一些使用 advapi32.dll 的 API-Calls 的示例,但看起来权限不能用这个来更改。

所以,长话短说,以下是我正在寻找的内容的摘要:

  • 授予组“本地用户”权限以启动我的服务,最好的方法是在安装期间(可能在 Visual Studio 安装程序项目中使用自定义操作?或者在 Windows 服务项目中的 ServiceInstaller-Class 中?)或第一次服务启动(Windows 服务项目中的 OnStart-Event)
  • 该服务不得以本地用户权限运行,因为它会错过安装更新​​所必需的提升权限。
  • 我无法通过 GPO/本地策略分配权限,因为用户不在我们公司内,而是在世界各地。出于同样的原因,我不能假设他们可以让管理员在每次更新时提升他们。
  • 如果可能,我希望避免命令行调用(如通过命令行分配权限,因为这些很可能与操作系统相关)
  • 另一种解决方案是将服务配置为自动并在安装后启动它,但我不喜欢我的服务一直运行的想法,因为它仅在我的主应用程序启动时才需要。
  • 很可能不是文件权限问题。每个人、SYSTEM 和 SERVICE 都可以完全访问 services 文件夹和其中的文件。

这里已经有不同的类似问题,但没有一个给出明确的答案。一位用户可能是使用 WiX-Installer 完成的,但我想保留 Visual Studio 安装程序项目,因为它非常简单易用。

【问题讨论】:

    标签: c# .net vb.net wcf


    【解决方案1】:

    经过一番谷歌搜索并试图找到一个“干净”的解决方案后,我放弃了,现在使用Process.Start 来执行 sc.exe 并在安装后设置新的权限。

    这是我的 ServiceInstaller-Class,供任何好奇的人使用:

    [VB.NET]

    Imports System.ComponentModel
    Imports System.Configuration.Install
    Imports System.ServiceProcess
    
    <RunInstaller(True)>
    Public Class SvcInstaller
        Inherits Installer
    
        Dim svcprocinst As ServiceProcessInstaller
        Dim svcinst As ServiceInstaller
    
        Public Sub New()
            svcprocinst = New ServiceProcessInstaller
            svcprocinst.Account = ServiceAccount.LocalSystem
            svcinst = New ServiceInstaller
            svcinst.ServiceName = "KrahMickeySvc"
            svcinst.DisplayName = "Mickey-Service"
            svcinst.Description = "This Service is used by KRAH Mickey for application updates and maintenance"
            Installers.Add(svcprocinst)
            Installers.Add(svcinst)
    
        End Sub
    
        Private Sub SvcInstaller_AfterInstall(sender As Object, e As InstallEventArgs) Handles Me.AfterInstall
    
            'Set new permissions acc. to Security Descriptor Definition Language (SDDL)
            'Source: https://blogs.msmvps.com/erikr/2007/09/26/set-permissions-on-a-specific-service-windows/
            'Keeping the source DACL and just adding RP,WP and DT (Start/Stop/PauseContinue) to IU (Interactive User)
    
            Dim DACLString As String = "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRCRPWPDT;;;IU)(A;;CCLCSWLOCRRC;;;SU)"
            process.Start("sc.exe", $"sdset {svcinst.ServiceName} ""{DACLString}""")
    
    
        End Sub
    
    End Class
    

    【讨论】:

    • 在检查了有关此问题的几个主题后,这是唯一一个运行良好的主题!谢谢大佬!
    猜你喜欢
    • 2018-01-18
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2018-11-08
    相关资源
    最近更新 更多