公司要做一个windows监听文件夹的服务,时间紧急,马上研究,摘了很多坑,最后终于搞定了,步骤如下:
新建windows服务项目
点击切换到代码,写入代码:
protected override void OnStart(string[] args) { System.Timers.Timer timer = new System.Timers.Timer(); timer.Elapsed += new System.Timers.ElapsedEventHandler(TimedEvent); timer.Interval = 3000;//每3秒执行一次 timer.Enabled = true; this.WriteLog("搜才Organiz客户端数据同步服务:【服务启动】"); //Console.WriteLine("开始!"); //Console.ReadKey(); } protected override void OnStop() { this.WriteLog("搜才Organiz客户端数据同步服务:【服务停止】"); //Console.WriteLine("结束!"); //Console.ReadKey(); } private void TimedEvent(object sender, System.Timers.ElapsedEventArgs e) { Console.WriteLine(DateTime.Now.ToString()); using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"D: emp1 est2.txt", true)) { file.WriteLine(DateTime.Now.ToString());// 直接追加文件末尾,换行 } } private void WriteLog(string msg) { string path = AppDomain.CurrentDomain.BaseDirectory + "\log.txt"; FileInfo file = new FileInfo(path); if (!file.Exists) { FileStream fs = File.Create(path); fs.Close(); } using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.WriteLine(DateTime.Now.ToString() + "" + msg); } } }
注意用2015新建的项目默认用.net framework4.7.2,这里我们在项目-》属性-》应用程序 中修改为之前版本,否者App.config文件会报configration未命名错误,换回低版本即可
双击Service1.cs文件,进入设计页面,对着空白处右键-》添加安装器
修改服务属性
修改安装程序的属性
选择localsystem,这里解释一下,因为windows是多用户系统,选择localsystem是为了所有用户登录windows都可以启动服务,并且如果默认选择user,在后期安装时会填写用户和密码
然后将从C:WindowsMicrosoft.NETFrameworkv4.0.30319中拷贝installutil.exe文件到生成目录(bin/Debug目的使installutil.exe和dp0WindowsService1.exe在同一级目录)下。在该目录新建“安装.bat”文件,使用记事本打开,输入如下命令:
%~dp0InstallUtil.exe %~dp0WindowsService1.exe
pause
注意前每个命令前要加一个%~dp0,表示将目录更改为当前目录。倘若不加,可能会出错。pause 一定要换行,否则报错。
最后用管理员打开.bat文件,就完成服务注册了。
在我的电脑上右键选择“管理”,打开“服务和应用程序”下的“服务”,就能看到我们注册的服务了。
卸载服务前停止服务
%~dp0installUtil /u %~dp0WindowsService1.exe
pause
管理员身份执行.bat文件
错误类型:
这种通常是程序本身的错误, 应该是服务的逻辑代码出了问题,打开控制面板/管理工具/事件查看器 ->应用程序 里发现了如下信息:
1053和1054都是操作不规范导致的
停止服务,重新生成
如果服务运行一段时间停止,解决方法如下:
重写commit方法
public override void Commit(IDictionary savedState) { base.Commit(savedState); ServiceController sc = new ServiceController("ServerDemo"); if (sc.Status.Equals(ServiceControllerStatus.Stopped)) { sc.Start(); } }
如果要监听文件夹,并读取新增文件中的内容,代码如下:
watcher.Changed +=
new
FileSystemEventHandler(watch_changed);
watcher.NotifyFilter = NotifyFilters.Size;
对比
watcher.Created +=
new
FileSystemEventHandler(watch_created);
watcher.NotifyFilter = NotifyFilters.FileName;
Changedd和Size搭配顾明思议,被监听文件夹的大小发生变化,并等待文件完全写入触发事件
Create和FileName搭配,意思是当文件被创建,并不等待写入是否结束 就触发事件,这个会导致监听程序中读取新增文件时 发生读取不完全错误
本人亲自尝试