C# 写 windows service c windows服务程序序 的问题 !

版权所有 京ICP备号-2
迷上了代码!您当前所在位置:
> Visual C#中调用Windows服务初探
Visual C#中调用Windows服务初探
Windows服务是独立于登录用户而工作的Windows应用程序,它通常在计算机启动时开始执行,且常常连续执行,直到计算机关闭为止。像Exchange Server,IIS和杀毒软件等都使用这种方式,
  Windows服务是独立于登录用户而工作的Windows应用程序,它通常在计算机启动时开始执行,且常常连续执行,直到计算机关闭为止。像Exchange Server,IIS和杀毒软件等都使用这种方式,这样就可以独立于某一用户而且可以在任何用户登录前来运行,同时也可以服务于所有的进程,从而以一种服务的形式存在。
  正因为Windows服务有着这么多的特性,因此,当需要一些特殊功能的时候就可以考虑使用Windows服务来解决问题。比如下面我们要做的这个例子。对于我们这些程序设计人员,计算机是在一起工作时间最长的伙伴,每天都会对着它的屏幕八个小时以上,还不包括下班后在家打游戏的时间,因此,保护眼睛是最重要的了。问题的起因来源于本人周六去眼科对激光手术的复查,大夫一再向我强调眼睛的自我调节能力,就是说只要你能保证你每隔一个小时左右就闭眼休息或向远处眺望,离开电脑屏幕,那么已经治好的近视就不会反弹。本人虽是自律性比较强的人,但在计算机屏幕面前就不再如此了,往往几个小时也不抬头一次,为了眼睛的健康,我决定把这个艰巨的任务交由计算机来完成,让它在一小时左右自动提醒我休息五分钟。如此一来,岂不是再也不用顾虑这件事了。
  功能虽然简单,但要写个程序放在启动组里每天自动运行也不是一个好的办法,正巧以前也没做过Windows服务,不如索性来试一试,同进也看看.net为我们提供了多么先进的功能吧,于是决定,就用C#来做一个提醒我保护眼睛的Windows服务,取名就叫CareEye吧。
  运行Visual Studio.NET 2003,建立一个C#的Windows服务项目,在CareEye.cs的设计视图提示可以把需要的控件和组件拖动到这上面,假如想要做系统日志的话当然就可以把EventLog组件拖过来了,不过这个程序好像不需要这些东西,还是算了吧。那么计时要不要采用计时器控件呢?想了一下,这个控件虽然好用,但太常用了,本着学习新知识的原则,最恰当的恐怕就是线程了,而且在以后做其他Windows服务的时候线程肯定是必需的,所以还是用线程好,这样我只要在线程中完成对时间的监测,把线程的启动和停止交给服务的启动和停止,呵,很方便啊。
  再来看CareEye.cs的源程序,一大堆没见过的东西,不过仔细分析一下也就没什么了。CareEye类派生于ServiceBase类,因此继承了基本服务类的特性,显然Main()方法会由SCM(服务控制管理程序)调用,在这个方法中Run一个新的CareEye实例,这样就运行了一个Windows服务,OnStart()和OnStop()明显是用于启动和停止服务的响应函数了。
  注意在Main()方法中有一个ServiceBase[]的数组,它是为那些一个服务进程包含多个服务准备的,对于这个程序来说,它只有一个CareEye服务,因此完全可以把这个数组删除,而只是使用System.ServiceProcess.ServiceBase.Run(new CareEye());一句就够了。
  接下来为了使用线程,需要引入System.Threading命名空间,为了使用对话框,还需要引入System.Windows.Forms命名空间,这是为了将来提示用户时显示对话框而准备的。
  下面为类CareEye添加一个成员字段private Thread MainT同时在构造函数中对其进行初始化:
MainThread=new Thread(new ThreadStart(ThreadFunc)); MainThread.Priority=ThreadPriority.L&
  这里把线程的优先级设到最低,这样不会耗用过多的系统性能。这个线程对象使用ThreadFunc作为线程函数,因此将这个线程函数补充完整:
