如果对以个问题,您有更好的实现方法,请不吝赐教,谢谢! 第一次写Windows服务,虽说只是一个小程序,但也够我忙活了几天。本来前段时间就要写的,后来有些其他的事情,给耽搁了。在写这个程序的过程中,碰到了一些问题,现记录下来,希望对一些朋友有些帮助。 我做的这个服务是带界面的,其实服务跟界面是两个不同的项目,只是放在同一个解决方案下而已。 1、启动/停止服务 别看着好像挺简单,一两句代码就能搞定。 添加引用System.ServiceProcess.dll C# codeServiceController 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); 4、获取服务的文件路径 个人觉得通过读取注册表的相应项的方法不错,具体实现代码如下: C# code using Microsoft.Win32; RegistryKey rk = Registry.LocalMachine; RegistryKey rkSub = rk.OpenSubKey("SYSTEM//CurrentControlSet//Services//服务名"); string servicePath = rkSub.GetValue("ImagePath").ToString(); //那么我们就可以轻易地得到第2点所需要的config文件路径 string configPath = servicePath + ".config"; 4、添加服务的描述 本来以为要给某个服务设置“描述”信息应该就像是给服务设置名称一样简单,结果找来找去,竟没有发现可以设置的地方。 搜索了一下,发现以下这个方法不错(保留代码的注释): 把以下的代码插入到ProjectInstaller 类的代码中就可以了。 代码出处:http://www.codeproject.com/dotnet/dotnetscmdescription.asp C# code //This code should be inserted into your ProjectInstaller class' code public override void Install(IDictionary stateServer) { Microsoft.Win32.RegistryKey system, //HKEY_LOCAL_MACHINE/Services/CurrentControlSet currentControlSet, //.../Services services, //.../ service, //.../Parameters - this is where you can put service-specific configuration config; try { //Let the project installer do its job base.Install(stateServer); //Open the HKEY_LOCAL_MACHINE/SYSTEM key system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System"); //Open CurrentControlSet currentControlSet = system.OpenSubKey("CurrentControlSet"); //Go to the services key services = currentControlSet.OpenSubKey("Services"); //Open the key for your service, and allow writing service = services.OpenSubKey(this.BakServiceInstaller.ServiceName, true); //Add your service's description as a REG_SZ value named "Description" service.SetValue("Description", "你的描述写在这里!"); //(Optional) Add some custom information your service will use... config = service.CreateSubKey("Parameters"); } catch(Exception e) { Console.WriteLine("An exception was thrown during service installation:/n" + e.ToString()); } } public override void Uninstall(IDictionary stateServer) { Microsoft.Win32.RegistryKey system, currentControlSet, services, service; try { //Drill down to the service key and open it with write permission system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System"); currentControlSet = system.OpenSubKey("CurrentControlSet"); services = currentControlSet.OpenSubKey("Services"); service = services.OpenSubKey(this.BakServiceInstaller.ServiceName, true); //Delete any keys you created during installation (or that your service created) service.DeleteSubKeyTree("Parameters"); //... } catch(Exception e) { Console.WriteLine("Exception encountered while uninstalling service:/n" + e.ToString()); } finally { //Let the project installer do its job base.Uninstall(stateServer); } }