Windows服务开发

1.新建Windows服务项目

(1)

(2)默认服务名称“Service1”。双击服务,在"设计"视图中,右击"属性",在属性窗口可以重命名服务

业务代码中,默认重写OnStart和OnStop两个方法,用于启动和停止服务对组件的处理:

        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="args"></param>
        protected override void OnStart(string[] args)
        {
            Log4netHelper.Info("Demo Service启动");
            // TODO 业务处理
        }

        /// <summary>
        /// 停止
        /// </summary>
        protected override void OnStop()
        {
            Log4netHelper.Info("Demo Service停止");
        }

(3)添加安装程序

(4)配置安装程序

注意:

  • Account设置为LocalService。
  • ServiceName设置为DemoService,和服务类名称保持一致。
  • StartType设置为Automatic,自启动。
  • Description设置服务描述,此描述在"服务"窗口描述列显示。
  • DisplayName可以不同于ServiceName属性,它是系统使用的名称,此名称在"服务"窗口名称列显示。

 

2.调试服务-将 Windows 服务作为控制台应用运行

(1)向你运行 OnStart 和 OnStop 方法的类添加一个方法:

internal void TestStartupAndStop(string[] args)  
{  
    this.OnStart(args);  
    Console.ReadLine();  
    this.OnStop();  
}  

(2)按如下所示重写 Main 方法:

static void Main(string[] args)  
{  
    if (Environment.UserInteractive)  
    {  
        MyNewService service1 = new MyNewService(args);  
        service1.TestStartupAndStop(args);  
    }  
    else  
    {  
        // Put the body of your old Main method here.  
    }  
}

(3)在项目属性的“应用程序” 选项卡中,将“输出类型” 设置为“控制台应用程序” 。

(4)选择“启动调试” (F5)。

(5)若要将该程序再次作为 Windows 服务运行,请安装它并像通常启动 Windows 服务一样启动它。 不必恢复这些更改。

在某些情况下,你必须使用 Windows 调试器,比如当你想要调试仅在系统启动时发生的问题时。

 

3.新建窗体项目,创建可视化服务管理界面

查看代码
#region
        
        const string serviceName = "HzService";
        string serviceFilePath = Application.StartupPath + "\\Hz_WindowsService.exe";

        //事件:安装服务

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.IsServiceExisted(serviceName))
                {
                    this.UninstallService(serviceName);
                }
                this.InstallService(serviceFilePath);

                Thread.Sleep(200);
                MessageBox.Show("服务安装成功。", "提示");
            }
            catch (Exception e1)
            {
                MessageBox.Show("出错!" + e1.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        //事件:启动服务

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.IsServiceExisted(serviceName))
                {
                    this.ServiceStart(serviceName);
                    MessageBox.Show("服务启动成功。", "提示");
                    btnStart.Enabled = false;
                    btnStop.Enabled = true;
                }
                else
                {
                    MessageBox.Show("服务不存在。", "提示");
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show("出错!" + e1.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        //事件:停止服务

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.IsServiceExisted(serviceName))
                {
                    this.ServiceStop(serviceName);
                    MessageBox.Show("服务停止成功。", "提示");
                    btnStart.Enabled = true;
                    btnStop.Enabled = false;
                }
                else
                {
                    MessageBox.Show("服务不存在。", "提示");
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show("出错!" + e1.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        //事件:卸载服务

        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.IsServiceExisted(serviceName))
                {
                    this.ServiceStop(serviceName);
                    this.UninstallService(serviceFilePath);
                    MessageBox.Show("服务卸载成功。", "提示");
                }
                else
                {
                    MessageBox.Show("服务不存在。", "提示");
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show("出错!" + e1.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        //判断服务是否存在

        private bool IsServiceExisted(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController sc in services)
            {
                if (sc.ServiceName.ToLower() == serviceName.ToLower())
                {
                    return true;
                }
            }
            return false;
        }

        //安装服务

        private void InstallService(string serviceFilePath)
        {
            using (AssemblyInstaller installer = new AssemblyInstaller())
            {
                installer.UseNewContext = true;
                installer.Path = serviceFilePath;
                IDictionary savedState = new Hashtable();
                installer.Install(savedState);
                installer.Commit(savedState);
            }
        }

        //卸载服务

        private void UninstallService(string serviceFilePath)
        {
            using (AssemblyInstaller installer = new AssemblyInstaller())
            {
                installer.UseNewContext = true;
                installer.Path = serviceFilePath;
                installer.Uninstall(null);
            }
        }

        //启动服务

        private void ServiceStart(string serviceName)
        {
            using (ServiceController control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Stopped)
                {
                    control.Start();
                }
            }
        }

        //停止服务

        private void ServiceStop(string serviceName)
        {
            using (ServiceController control = new ServiceController(serviceName))
            {
                if (control.Status == ServiceControllerStatus.Running)
                {
                    control.Stop();
                }
            }
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            btnFlush_Click(null, null);           
        }

        private void btnFlush_Click(object sender, EventArgs e)
        {
            try
            {
                this.btnStart.Enabled = false;
                this.btnStop.Enabled = false;
                ServiceController sc = new ServiceController(serviceName);
                switch (sc.Status)
                {
                    case ServiceControllerStatus.Running:
                        this.btnStop.Enabled = true;
                        break;
                    case ServiceControllerStatus.Stopped:
                        this.btnStart.Enabled = true;
                        break;
                }
            }
            catch (Exception e1)
            {
                MessageBox.Show("出错!" + e1.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

补充:如未进行以下步骤,则运行“服务管理程序”进行相关操作时,需要右键管理员权限打开。

由于需要安装服务,故需要使用UAC中Administrator的权限,鼠标右击项目,添加新项“应用程序清单文件,如下图所示:

打开该文件,并将<requestedExecutionLevel level="asInvoker" uiAccess="false" />改为<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />,如下图所示:

 

4.遇到的问题

问题:当服务无法停止时。

解决方案:

管理员打开命令行窗口,运行 sc queryex 命令来获取服务的 PID(也可以右键任务管理器,在服务页找到该服务对应PID),接着使用 taskkill 命令来停止它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
C:\>sc queryex PlatformMessageService
 
SERVICE_NAME: PlatformMessageService
TYPE               : 10  WIN32_OWN_PROCESS
STATE              : 2  START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN))
 
WIN32_EXIT_CODE    : 0  (0x0)
SERVICE_EXIT_CODE  : 0  (0x0)
CHECKPOINT         : 0x1
WAIT_HINT          : 0xbb8
PID                : 524
FLAGS              :
 
C:\>taskkill /PID 524 /F
SUCCESS: The process with PID 3756 has been terminated.<br><br><br>

 

posted @ 2023-07-31 10:16  茜茜87  阅读(1)  评论(0编辑  收藏  举报