public static void ThreadFunc() {  int LastHour=DateTime.Now.H  while (true)  {   System.Threading.Thread.Sleep(60000);   if (DateTime.Now.Hour-1==LastHour)   {    MessageBox.Show("为了爱护您的眼睛,请您暂时休息5分钟并向远处眺望!","警告",MessageBoxButtons.OK,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);    LastHour=DateTime.Now.H   }  } }
  余下的代码就简单了,只要在OnStart中启动线程,在OnStop中停止线程就行了。
  以上的服务程序虽然很简单,线程的处理上也不很恰当,也违背了很多服务程序的原则比如界面显示等,但对于本人的需求而言是足够了,因此就如此制作了。如果你有需要,当然可以把对话框改为其他的提醒方式如响铃等,线程也可以使用内核对象同时使用更好的处理方法。
  Windows服务就做完了,余下的就是要测试了,但发现这个EXE无法运行,它会提示你该EXE需要使用安装程序来安装服务,看来不可能写一个程序就算是Windows服务了,还要把它注册到Windows才行。
  接下来,右击CareEye.cs的设计视图,添加安装程序,(VS.net想得就是挺周到的),这下又出来一批代码,不过好在不用改代码了,只要把Account的账户类型设成LocalSystem,把StartType设成手动启动就行了,这里用手动是为了方便调试,以后可以改成自动类型。
  编译完后,还是无法运行,此处还需要一步,就是运行installutil来安装这个服务,其安装和卸载的用法为:
installutil CareEye.exe installutil /u CareEye.exe&
  安装完后能过系统的服务管理器你就可以看到你的服务了,只要点击启动就可以把它启动,把时间向前改一个小时它就会提醒你需要休息了,呵呵,够简单了吧。
  如果你想制作成安装包分发给自己的朋友,只需要再添加个部署项目就行了,不过为了完成自注册,要在自定义操作编辑器中的安装阶段添加一个自定义的安装操作,把InstallerClass属性设成TRUE即可。
  余下的事情,就是自己动手试试吧,这回不用担心用眼超时了!
 以下是careeye.cs的源程序:
