在VB.NET 4下创建系统服务时线程/计时器出现问题
我认为在VB.NET下创建一个简单的系统服务是小菜一碟。天哪,我错了。首先,我在谷歌上找到一些帖子,上面说你应该使用Windows.Forms.Timer。然后,我发现了一些相互矛盾的信息,这些信息表示您必须通过代码从timer类派生计时器才能使其工作。然后,人们使用各种类型的线程报告各种各样的问题。由于明显的原因,我无法使用VS2010实时调试器调试线程(不过,我不知道是否有其他方法可以做到这一点)。哇,当没有明确的指南时,这一切是多么令人困惑 我的项目是一个应用程序启动器(类似于cron),它将在一定的时间内定期启动。我正在尝试使用Process.Start()方法。我有一个Beep()函数作为第一条指令,还有Process.Start,还有一个Process.WaitForExit方法,使其阻塞为最后一条指令。我的代码是通过计时器来完成的,但现在我开始使用线程。执行上没有区别。过度使用的OnStart方法确实会启动(我通过调试确定),但在生产环境中启动服务时不会发生任何事情,就好像它忽略了我的所有代码一样。将循环和逻辑放入OnStart方法会产生一个无法启动的进程。我知道这是一个线程问题,但我也知道必须使用线程。我现在对如何使这项工作成功感到目瞪口呆。我很想知道解决办法 除了服务类之外,我还实现了一个ServiceInstaller和ProcessInstaller,它是我从MSDN中逐字复制的 下面是我正在尝试使用的一些代码。请注意,这只是反映了我的代码在尝试在线程而不是计时器中实现逻辑时的当前状态(对我来说这是最佳的):在VB.NET 4下创建系统服务时线程/计时器出现问题,.net,vb.net,multithreading,service,cron,.net,Vb.net,Multithreading,Service,Cron,我认为在VB.NET下创建一个简单的系统服务是小菜一碟。天哪,我错了。首先,我在谷歌上找到一些帖子,上面说你应该使用Windows.Forms.Timer。然后,我发现了一些相互矛盾的信息,这些信息表示您必须通过代码从timer类派生计时器才能使其工作。然后,人们使用各种类型的线程报告各种各样的问题。由于明显的原因,我无法使用VS2010实时调试器调试线程(不过,我不知道是否有其他方法可以做到这一点)。哇,当没有明确的指南时,这一切是多么令人困惑 我的项目是一个应用程序启动器(类似于cron),
TIA.尝试进入服务控制面板,编辑服务的属性,并选中显示“交互式服务”或“允许服务与桌面交互”的选项。如果您试图启动一个新进程并在屏幕上看到它,除非启用此选项,否则不会发生任何事情 另外,将服务的登录凭据设置为管理员,以确保这不是权限问题。如果它有效,那么您已经发现了问题
另一个技巧:将所有处理代码编写成一个普通应用程序,你可以轻松调试,一旦所有的bug都消除了,你知道代码是完美的,然后将其作为一项服务来实现好的,我已经设法找到了我的项目不起作用的原因。我确实记得有人说过,[statthread]指令是在服务中执行已启动进程所必需的,它必须放在主函数之前。Codeproject已在C#中为Windows服务发布了一个命令,并使用此指令。我将不得不更多地研究这个发布的项目,但它可能无法在VB.NET中实现。此时,我不理解如何通过VB.NETVisualStudio服务模板通过主函数/类合并服务启动器,因为它似乎已经自己启动了
此外,我终于找到了一个Windows cron服务程序,它可以在几秒钟内运行,没有强制商业许可证,可以免费使用,并且注册费用合理(根据网站上的说明)。它被称为。我们可以看看您的
OnStart
代码吗?现在提供了OnStart代码。请注意,子appLaunchLogic仅定义为:“子appLaunchLogic()”。计时器滴答法会使所有这些都变得不必要。将appLaunchLogicThread作为thread公开是的,我没有看到您的OnStart
代码有任何明显的缺陷。我认为您必须使用足够详细的日志信息来插入代码,以提供线索,说明这在生产环境中不起作用的原因。有一个想法……可能是权限问题导致进程。启动以引发异常,从而终止线程。在您的所有代码周围放置一个try-catch,并将所有异常记录到一个文件中。是否有任何方法可以模拟从本地系统服务帐户启动应用程序?此外,我正在使用一个具有无密码管理员帐户的系统。我似乎无法使用它使服务成功登录。不管怎样,不用设置密码就可以绕过它吗?据我所知不是这样的,因为它确实是为服务而设计的。不过,作为一个普通的应用程序编写应用程序将确保您解决所有与服务无关的难题,然后您可以确定您正在处理与作为服务运行相关的安全或线程问题。我会(1)编写一个要处理的普通应用程序,然后(2)使用该应用程序并使处理代码在另一个线程中运行,最后在一切正常时(3)将代码移动到服务中。此外,考虑到服务基本上是不可见的,调试通常需要使用日志文件完成。您始终可以使用密码创建另一个用户并将其添加到管理员组。我认为本文仅在非常特定的安全问题情况下有用,但可能会有所帮助:
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
Protected Overrides Sub OnStart(ByVal args() As String)
appLaunchLogicThread = New Thread(AddressOf appLaunchLogic)
appLaunchLogicThread.Start()
End Sub