以编程方式授予本地用户权限以使用.Net

时间:2018-02-12 11:49:06

标签: c# .net vb.net wcf

我想在我的应用程序中实现更新服务(因此一旦安装了服务,用户就不需要管理员权限来更新我的应用程序,就像Google或Mozilla更新它们一样),我想我找到了一个好方法用WCF做到这一点。

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

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

我需要使用更高权限运行服务才能执行更新安装,因此我希望授予本地用户启动服务的权限在首次安装服务期间服务首次启动时(因为我也可以在安装期间触发)。

但是,如何使用VB.NET(或C#)实现这一目标?我找到了使用advapi32.dll的API调用的一些示例,但看起来不能通过此更改权限。

所以,长话短说,这是我正在寻找的总结:

  • 授予Group“本地用户”权限以启动我的服务,这是安装过程中的最佳方法(可能是在Visual Studio Installer项目中使用自定义操作?或者在Windows服务项目中的ServiceInstaller-Class中?)或第一次服务启动(Windows服务项目中的OnStart-Event)
  • 该服务不得以本地用户权限运行,因为它会错过安装更新​​所需的提升权限。
  • 我无法通过GPO /本地政策分配权限,因为用户不在我们公司内部,而是遍布全球。出于同样的原因,我不能假设每次更新时他们都可以让管理员提升它们。
  • 我想尽可能避免命令行调用(如通过命令行分配权限,因为那些很可能是依赖于os的)
  • 另一个解决方案是将服务配置为自动并在安装后启动它,但我不喜欢我的服务一直运行的想法,因为它只在主应用程序启动时才需要。
  • 很可能不是文件权限问题。每个人,系统和服务都可以完全访问服务文件夹和文件。

这里已经有不同的类似问题了,但没有一个能给出这个问题的明确答案。一个用户可能使用WiX-Installer来完成它,但我想保留Visual Studio Installer项目,因为它非常直接且易于使用。

1 个答案:

答案 0 :(得分:0)

经过一段谷歌搜索并试图找到一个“干净”的解决方案,我已经放弃并立即使用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