using S using System.C ponentM using System.D using System.D using System.ServiceP using System.T using System.Windows.F namespace CareEye {  public class CareEye : System.ServiceProcess.ServiceBase  {   private Thread MainT   /// &summary&   /// 必需的设计器变量。   /// &/summary&   ponentModel.Container components =
  public CareEye()   {    // 该调用是 Windows.Forms 组件设计器所必需的。    InitializeComponent();
   // TODO: 在 InitComponent 调用后添加任何初始化    MainThread=new Thread(new ThreadStart(ThreadFunc));    MainThread.Priority=ThreadPriority.L   }
  // 进程的主入口点   static void Main()   {    //System.ServiceProcess.ServiceBase[] ServicesToR
   // 同一进程中可以运行多个用户服务。若要将    //另一个服务添加到此进程,请更改下行    // 以创建另一个服务对象。例如,    //    // ServicesToRun = New System.ServiceProcess.ServiceBase[] {new CareEye(), new MySecondUserService()};    //    //ServicesToRun = new System.ServiceProcess.ServiceBase[] { new CareEye() };
   System.ServiceProcess.ServiceBase.Run(new CareEye());   }
  /// &summary&   /// 设计器支持所需的方法 - 不要使用代码编辑器   /// 修改此方法的内容。   /// &/summary&   private void InitializeComponent()   {    //    // CareEye    //    this.ServiceName = "CareEye";
  /// &summary&   /// 清理所有正在使用的资源。   /// &/summary&
  protected override void Dispose( bool disposing )   {    if( disposing )    {     if (components != null)     {      components.Dispose();     }    }    base.Dispose( disposing );   }
  /// &summary&   /// 设置具体的操作,以便服务可以执行它的工作。   /// &/summary&   protected override void OnStart(string[] args)   {    // TODO: 在此处添加代码以启动服务。    MainThread.Start();   }
  /// &summary&   /// 停止此服务。   /// &/summary&   protected override void OnStop()   {    // TODO: 在此处添加代码以执行停止服务所需的关闭操作。    MainThread.Abort();   }   public static void ThreadFunc()   {    int LastHour=DateTime.Now.H    while (true)    {     System.Threading.Thread.Sleep(60000);     if (DateTime.Now.Hour-1==LastHour)     {      MessageBox.Show("为了爱护您的眼睛,请您暂时休息5分钟并向远处眺望!","警告",MessageBoxButtons.OK,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1,MessageBoxOptions.DefaultDesktopOnly); LastHour=DateTime.Now.H     }    }   }  } }&
关键词标签:
延伸相关阅读:
小巧方便的极速浏览器
彩蝶浏览器是一款便捷、小巧的上网浏览工具,占用内存小,一键触达...C#.net 4.0写的windows服务,启动就出错,该怎么调试呢?_百度知道
C#.net 4.0写的windows服务,启动就出错,该怎么调试呢?
网上看了很多调试方法,但前提都是要先启动服务才能调试。在可能出错的地方加入 文件输出参数 的方式 又太麻烦了··
但运行后没有控制台。OnStart里边只有初始化消息队列和启动线程的操作,其他什么都没有了。。怎么变成Console Application呢?我有更改main函数,可以调试断点了。日志中只有堆栈信息哈
提问者采纳
并把你OnStart里的逻辑移到Main方法运行,可以将这些操作移到新线程去执行。还有可能就是你的OnStart里的处理逻辑太耗时,看有没有问题在本机你可以先你你的服务项目类型变成Console Application
其他类似问题
您可能关注的推广
windows服务的相关知识
其他3条回答
这样可以调试sleep之后的代码了在OnStart里让线程sleep一段时间(20秒应该够了),迅速把这个服务的进程附加到VS里,在sleep这段时间中
可以写个控制台程序 调用 你的服务代码可以写日志可以 写个form程序 调用你的服务代码都可以就看你 怎么方便
启动就出错,错误会在你的事件日志里面,eventvwr.msc 打开你的事件查看器,最新的错误应该出现在Windows日志\应用程序里面。 =================================================把服务调整成控制台程序的方法确实可以用来调试,但是不是所有的情况适用。有个别的情况,完全相同的代码在不同的程序类型中,其结果是不同的。比如Environment.CurrentDirectory的返回值是不同的。如果你想在服务运行的时候记录一些日志在服务所在的目录里,那么最好用ConfigurationManager.AppSettings[&你的配置节点名&]来设置。
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁BI即商务智能,它是一套完整的解决方案..
微软12亿美元现金收购企业社交供应商Yamm..
C#Windows服务程序开发实例介绍
软网提示:C#Windows服务程序开发实例程序的目的和用途:很多开机启动程序仅仅加在启动项里面,只有登陆后才真正启动。windows服务在开机未C#Windows服务程序开发实例程序的目的和用途:很多开机启动程序仅仅加在启动项里面,只有登陆后才真正启动。windows服务在开机未进行用户登录前就启动了。正是利用这一点,解决一些服务器自动重启后特定软件也自动启动的问题。C#Windows服务程序开发1.新建一个服务项目 visual C#----windows----windows服务;C#Windows服务程序开发2.添加一个dataset(.xsd),用于存储启动目标的路径,日志路径等。在dataset可视化编辑中,添加一个datatable,包含两列 StartAppPath 和 LogFilePath。分别用于存储目标的路径、日志路径。我认为利用dataset.xsd存储配置参数的优势在于可以忽略xml解析的具体过程直接使用xml文件。在dataset中 提供了ReadXml方法用于读取xml文件并将其转换成内存中的一张datatable表,数据很容易取出来!同样,WriteXml方法用于存储为xml格式的文件,也仅仅需要一句话而已。C#Windows服务程序开发3. program.cs文件 作为程序入口,代码如下:view&plaincopy&to&clipboardprint? &using&System.Collections.G&&& &using&System.ServiceP&&& &using&System.T&&& &&& &namespace&WindowsServices_AutoStart&&& &{&&& &static&class&Program&&& &{&&& &///&﹤summary﹥&&& &///&应用程序的主入口点。&&& &///&﹤/summary﹥&&& &static&void&Main()&&& &{&&& &ServiceBase[]&ServicesToR&&& &&& &//&同一进程中可以运行多个用户服务。若要将&&& &//&另一个服务添加到此进程中,请更改下行以&&& &//&创建另一个服务对象。例如,&&& &//&&& &//&&&ServicesToRun&=&new&ServiceBase[]&{ &new&Service1(),&new&MySecondUserService()};&&& &//&&& &ServicesToRun&=&new&ServiceBase[]&{& &new&WindowsServices_AutoStart()&};&&& &&& &ServiceBase.Run(ServicesToRun);&&& &}&&& &}&&& &}&& &using&System.Collections.G &using&System.ServiceP &using&System.T &&namespace&WindowsServices_AutoStart &{ &static&class&Program &{ &///&﹤summary﹥ &///&应用程序的主入口点。 &///&﹤/summary﹥ &static&void&Main() &{ &ServiceBase[]&ServicesToR &&//&同一进程中可以运行多个用户服务。若要将 &//&另一个服务添加到此进程中,请更改下行以 &//&创建另一个服务对象。例如, &// &//&&&ServicesToRun&=&new&ServiceBase[]&{ &new&Service1(),&new&MySecondUserService()}; &// &ServicesToRun&=&new&ServiceBase[]&{ &&new&WindowsServices_AutoStart()&}; &&ServiceBase.Run(ServicesToRun); &} &} &}&&C#Windows服务程序开发4.service.cs主文件,代码如下:view&plaincopy&to&clipboardprint? &using&S&&& &using&System.Collections.G&&& &using&ponentM&&& &using&System.D&&& &using&System.IO;&&& &using&System.D&&& &using&System.ServiceP&&& &using&System.T&&& &&& &namespace&WindowsServices_AutoStart&&& &{&&& &public&partial&class& &WindowsServices_AutoStart&:&ServiceBase&&& &{&&& &public&WindowsServices_AutoStart()&&& &{&&& &InitializeComponent();&&& &}&&& &string&StartAppPath&=""; &&//@"F:\00.exe";&&& &string&LogFilePath&=""; &//&@"f:\WindowsService.txt";&&& &protected&override&void&OnStart(string[]&args)&&& &{&&& &string&exePath&=&System.Threading. &Thread.GetDomain().BaseD&&& &//&&& &if&(!File.Exists(exePath&+&@"\ServiceAppPath.xml"))&&& &{&&& &dsAppPath&ds&=&new&dsAppPath();&&& &object[]&obj=new&object[2];&&& &obj[0]="0";&&& &obj[1]="0";&&& &ds.Tables["dtAppPath"].Rows.Add(obj);&&& &ds.Tables["dtAppPath"].WriteXml( &exePath&+&@"\ServiceAppPath.xml");&&& &&&& &}&&& &try&& &{&&& &dsAppPath&ds&=&new&dsAppPath();&&& &ds.Tables["dtAppPath"].ReadXml( &exePath&+&@"\ServiceAppPath.xml");&&& &DataTable&dt&=&ds.Tables["dtAppPath"];&&& &StartAppPath&=&dt.Rows[0] &["StartAppPath"].ToString();&&& &LogFilePath&=&dt.Rows[0] &["LogFilePath"].ToString();&&& &}&&& &catch&{&&}&&& &&&& &if&(File.Exists(StartAppPath))&&& &{&&& &try&& &{&&& &Process&proc&=&new&Process();&&& &proc.StartInfo.FileName&=&StartAppP&//注意路径&&& &//proc.StartInfo.Arguments&=&"";&&& &proc.Start();&&& &}&&& &catch&(System.Exception&ex)&&& &{&&& &//MessageBox.Show(this,&"找不到帮助文件路径。 &文件是否被改动或删除?\n"&+&ex.Message,&"提示", &&MessageBoxButtons.OK,&rmation);&&& &}&&& &FileStream&fs&=&new&FileStream(LogFilePath,& &FileMode.OpenOrCreate,&FileAccess.Write);&&& &StreamWriter&m_streamWriter&=&new&StreamWriter(fs);&&& &m_streamWriter.BaseStream.Seek(0,&SeekOrigin.End);&&& &m_streamWriter.WriteLine("WindowsService:& &Service&Started"&+&DateTime.Now.ToString()&+&"\n");&&& &m_streamWriter.Flush();&&& &m_streamWriter.Close();&&& &fs.Close();&&& &}&&& &}&&& &&& &protected&override&void&OnStop()&&& &{&&& &try&& &{&&& &//&TODO:&在此处添加代码以执行停止服务所需的关闭操作。&&& &FileStream&fs&=&new&FileStream(LogFilePath, &&FileMode.OpenOrCreate,&FileAccess.Write);&&& &StreamWriter&m_streamWriter&=&new&StreamWriter(fs);&&& &m_streamWriter.BaseStream.Seek(0,&SeekOrigin.End);&&& &m_streamWriter.WriteLine("WindowsService: &&Service&Stopped&"&+&DateTime.Now.ToString()&+&"\n");&&& &m_streamWriter.Flush();&&& &m_streamWriter.Close();&&& &fs.Close();&&& &}&&& &catch&& &{&&& &&& &}&&& &}&&& &}&&& &}&& &using&S &using&System.Collections.G &using&ponentM &using&System.D &using&System.IO; &using&System.D &using&System.ServiceP &using&System.T &&namespace&WindowsServices_AutoStart &{ &public&partial&class& &WindowsServices_AutoStart&:&ServiceBase &{ &public&WindowsServices_AutoStart() &{ &InitializeComponent(); &} &string&StartAppPath&="";& &//@"F:\00.exe"; &string&LogFilePath&=""; &//&@"f:\WindowsService.txt"; &protected&override&void&OnStart(string[]&args) &{ &string&exePath&=&System. &Threading.Thread.GetDomain().BaseD &// &if&(!File.Exists(exePath&+&@"\ServiceAppPath.xml")) &{ &dsAppPath&ds&=&new&dsAppPath(); &object[]&obj=new&object[2]; &obj[0]="0"; &obj[1]="0"; &ds.Tables["dtAppPath"].Rows.Add(obj); &ds.Tables["dtAppPath"].WriteXml( &exePath&+&@"\ServiceAppPath.xml"); & &} &try&{ &dsAppPath&ds&=&new&dsAppPath(); &ds.Tables["dtAppPath"].ReadXml( &exePath&+&@"\ServiceAppPath.xml"); &DataTable&dt&=&ds.Tables["dtAppPath"]; &StartAppPath&=&dt.Rows[0] &["StartAppPath"].ToString(); &LogFilePath&=&dt.Rows[0] &["LogFilePath"].ToString(); &} &catch&{&&} &&if&(File.Exists(StartAppPath)) &{ &try&{ &Process&proc&=&new&Process(); &proc.StartInfo.FileName&=&StartAppP&//注意路径 &//proc.StartInfo.Arguments&=&""; &proc.Start(); &} &catch&(System.Exception&ex) &{ &//MessageBox.Show(this,&" &找不到帮助文件路径。文件是否被改动或删除?\n" &&+&ex.Message,&"提示",&MessageBoxButtons.OK, &&rmation); &} &FileStream&fs&=&new&FileStream(LogFilePath, &&FileMode.OpenOrCreate,&FileAccess.Write); &StreamWriter&m_streamWriter&=&new&StreamWriter(fs); &m_streamWriter.BaseStream.Seek(0,&SeekOrigin.End); &m_streamWriter.WriteLine("WindowsService:& &Service&Started"&+&DateTime.Now.ToString()&+&"\n"); &m_streamWriter.Flush(); &m_streamWriter.Close(); &fs.Close(); &} &} &&protected&override&void&OnStop() &{ &try&{ &//&TODO:&在此处添加代码以执行停止服务所需的关闭操作。 &FileStream&fs&=&new&FileStream(LogFilePath,& &FileMode.OpenOrCreate,&FileAccess.Write); &StreamWriter&m_streamWriter&=&new&StreamWriter(fs); &m_streamWriter.BaseStream.Seek(0,&SeekOrigin.End); &m_streamWriter.WriteLine("WindowsService:& &Service&Stopped&"&+&DateTime.Now.ToString()&+&"\n"); &m_streamWriter.Flush(); &m_streamWriter.Close(); &fs.Close(); &} &catch&{ &&} &} &} &}&C#Windows服务程序开发5.启动调试,成功时也会弹出一个对话框大致意思是提示服务需要安装。C#Windows服务程序开发6.把Debug文件夹下面的.exe执行程序,安装为windows系统服务,安装方法网上很多介绍。我说一种常用的:C#Windows服务程序开发之安装服务访问项目中的已编译可执行文件所在的目录。用项目的输出作为参数,从命令行运行 InstallUtil.exe。在命令行中输入下列代码:&installutil yourproject.exeC#Windows服务程序开发之卸载服务&用项目的输出作为参数,从命令行运行 InstallUtil.exe。& installutil /u yourproject.exe至此,整个服务已经编写,编译,安装完成,你可以在控制面板的管理工具的服务中,看到你编写的服务。C#Windows服务程序开发7.安装好了之后在系统服务列表中可以管理服务,这时要注意将服务的属性窗口----登陆----“允许于桌面交互”勾选!这样才能在启动了你要的目标程序后不单单存留于进程。在桌面上也看得到。C#Windows服务程序开发8.关于卸载服务,目前有两个概念:一是禁用而已;一是完全删除服务。 前者可以通过服务管理窗口直接完成。后者则需要进入注册表“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services”找到服务名称的文件夹,整个删掉,重新启动电脑后,服务消失。C#Windows服务程序开发9.扩展思考:经过修改代码,还可以实现:启动目标程序之前,检测进程中是否存在目标程序,存在则不再次启动。C#Windows服务程序开发的实例的基本内容就向你,希望对你学习和理解C#Windows服务程序开发有所帮助。C#Windows服务程序开发之Windows服务浅析C#Windows服务程序安装浅析C#Windows服务程序开发的体会C#启动windows服务的方法浅析C#windows服务状态改变操作浅析【责任编辑:李彦光 TEL:(010)】
移动互联网正在重新定义企业,企业如何抢占移动互联时代发展先机?如何打破传统商业模式?如何寻找新的营销手段?在这里找到答案:

我要回帖

更多关于 windows 服务程序 的文章

 

随机推荐