【问题标题】:Threads / Timers Troubles While Creating System Service Under VB.NET 4在 VB.NET 4 下创建系统服务时出现线程/定时器问题
【发布时间】:2012-04-05 18:56:46
【问题描述】:

我认为在 VB .NET 下创建一个简单的系统服务将是小菜一碟。男孩,我错了吗。首先,我通过 Google 发现一般帖子说您应该使用 Windows.Forms.Timer。然后,我发现相互矛盾的信息表明您必须通过代码从计时器类派生计时器才能使其工作。然后,人们使用各种可用的线程报告各种问题。由于显而易见的原因,我无法使用 VS 2010 即时调试器调试线程(尽管我不知道是否有其他方法可以做到这一点)。哇,当没有明确的指南时,这一切是多么令人困惑……

我的项目是一个应用程序启动器(类似于 cron),它将在一定的秒数内定期启动。我正在尝试使用 Process.Start() 方法。我有一个 Beep() 函数作为第一条指令,Process.Start 以及一个 Process.WaitForExit 方法使它作为最后一条指令阻塞。我让我的代码通过计时器来执行此操作,但现在我开始使用线程。执行上没有区别。被覆盖的 OnStart 方法确实启动了(正如我通过调试确定的那样),但是在生产中启动服务时什么也没有发生,就好像它忽略了我的所有代码一样。将循环和逻辑放在 OnStart 方法中会产生一个不会启动的进程。我知道这是一个线程问题,但我也知道必须强制使用线程。我现在对如何完成这项工作感到目瞪口呆。我很想知道解决方案。

除了服务类之外,我还实现了一个 ServiceInstaller 和 ProcessInstaller,这是我从 MSDN 逐字复制的。

这是我正在尝试使用的一些代码。请注意,这只是反映了我的代码在尝试在线程而不是计时器中实现逻辑时的当前状态(这对我来说是最佳选择):

    Dim config As String
    Dim configValues(2) As String
    Dim objReader As System.IO.StreamReader
    Dim interval As Integer
    Dim launchProcess As Process

    While True
        Beep()
        ' This sub runs every time the elapsed milli-seconds of the timer pass
        ' Sp add your code here.

        config = "30 c:\WiFiDropOutFix\start.vbs"

        Try
            objReader = New System.IO.StreamReader("C:\WiFiDropOutFix\config.txt")
            config = objReader.ReadToEnd
            objReader.Close()
        Catch ex As Exception

        End Try

        configValues = config.Split(New Char() {" "c})
        interval = Convert.ToInt32(configValues(0))

        If Not interval > 0 And Not interval < 61 Then
            interval = 10
        End If

        launchProcess = Process.Start(configValues(1))
        launchProcess.WaitForExit()

        Thread.Sleep(interval * 1000)

    End While
End Sub

这是我请求的 OnStart 代码:

Protected Overrides Sub OnStart(ByVal args() As String)

    appLaunchLogicThread = New Thread(AddressOf appLaunchLogic)
    appLaunchLogicThread.Start()

End Sub

TIA。

【问题讨论】:

  • 我们可以看看你的OnStart 代码吗?
  • 现在提供了 OnStart 代码。请注意,Sub appLaunchLogic 被简单地定义为:“Sub appLaunchLogic()”。计时器滴答方法将使这一切变得不必要。
  • 公共 appLaunchLogicThread 作为线程
  • 是的,我没有看到任何与您的 OnStart 代码有关的内容。我认为您将不得不使用足够详细的日志信息来检测您的代码,以提供有关为什么这在生产中不起作用的线索。
  • 一个想法...可能是权限问题导致Process.Start 抛出异常,该异常将终止线程。在所有代码周围放置一个 try-catch 并将所有异常记录到文件中。

标签: .net vb.net multithreading service cron


【解决方案1】:

尝试进入服务控制面板,编辑服务的属性,然后选中“交互式服务”或“允许服务与桌面交互”选项。如果您尝试启动一个新进程并在屏幕上看到它,除非启用此选项,否则不会发生任何事情。

另外,将服务的登录凭据设置为Administrator,以确保这不是权限问题。如果它有效,那么您已经发现了问题。

另一个提示:将所有处理代码编写为一个您可以轻松调试的普通应用程序,一旦所有错误都被解决并且您知道代码是完美无缺,然后将其实现为服务

【讨论】:

  • 有什么方法可以模拟从本地系统服务帐户启动应用程序?
  • 另外,我正在使用具有无密码管理员帐户的系统。我似乎无法让服务成功登录。无论如何在不设置密码的情况下绕过这个?
  • 我不知道 - 因为它真的是为服务而设计的。不过,作为普通应用程序编写将确保您解决所有与服务无关的问题,然后您可以确定您正在处理与作为服务运行相关的安全或线程问题。我会(1)编写一个普通的应用程序来处理,然后(2)获取应用程序并使处理代码在另一个线程中运行,最后当一切正常时(3)将代码移动到服务中。此外,鉴于服务基本上是不可见的,通常需要使用日志文件进行调试。
  • 您可以随时使用密码创建另一个用户并将其添加到管理员组
  • 我认为这篇文章只会在非常具体的安全问题情况下有用,但可能会有所帮助:blogs.msdn.com/b/adioltean/archive/2004/11/27/271063.aspx
【解决方案2】:

好的,我设法找到了我的项目无法运行的原因。我确实记得看到有人说 [STAThread] 指令对于已启动的进程在服务中执行是必需的,并且它必须放在 Main 函数之前。 Codeproject 已经为 C# 中的 Windows 服务发布了 cron project,它使用了这个指令。我将不得不更多地查看这个已发布的项目,但它可能无法在 VB .NET 中实现。在这一点上,我不明白如何通过 VB .NET Visual Studio Service 模板通过 Main 函数/类来合并服务启动器,因为它似乎已经自行启动了。

另外,我终于找到了一个 Windows cron 服务程序,它可以在几秒钟内运行,没有强制性商业许可证,可以免费使用,并且注册价格合理(根据网站上的说明) )。它被称为WinCron

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    相关资源
    最近更新 更多