任务:本例中我们做一个定时向本地文件写记录的功能。
一、创建windows服务
创建成功后如图:
右键点击Service1.cs查看代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; namespace MyFirstWindowsService { public partial class Service1 : ServiceBase { public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { } protected override void OnStop() { } } }
三、添加一个FileOperation类文件
四、编写代码到File Operation类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace MyFirstWindowsService { public class FileOpetation { /// <summary> /// 保存至本地文件 /// </summary> /// <param name="ETMID"></param> /// <param name="content"></param> public static void SaveRecord(string content) { if (string.IsNullOrEmpty(content)) { return; } FileStream fileStream = null; StreamWriter streamWriter = null; try { string path = Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, string.Format("{0:yyyyMMdd}", DateTime.Now)); using (fileStream = new FileStream(path, FileMode.Append, FileAccess.Write)) { using (streamWriter = new StreamWriter(fileStream)) { streamWriter.Write(content); if (streamWriter != null) { streamWriter.Close(); } } if (fileStream != null) { fileStream.Close(); } } } catch { } } } }
五、在Service.cs类中调用代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading; namespace MyFirstWindowsService { public partial class Service1 : ServiceBase { System.Threading.Timer recordTimer; public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { IntialSaveRecord(); } protected override void OnStop() { if (recordTimer != null) { recordTimer.Dispose(); } } private void IntialSaveRecord() { TimerCallback timerCallback = new TimerCallback(CallbackTask); AutoResetEvent autoEvent = new AutoResetEvent(false); recordTimer = new System.Threading.Timer(timerCallback, autoEvent, 10000, 60000 * 10); } private void CallbackTask(Object stateInfo) { FileOpetation.SaveRecord(string.Format(@"当前记录时间:{0},状况:程序运行正常!", DateTime.Now)); } } }
六、右键点击添加安装程序
七、右键serviceInstaller1点属性
八,同理,右键serviceProcessInstaller1点属性
这样一个服务就写好了,剩下的就是如何把服务添加到windows服务中。后面就是用代码实现把服务添加到windows服务中。
1)上面写好的服务会在..\Service\MyFirstWindowsService\MyFirstWindowsService\bin\Debug生成
安装程序安装时需要用到这个exe的路径,所以方便起见,将这个生成的exe文件拷贝至安装程序的运行目录下
把exe文件复制在安装程序的bin\Debug下:如..\Service\MyInstallFirstWindowsService\MyInstallFirstWindowsService\bin\Debug
2)新建一个控制台应用程序
3)添加下图两个引用和应用程序配置文件
4)在app.config中添加如下代码
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> </startup> </configuration>
5)最后在Program.cs中添加安装代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Threading; using System.IO; using System.Windows.Forms; using System.ServiceProcess; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); string sysDisk = System.Environment.SystemDirectory.Substring(0, 3); string dotNetPath = sysDisk + @"WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe";//因为当前用的是4.0的环境 string serviceEXEPath = Application.StartupPath + @"\MyFirstWindowsService.exe";//把服务的exe程序拷贝到了当前运行目录下,所以用此路径 string serviceInstallCommand = string.Format(@"{0} {1}", dotNetPath, serviceEXEPath);//安装服务时使用的dos命令 string serviceUninstallCommand = string.Format(@"{0} -U {1}", dotNetPath, serviceEXEPath);//卸载服务时使用的dos命令 try { if (File.Exists(dotNetPath)) { string[] cmd = new string[] { serviceUninstallCommand }; string ss = Cmd(cmd); CloseProcess("cmd.exe"); } } catch { } Thread.Sleep(1000); try { if (File.Exists(dotNetPath)) { string[] cmd = new string[] { serviceInstallCommand }; string ss = Cmd(cmd); CloseProcess("cmd.exe"); } } catch { } try { Thread.Sleep(3000); ServiceController sc = new ServiceController("MyFirstWindowsService"); if (sc != null && (sc.Status.Equals(ServiceControllerStatus.Stopped)) || (sc.Status.Equals(ServiceControllerStatus.StopPending))) { sc.Start(); } sc.Refresh(); } catch { } } /// <summary> /// 运行CMD命令 /// </summary> /// <param name="cmd">命令</param> /// <returns></returns> public static string Cmd(string[] cmd) { Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.Start(); p.StandardInput.AutoFlush = true; for (int i = 0; i < cmd.Length; i++) { p.StandardInput.WriteLine(cmd[i].ToString()); } p.StandardInput.WriteLine("exit"); string strRst = p.StandardOutput.ReadToEnd(); p.WaitForExit(); p.Close(); return strRst; } /// <summary> /// 关闭进程 /// </summary> /// <param name="ProcName">进程名称</param> /// <returns></returns> public static bool CloseProcess(string ProcName) { bool result = false; System.Collections.ArrayList procList = new System.Collections.ArrayList(); string tempName = ""; int begpos; int endpos; foreach (System.Diagnostics.Process thisProc in System.Diagnostics.Process.GetProcesses()) { tempName = thisProc.ToString(); begpos = tempName.IndexOf("(") + 1; endpos = tempName.IndexOf(")"); tempName = tempName.Substring(begpos, endpos - begpos); procList.Add(tempName); if (tempName == ProcName) { if (!thisProc.CloseMainWindow()) thisProc.Kill(); // 当发送关闭窗口命令无效时强行结束进程 result = true; } } return result; } } }
直接运行程序,运行完成后;
除了代码添加windows服务外,也可以用管理员的身份运行Visual Studio 命令提示(2010),
安装输入:installutil ..\Service\MyFirstWindowsService\MyFirstWindowsService\bin\Debug\MyFirstWindowsService.exe
卸载输入:installutil -u ..\Service\MyFirstWindowsService\MyFirstWindowsService\bin\Debug\MyFirstWindowsService.exe
1、服务效果如图
这就是我们新创建的服务,点击启动
2、在查看安装路径下的记录文件。
这样一个服务就运行完成了。
注意,运行vs时一定要用管理员的身份运行