0

这是我想要做的是创建一个检查 Microsoft Lync 是否正在运行的服务。如果它正在运行,那么除了写入事件日志之外什么都不做。如果它没有运行,请运行 exe,然后登录到 Lync。我遇到的问题是,当需要运行 exe 时,它​​会启动该进程,但它从未真正运行过该应用程序。我试图查看是否可以使用记事本,但它所做的只是在任务管理器中创建进程,但从未打开实际的应用程序。

  Imports System
  Imports System.Data
  Imports System.Timers
  Imports System.Diagnostics
  Imports System.Data.SqlClient
  Imports System.ServiceProcess
  Imports System.Windows.Forms

    Public Class Service1

    Protected Overrides Sub OnStart(ByVal args() As String)
        EventLog.WriteEntry("In Onstart", "starting timer")
           Timer1.Start()
    End Sub



   Protected Overrides Sub OnStop()
   End Sub

   Private Sub Timer1_Elapsed(ByVal sender As System.Object, 
   ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed

       If IsProcessRunning("communicator") Then
       EventLog.WriteEntry("no problem")
       Else
       EventLog.WriteEntry("not running")
       Dim info As New ProcessStartInfo("C:\Program Files (x86)\Microsoft Lync\communicator.exe")
       info.UseShellExecute = False
       info.RedirectStandardError = True
       info.RedirectStandardInput = True
       info.RedirectStandardOutput = True
       info.CreateNoWindow = True
       info.ErrorDialog = False
       info.WindowStyle = ProcessWindowStyle.Hidden

     Dim process__1 As Process = Process.Start(info)

     End If

   End Sub

   Public Function IsProcessRunning(ByVal name As String) As Boolean
      For Each clsProcess As Process In Process.GetProcesses()
        If clsProcess.ProcessName.StartsWith(name) Then
         Return True
      End If
      Next
         Return False
   End Function
End Class
4

2 回答 2

1

问题来自这样一个事实,即在 Windows 中(特别是从 6.x 版本开始)服务在完全隔离的会话和桌面中运行,没有任何用户交互的机会,这是设计使然,出于安全原因不鼓励这样做。您正在启动的程序实际上确实启动了,但它是在用户无法看到的隐藏桌面(记事本相同)中启动的。

快速而肮脏的解决方法是在控制面板中将服务标记为交互式,并启动交互式服务检测服务。这样做时,当您的服务运行程序时,任务栏中会闪烁一个窗口,告诉您有来自服务的消息,以便您可以切换到该并行桌面并实际看到它。这对用户来说非常不方便,并且被广泛认为是一种不良做法

真正的解决方案是使程序成为常规应用程序而不是服务,并通过 Windows 中的某个自动启动位置为每个用户运行它。它不需要有可见的 UI,但可以在与您相同的上下文中运行。或者离开服务,也为了运行第二个程序而将一些应用程序放在与服务通信的用户空间中。在任何情况下,一般规则是永远不要有来自服务进程的任何类型的用户交互。

这是一篇解释问题和一些解决方法的文章http://blogs.technet.com/b/askperf/archive/2007/04/27/application-compatibility-session-0-isolation.aspx

于 2013-07-20T00:02:50.940 回答
0

我能够创建一个程序来检测 Lync 是否正在运行以及是否重新启动程序。

Imports System.Diagnostics
Imports Microsoft.Lync
Imports Microsoft.Lync.Model
Imports Microsoft.Lync.Model.Conversation
Imports Microsoft.Lync.Model.Group

Public Class frmCheckLync
Private _lyncClient As LyncClient
Private _contactManager As ContactManager
Private _conversationManager As ConversationManager
Private _self As Self
Private _groups As Dictionary(Of String, Group)
Private _contactSubscriptions As Dictionary(Of String, ContactSubscription)
Public Event StateChanged As EventHandler(Of ClientStateChangedEventArgs)
Public _signIn As IAsyncResult
Public asyncState As Object() = {_lyncClient}
Public clsProcess As Process


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Try

        Timer1.Enabled = True

        AddHandler Timer1.Elapsed, AddressOf Timer1_Tick

        Timer1.Interval = 600

        Timer1.Start()

    Catch ex As Exception

        Diagnostics.EventLog.WriteEntry("This is a test" + ex.Message.ToString, "This is a test")

    End Try
End Sub

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs)

    Try

        Timer1.Stop()

        GetClient()


        Try
            CheckClient()
        Catch ex As Exception

        End Try



    Catch ex As Exception




    Finally

        Timer1.Start()

    End Try

End Sub

Public Function IsProcessRunning(ByVal name As String) As Boolean
    For Each Me.clsProcess In Process.GetProcesses()

        If Me.clsProcess.ProcessName.StartsWith(name) Then
            Return True
        End If
    Next
    Return False
End Function

Public Sub GetClient()
    If IsProcessRunning("communicator") = False Then

        Try
            Dim info As New ProcessStartInfo("C:\Program Files\Microsoft Lync\communicator.exe")
            info.UseShellExecute = False
            info.RedirectStandardError = True
            info.RedirectStandardInput = True
            info.RedirectStandardOutput = True
            info.CreateNoWindow = True
            info.ErrorDialog = False
            info.WindowStyle = ProcessWindowStyle.Normal

            Dim process__1 As Process = Process.Start(info)
        Catch ex1 As Exception

        End Try
        Try
            Dim info1 As New ProcessStartInfo("C:\Program Files (x86)\Microsoft Lync\communicator.exe")
            info1.UseShellExecute = False
            info1.RedirectStandardError = True
            info1.RedirectStandardInput = True
            info1.RedirectStandardOutput = True
            info1.CreateNoWindow = True
            info1.ErrorDialog = False
            info1.WindowStyle = ProcessWindowStyle.Normal

            Dim process__2 As Process = Process.Start(info1)
        Catch ex2 As Exception

        End Try
    End If
End Sub
Public Sub CheckClient()
    Try
        _lyncClient = LyncClient.GetClient()
    Catch
        GetClient()
    End Try


    If _lyncClient.State = ClientState.SignedOut Then
        _signIn = _lyncClient.BeginSignIn(Nothing, Nothing, Nothing,
                                          Function(result)
                                              If result.IsCompleted Then
                                                  _lyncClient.EndSignIn(result)
                                                  ' Setup application logic

                                                  ' could not sign in 
                                              Else
                                              End If

                                          End Function, TryCast("Local user signing in", Object))

    End If

End Sub



End Class
于 2014-07-25T21:02:58.510 回答