• C# windows 服务编写及安装


        最近项目中用到window服务程序,以前没接触过,比较陌生,花了两天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作不成功,可能是开发环境或项目配置的不同,这里把自己成功制作的方式贴出来,一方面留给自己,一方面也希望能给遇到同样问题绝望中不能自拔、以致失去灵魂的路人甲,路人乙一还魂丹 . . .

          IDE WIN2003  VS2008  SQL2005

    Demo下载地址:http://download.csdn.net/detail/zahxz/5730281

          一、创建window服务项目

          首先我们建一个window服务项目 :解决方案(右击)——> 增加 ——> 新建项目——>项目类型选择Windows——>模板选择Windows服务 ,如图: 

     

     

          二、编写Window服务程序

          创建后会生成两个文件 Program.cs 和 Service1.cs ,其中 program.cs 这个文件不用动,里面已自动生成好了。我们在Service1.cs里增加所要的操作,里面有两个重写方法 OnStart 和 OnStop OnStart 方法表示服务启动的操作,OnStop 表示服务停止的操作,下面写了一个简单示例 :当服务启动后,调用远程一个WebServiceHello函数,并把返回的值写入到一个文件中。code如下:

    代码 

    /// <summary>
            /// 服务启动的操作
            /// </summary>
            /// <param name="args"></param>
            protected override void OnStart(string[] args)  
            {
                StartHello();
            }

            /// <summary>
            /// 服务停止的操作
            /// </summary>
            protected override void OnStop()
            {
                try
                {
                    ThreadHello.Abort();

                    Flag = false;

                    System.Diagnostics.Trace.Write("线程停止");
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.Write(ex.Message);
                }
            }

            private Thread ThreadHello;

            private void StartHello()
            {
                try
                {
                    // 标准形式
                    
                    //ThreadStart NewThreadStart = new ThreadStart(VoidName);
                    //Thread NewThead = new Thread(NewThreadStart);
                    //NewThead.Start();

                    ThreadHello = new Thread(new ThreadStart(Hello));
                    ThreadHello.Start();
                    System.Diagnostics.Trace.Write("线程任务开始");
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.Write(ex.Message);
                    throw ex;
                }
            }

            private void Hello()
            {
                while (Flag)
                {
                    localhost.AdvService la = new WindowsService1.localhost.AdvService();
                    try
                    {
                        string helloname = la.Hello("Andy"); // 调用远程WebService中的方法
                        writeInLog(helloname, false);   // 把调用返回的数据写入到文件中
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Trace.Write(ex.Message);
                        throw ex;
                    }

                    Thread.Sleep(5000);
                }
            }

            /// <summary>
            /// 写入文件操作
            /// </summary>
            /// <param name="msg">写入内容</param>
            /// <param name="IsAutoDelete">是否删除</param>
            private void writeInLog(string msg, bool IsAutoDelete)
            {
                try
                {
                    string logFileName = @"E:SamplePG_Samplelog.txt"; // 文件路径
                    FileInfo fileinfo = new FileInfo(logFileName);
                    if (IsAutoDelete)
                    {
                        if (fileinfo.Exists && fileinfo.Length >= 1024)
                        {
                            fileinfo.Delete();
                        }
                    }
                    using (FileStream fs = fileinfo.OpenWrite())
                    {
                        StreamWriter sw = new StreamWriter(fs);
                        sw.BaseStream.Seek(0, SeekOrigin.End);
                        sw.WriteLine("=====================================");
                        sw.Write("添加日期为:" + DateTime.Now.ToString() + " ");
                        sw.Write("日志内容为:" + msg + " ");
                        sw.WriteLine("=====================================");
                        sw.Flush();
                        sw.Close();
                    }
                }
                catch (Exception ex)
                {
                    ex.ToString();
                }
            }

     

          例子很简单,方便理解,上面通过线程,每5秒执行一次操作,到这里,我们的服务以及服务实现的功能就已经写好了,下面怎么让客户端安装我们的服务呢?这里才是我写这篇文章的目的!先要增加一个安装程序类,切换到视图窗口,右击——>增加安装程序,便会增加一个程序安装类文件 ProjectInstaller.cs,如图:

     

    这里serviceProcessInstaller1 和 serviceInstaller1 有几个重要属性要设置,serviceInstaller1 中的StartType要设置成Automatic,表示随机启动,ServiceName表示服务名称,Description 表示服务的描述, DisplayName 表示显示名称。serviceProcessInstaller1 中的Account要设置成LocalSystem,表示本地系统帐号 

     

          Window服务的安装有两个方式:

          一、命令安装

     

           通过命令窗口,执行 InstallUtil.exe 服务路径 可安装Window服务,你是不是觉得我在扯,这么长的命令怎么看?怎么记住?可以想想如果客户端是一个不懂程序的人是不可能自己完成安装的,那么能不能制作一个简单有效,点点按钮可以安装的呢,答案是肯定的 ——> 安装程序制作

           二、安装程序

           安装程序制作 :解决方案(右击)——> 增加 ——> 新建项目 ——> 项目类型选择安装和部署 ——>  模板选择安装项目   如图 

     

     

         创建后,安装项目(右击) ——> 视图 ——> 文件系统 如图:

     

     

         由于我们是安装服务,就不需要用户桌面和程序菜单了,直接应用程序文件夹(右击)——> 增加 ——> 项目输出 入图 :

     

           上面有两点需要注意 ,一 项目选择中选择要安装的服务, 二 项目选择下面要选择主输出,选择好后确定,这一步增加了安装程序的文件夹,下一步就是给这个安装程序增加操作,这里我们增加两个基本操作,一个是安装,一个是卸载。安装项目(右击) ——> 视图 ——> 自定义操作 如图

     

           上面可以看到有安装,提交,回滚,卸载等操作,我们先增加安装操作,安装(右击)——> 增加自定义操作,会弹出一个对话 如图:

     

          选择应用程序文件夹,并选中之前增加的主输出项,确定,这样这个安装程序就增加了安装的操作,同样按照这样的方式增加卸载操作,卸载与安装唯一不同的是需要设置一个命令参数,不可少,如图:

     

          这里 Arguments 里输入 /u  表示卸载命令相当于 InstallUtil.exe /u 服务路径  , 到这里 ,我们的安装程序就已经制作好了,生成安装程序项目,将会生成 setup.exe 和 setup.msi 安装文件,拷贝到客户端,点击setup.exe 就像安装QQ一样安装我们的服务,实际上比QQ好多了,QQ还有广告,我们可是纯绿色的!

     

     

    安装完后自动启动:

    1、重写ProjectInstallerCommit方法

    using System;

    using System.Collections;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Configuration.Install;

    using System.Linq;

    using System.ServiceProcess;

     

     

    namespace CleanExpiredSessionSeivice

    {

        [RunInstaller(true)]

        public partial class ProjectInstaller : System.Configuration.Install.Installer

        {

            public ProjectInstaller()

            {

                InitializeComponent();

            }

     

            public override void Commit(IDictionary savedState)

            {

                base.Commit(savedState);

                //Auot start service after the installation is completed

                ServiceController sc = new ServiceController("CleanExpiredSessionSeivice");

                if (sc.Status.Equals(ServiceControllerStatus.Stopped))

                {

                    sc.Start();

                }

            }

        }

    }

    2、在服务安装项目中添加名为 Commit的 Custome Action

    在服务安装项目上右击,在弹出的菜单中选择View — Custom Actions

     

    然后在Commit项上右击,选择Add Custom Action…,在弹出的列表框中选择Application Folder。最终结果如下:

     

    需要注意的是,第二步操作是必不可少的,否则服务无法自动启动。我的个人理解是Commit Custom Action 会自动调用ProjectInstallerCommit方法,Commit Custom Action 在这里扮演了一个调用者的角色。

    Demo下载地址:http://download.csdn.net/detail/zahxz/5730281

  • 相关阅读:
    一些比较实用的小函数
    开发KOL程序 (1)
    开发KOL程序2
    使用mask来制作图像透明
    用U盘方便快捷安装系统
    Windows记忆专家
    Delphi开发桌面图标列表查看程序
    js压缩上传图片,转载
    js操作二进制数据
    mui扫码横屏全屏
  • 原文地址:https://www.cnblogs.com/zahxz/p/3435638.html
Copyright © 2020-2023  润新知