以具有管理权限的当前用户身份从Windows服务运行进程

时间:2018-02-06 04:40:49

标签: vb.net windows-services

我在.net中很新。我正在尝试构建一个Windows服务来监视Windows窗体应用程序,以便它启动并保持从启动运行。

该应用程序还将来回监视Windows服务,以检查它是否未停止,如果停止,它将尝试启动该服务。我正在关注此stack post(用c#编写,我将其转换为vb.net。Pastebin)以从Windows服务运行应用程序作为当前用户,并且它按预期成功运行。

但问题是,当应用程序监视服务并发现服务停止时,此进程在没有管理权限的情况下启动,而服务启动触发器无效。

当我以Run As Administrator手动运行应用程序时,如果找到停止的服务,它会成功触发该服务。请建议如何以Windows服务的管理权限作为当前用户运行该进程。

这是我的服务类

Public Class myService
Dim ApplicationLauncher As New ApplicationLauncher
Private aTimer As System.Timers.Timer
Dim exePath As String = "path_to_exe"

Protected Overrides Sub OnStart(ByVal args() As String)
    SetTimer()
    If Not String.IsNullOrEmpty(GetPCUser()) Then
        If Not IsProcessRunning("App_exePath") Then
            ApplicationLauncher.CreateProcessInConsoleSession(exePath, True)
        End If
    End If
End Sub

Protected Overrides Sub OnStop()        
End Sub

Private Sub SetTimer()
    aTimer = New System.Timers.Timer(1000)
    AddHandler aTimer.Elapsed, AddressOf OnTimedEvent
    aTimer.AutoReset = True
    aTimer.Enabled = True
End Sub

Private Sub OnTimedEvent(source As Object, e As ElapsedEventArgs)
    If Not String.IsNullOrEmpty(GetPCUser()) Then
        If Not IsProcessRunning("App_exePath") Then
            ApplicationLauncher.CreateProcessInConsoleSession(exePath, True)
        End If
    End If
End Sub

Private Function GetPCUser()
    Dim strCurrentUser As String = ""
    Dim moReturn As ManagementObjectCollection
    Dim moSearch As ManagementObjectSearcher
    Dim mo As ManagementObject
    moSearch = New ManagementObjectSearcher("Select * from Win32_Process")
    moReturn = moSearch.Get
    For Each mo In moReturn
        Dim arOwner(2) As String
        mo.InvokeMethod("GetOwner", arOwner)
        Dim strOut As String
        strOut = String.Format("{0} Owner {1} Domain {2}", mo("Name"), arOwner(0), arOwner(1))
        If (mo("Name") = "explorer.exe") Then
            strCurrentUser = String.Format("{0}", arOwner(0))
        End If
    Next
    Return strCurrentUser
End Function

Public Function IsProcessRunning(name As String) As Boolean
    Dim Result As Boolean = False
    Dim GetProcess As Process() = Process.GetProcesses()
    For Each pr In GetProcess
        If pr.ProcessName = name Then
            Result = True
        End If
    Next
    Return Result
End Function
End Class 

这是我的Windows窗体应用程序类

Public Class Form    
Dim sc As New ServiceController("myService")
Private Timer2 As System.Timers.Timer

Private Sub Form_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    SetTimer2()        
    Visible = False
    ShowInTaskbar = False
    'Some other code
End Sub

Public Sub Form_Startup() Handles Me.Load
    'Some other code
End Sub

Private Sub SetTimer2()
    Timer2 = New System.Timers.Timer(1000)
    AddHandler Timer2.Elapsed, AddressOf OnTimedEvent2
    Timer2.AutoReset = True
    Timer2.Enabled = True
End Sub

Private Sub OnTimedEvent2(source As Object, e As ElapsedEventArgs)
    sc.Refresh()
    If sc.Status.Equals(ServiceControllerStatus.Stopped) Or sc.Status.Equals(ServiceControllerStatus.StopPending) Then
        sc.Start()
    End If
End Sub
End Class

1 个答案:

答案 0 :(得分:1)

您需要修改服务启动程序的manifest文件(Windows窗体应用程序)

自定义嵌入程序的清单。

  1. 项目+添加新项目
  2. 选择“应用程序清单文件”。
  3. <requestedExecutionLevel>元素更改为
  4. <强> E.g

     <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
    

    这将使应用程序在启动程序时显示UAC提示符。

    <强>更新

    根据您的意见

      

    如果没有UAC违反此行为,则无法授予提升权限   用户访问控制的基本原则。

         

    在避免提示时无法提升权限   设计。如果有办法做到这一点,UAC将变得毫无用处。

    您需要阅读此问题

    Start / Stop a Windows Service from a non-Administrator user account

    您需要设置服务权限才能执行此操作