日期:2014-05-20  浏览次数:20803 次

分享:第一次写Windows服务的几点心得(C#/VS2003)
如果对以个问题,您有更好的实现方法,请不吝赐教,谢谢!

第一次写Windows服务,虽说只是一个小程序,但也够我忙活了几天。本来前段时间就要写的,后来有些其他的事情,给耽搁了。在写这个程序的过程中,碰到了一些问题,现记录下来,希望对一些朋友有些帮助。

 

我做的这个服务是带界面的,其实服务跟界面是两个不同的项目,只是放在同一个解决方案下而已。
1、启动/停止服务
别看着好像挺简单,一两句代码就能搞定。
添加引用System.ServiceProcess.dll

C# code
ServiceController sc = new ServiceController(); 
sc.ServiceName = "服务名";


以下是启动服务和停止服务的按钮事件

C# code
        private void btnStart_Click(object sender, EventArgs e) 
        { 
            sc.Start();//启动 
        } 

        private void btnStop_Click(object sender, EventArgs e) 
        { 
            sc.Stop();//停止 
        } 


如果以为这样就可以,那可就错了。服务的启动或停止可能需要一定的时间,如果在这过程中再去点击启动或停止服务的按钮,程序将会报错。因此,我又加了一些代码,以启动服务事件为例:
C# code

        private void btnStart_Click(object sender, EventArgs e) 
        { 
            sc.Start();//启动 
            sc.WaitForStatus(ServiceControllerStatus.Running);//等待服务达到指定状态 
        }

然而,如果服务已经通过其他方式启动了,点击启动按钮,还是会错,于是还得判断一下:

C# code
        private void btnStart_Click(object sender, EventArgs e) 
        { 
            if(sc.Status==ServiceControllerStatus.Stopped) 
                sc.Start();//启动 
            sc.WaitForStatus(ServiceControllerStatus.Running);//等待服务达到指定状态 
        } 


可是问题还没有解决,经过调试,发现sc.Status并没有取到最新的状态,还得加句代码,最后版本如下:

C# code
        private void btnStart_Click(object sender, EventArgs e) 
        { 
            sc.Refresh();//刷新属性值 
            if(sc.Status==ServiceControllerStatus.Stopped) 
                sc.Start();//启动 
            sc.WaitForStatus(ServiceControllerStatus.Running);//等待服务达到指定状态 
        }

2、读取config文件

如果是自身项目中的config文件,那么只需要:
C# code

            using System.Configuration; 
            string _value = ConfigurationSettings.AppSettings["Key值"];

注意: ConfigurationSettings.AppSettings[""]获取的是程序初始化时的数据,如果此后config文件作了修改,需要在下次初始化时才能获取到新的值(换句话说:程序需要重新启动)。因此如果要使用新值,需要声明全局变量将新值存储起来。

 

但我是在界面项目读取服务项目的config文件,那就得采用其他的方法了:

C# code
            using System.Xml; 

            XmlDocument xmlDoc = new XmlDocument(); 
            xmlDoc.Load(configPath);//configPath是config文件的路径,对于这个路径的获取,将会在后面说明 
            XmlNodeList nodes = xmlDoc.GetElementsByTagName("add"); 
            Hashtable hash = new Hashtable(); 
            foreach (XmlNode node in nodes) 
            { 
                hash.Add(node.Attributes["key"].Value.ToString(), node.Attributes["value"].Value.ToString()); 
            } 
            //通过hash["Key值"].ToString()就能获取到某一个key所对应的value了 


3、修改config配置文件指定key的value

与第2点类似,若是自身项目的config文件,只需要 ConfigurationSettings.AppSettings.Set(key,value)方法就可以搞定的。

但我不得不用读写XML文件来做,具体代码如下:

C# code
   XmlDocument xmlDoc=new XmlDocument(); 
   xmlDoc.Load(configPath);//configPath为config文件的路径 
   XmlNode xmlNode=xmlDoc.SelectSingleNode("configuration/appSettings/add[@key='"+_key+"']");//_key为需要修改其value的key值 
   xmlNode.Attributes["value"].InnerText=_value;//_value为新值 
   xmlDoc.Save(configPath);