C#实现Windows服务

资源:Walkthrough: Creating a Windows Service Application in the Component Designer: https://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx

注意事项

  1. 调试服务:先启动服务,然后Attach到服务进程。
  2. 需要添加安装模块,这样可以安装Windows服务。使用InstallUtil.exe安装。
  3. 服务运行在different window station,不是interactive的,如果服务弹出对话框,用户是看不见的,这时候可能中断服务,使服务失去响应。

安装服务。

  1. 命令。InstallUtil /i MyService.exe安装服务。InstallUtil /u MyService.exe卸载服务。
  2. 编程。ManagedInstallerClass
                if (args[0] == "-i")
                {
                    ManagedInstallerClass.InstallHelper(new[] { Assembly.GetExecutingAssembly().Location });
                }
                else if (args[0] == "-u")
                {
                    ManagedInstallerClass.InstallHelper(new[] { "/u", Assembly.GetExecutingAssembly().Location });
                }

控制服务状态:

  1. 命令。使用sc start ServiceName启动服务,sc stop ServiceName停止服务,sc query ServiceName查询服务状态。Sc delete ServiceName删除服务。
  2. 编程。System.ServiceProcess.ServiceController。 https://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller(v=vs.110).aspx
  3. 服务管理界面。

clip_image001

创建服务。

如果创建新项目,可以使用Windows服务模板。

clip_image002

如果是现有项目,往项目中添加Windows服务模块。

clip_image003

在Main中调用ServiceBase.Run把服务跑起来

ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new Service1() 
            };
            ServiceBase.Run(ServicesToRun);

在OnStart和OnStop中启动和清理工作线程。注意不要在OnStart中提供服务(比如while循环),否则服务一直会是正在启动状态,后面也就没有办法停止服务了。

protected override void OnStart(string[] args)
        {
            //启动后台线程,提供服务
        }

在控制台测试。为了测试,我们可能在控制台跑服务。

private static void Main(string[] args)
        {
            if (Environment.UserInteractive)
            {
                var service = new Service1();
                service.TestService(args);
            }
            else
            {
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] { new Service1() };
                ServiceBase.Run(ServicesToRun);
            }
        }

///Service1
        public void TestService(string[] args)
        {
            this.OnStart(args);

            Console.ReadLine();

            this.OnStop();
        }

注意程序的编译输出类型应该为“控制台应用程序”。

clip_image004

添加安装模块。在Service的设计界面上右键,选择添加安装程序。

clip_image005

设置添加的Installer中的控件属性,包括服务运行的账号,服务名等。

clip_image006

clip_image007

设置服务状态

如果服务启动时间很长,可以在代码里面设置服务显示的状态。

public enum ServiceState
    {
        SERVICE_STOPPED = 0x00000001,
        SERVICE_START_PENDING = 0x00000002,
        SERVICE_STOP_PENDING = 0x00000003,
        SERVICE_RUNNING = 0x00000004,
        SERVICE_CONTINUE_PENDING = 0x00000005,
        SERVICE_PAUSE_PENDING = 0x00000006,
        SERVICE_PAUSED = 0x00000007,
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct ServiceStatus
    {
        public long dwServiceType;
        public ServiceState dwCurrentState;
        public long dwControlsAccepted;
        public long dwWin32ExitCode;
        public long dwServiceSpecificExitCode;
        public long dwCheckPoint;
        public long dwWaitHint;
    };

//在服务中导入方法
        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);


//使用方法。
            ServiceStatus status = new ServiceStatus();
            status.dwCurrentState = ServiceState.SERVICE_START_PENDING;

            SetServiceStatus(this.ServiceHandle, ref status);
posted on 2016-05-27 17:47  ShaunLing  阅读(597)  评论(0编辑  收藏  举报