我在.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
答案 0 :(得分:1)
您需要修改服务启动程序的manifest
文件(Windows窗体应用程序)
自定义嵌入程序的清单。
<requestedExecutionLevel>
元素更改为<强> E.g 强>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
这将使应用程序在启动程序时显示UAC
提示符。
<强>更新强>
根据您的意见
如果没有
UAC
违反此行为,则无法授予提升权限 用户访问控制的基本原则。在避免提示时无法提升权限 设计。如果有办法做到这一点,UAC将变得毫无用处。
您需要阅读此问题
Start / Stop a Windows Service from a non-Administrator user account
您需要设置服务权限才能执行此操作