总结下今天将一个程序转为windows服务(用C#)
背景
同事写的一个程序每天定时将一个二进制文件分析,转存为数据库。目前这个程序不便之处是服务器重启后必须要登录系统,打开这个程序才可以。还有业务出现了一些变化,需要修改程序,加之前也没写过windows服务程序,所以趁周末学习一下。
过程
肯定是先上博客园搜索一下,找了个blog看看,熟悉一下。
打开vs2008,新建一个windows服务项目,开始把代码搬过来。
- 修改默认生成的Service1.cs文件名使之符合公司规范,并相应修改Program里的类名
- 在下面两个方法中初始化,记录一下事件protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
} - 记录事件是在工具栏拖了个eventLog,这个注意需要自己指定source属性。这样在系统日志里面就可以看到一些日志了。
eventLog.WriteEntry(message + " 时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm", DateTimeFormatInfo.InvariantInfo));
- 再拖一个Timer控件,用于定时执行
- 在Service.cs上点击右键添加一个安装程序,serviceProcessInstaller中设置登录类型,serviceInstaller设置服务名,描述和启动类型
- 剩下的就是把同事的代码整理整理,没敢说是重构,感觉重构属于高深技术,呵呵
- 在OnStart中设置Timer的Enable属性,在Timer的timer_Tick事件中执行。
- 用于以前的程序用到了config配置一些东西,新建一个config文件,自己新建的不能自动copy到debug目录好像,需要自己在项目属性中设置一下,如果不嫌麻烦,可以手动拷贝过去。
- ConfigurationManager.AppSettings["SourceServer"]这个需要添加引用System.configuration。
- 编译通过,下面就是安装这个服务进行测试了,不能像一般的程序那样,直接运行,这个需要安装到系统服务,然后用附加程序的方法调试。安装服务最好吧installutil.exe拷贝一个到程序目录,这样就不用每次都用那个vs的命令行进了。以后安装也方便。
问题
调试发现并没有执行 timer_Tick里的程序,继续博客园搜索,发现VS2008用工具箱拖的那个timer是system.windows.forms下面的timer,此timer在多线程下有问题,而windows服务默认就是起的多线程,所以没有执行。不知道ms为啥在这个里面拖出来的是这个timer,还是我的个例。
换成
System.Timers.Timer timer = new System.Timers.Timer();
timer.Enabled = true;
timer.Interval = 600000;timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Tick);
搞定。
遗留
从附加程序的方法可以调试,但是不能调试OnStart里面的代码啊,因为只要服务运行起来后才可以附加,等你附加上后Onstart早跑过了。
所以不知道这个函数里面的代码怎么调试?难道是在这个里面加sleep延迟一下?