2007-04-10

 

传入时间字符串,返回与系统当前时间的毫秒差值

做Windows service,要从配置文件读取定时处理时间,再取得与当前时间的差,设置处理定时器。下面的函数是为了完成取差值。传入的参数格式是:"HH:MM:SS",秒数可省:"HH:MM",各数值为00~99的数值,表示从零时后多少小时,又多少分,又多少秒,与报时用的时间有别。
        Private Function GetTimeOffset(ByVal strTime As String) As Double
            Dim objReg As New Regex("(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?")
            Dim objMatch As Match
            Dim objLanuch As TimeSpan
            Dim objOffsetSpan As TimeSpan

            If Not objReg.IsMatch(strTime) Then
                Return -1
            End If

            objMatch = objReg.Match(strTime)

            If String.Empty.Equals(objMatch.Groups(3).Value) Then
                objLanuch = New TimeSpan(Integer.Parse(objMatch.Groups(1).Value), _
                    Integer.Parse(objMatch.Groups(2).Value), _
                    0)
            Else
                objLanuch = New TimeSpan(Integer.Parse(objMatch.Groups(1).Value), _
                    Integer.Parse(objMatch.Groups(2).Value), _
                    Integer.Parse(objMatch.Groups(3).Value))
            End If

            objOffsetSpan = objLanuch.Subtract(DateTime.Now.TimeOfDay)
            If objOffsetSpan.TotalMilliseconds <= 0 Then
                objOffsetSpan = objOffsetSpan.Add(New TimeSpan(1, 0, 0, 0))
            End If

            Return objOffsetSpan.TotalMilliseconds
        End Function

Labels: ,


 

如何调试Windows service的onStart()方法

一般来说,启动Windows service后,创建定时器,定时调用处理过程。调试定时处理过程时,挂载到服务进程,再等待定时器被激发后,IDE会停在断点,进行单步跟踪调试。但想对onStart()进行调试却比较困难,因为等我们完成挂载时,onStart()已经执行完毕了。所以,首先要想办法让onStart()慢点执行,以便我们在服务启动并执行到断点前,有足够的时间来挂载调试器。要实现这个功能,最简单的就是让程序在断点前,暂停一段时间。我们可以追回一句:
System.Threading.Thread.Sleep(10000)
Sleep()的参数是毫秒,这里是暂停10秒,应该有足够的时间,让我们从容挂载调试器。
要注意的是,从管理控制台,点启动服务时,就马上去IDE的TOOL菜单下挂载调试器,而不是等服务启动完成。服务是在onStart()执行完毕后,才完成启动的,那时再去挂载,就为时已晚了。这点我们可以修改暂停时间来证明,如果时间设得越长,则服务器动时,那个等待进度条走得就越慢。

Labels: ,


 

.Net2.0下,Windows Service程序Log无法输出的问题

这两天遇到了这个问题,最后发现,是路径的问题。
以下是我的配置:
<system.diagnostics>
<sources>
<source name="DefaultSource" switchname="DefaultSwitch">
<listeners>
<add name="FileLogListener">
<!--<add name="EventLog">-->
</listeners>
</source>
</sources>
<switches>
<add name="DefaultSwitch" value="Information">
</switches>
<sharedlisteners>
<add name="FileLogListener"
type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
initializeData="FileLogListenerWriter"
location="Custom"
customlocation="LOG\" />

<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializedata="APPLICATION_NAME"> -->
</sharedlisteners>
</system.diagnostics>
其中,红色部分为LOG输出路径,我写的是相对路径。
运行Windows Service后,我在EXE所在路径下去检查LOG文件,但不存在。这使我误以为在Windows service下无法使用my.Application.Log,为解决这个问题走了很多弯路。后来,查了MSDN,上面明确提到支持Windows service,而且配置文件,除了使用绝对路径外,其它都相同。于是我也改成绝对路径,测试后发现,确实能输出LOG。
那为什么用相对路径无法输出呢?还是输出到其它路径下去了?
我运行Process Explorer查看windows service进程,发现它打开了文件:%SystemRoot%\system32\LOG\myService.log
这样看来,当采用相对路径时,输出目录是相对于程序的工作目录,而不是可执行文件所在目录。一般的windows application的工作目录,与可执行文件所在目录一致,而windows service由于是系统目录system32下的svchost.exe加载的,它的工作目录也就成了系统目录system32。

Labels: ,


This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]