windows 服务程序和桌面程序集成(六)集成安装、启动、卸载功能

news2024/9/29 9:36:25

 

系列文章目录链接:

  1. windows 服务程序和桌面程序集成(一)概念介绍
  2. windows 服务程序和桌面程序集成(二)服务程序
  3. windows 服务程序和桌面程序集成(三)UDP监控工具
  4. windows 服务程序和桌面程序集成(四)桌面程序
  5. windows 服务程序和桌面程序集成(五)集成为一个EXE
  6. windows 服务程序和桌面程序集成(六)集成安装、启动、卸载功能
  7. windows 服务程序和桌面程序集成(七)效果演示及源程序下载
     

把windows服务程序的安装、启动等功能集成到自身的桌面程序上,需要引入单元uszhnServiceUtils.pas。

 该单元包括如下函数:

unit uszhnServiceUtils;

interface

uses
  WinApi.Windows, WinApi.Messages, System.SysUtils, WinApi.Winsvc, VCL.Dialogs,
  vcl.ExtCtrls,
  system.Classes,

  System.Win.Registry;

type
  TServiceState = (ssUnKnow, ssTimeOut, ssRuning{运行中},
  	ssWait{等待},
    ssStop{停止},
    ssUnInstall{未安装},
    ssPause{暂停});


//启动服务
function StartServices(const SvrName: string): Boolean;

function Always_StartServices(const SvrName: string; var ErrorMsg: String): Boolean;
//SvrName服务名;下同

//停止服务
function StopServices(const SvrName: string): Boolean;
///<summary>一直停,直到服务停下为止<sammary>
function Always_StopServices(const SvrName: string; var ErrorMsg: String): Boolean;

//查询服务状态;返回状态类型
function QueryServiceState(const SvrName: string): TServiceState;
///<summary>持续询问<sammary>
function Always_QueryServiceState(const SvrName: string; const tgtState: TServiceState;  TimeOut: Integer = 5*60*1000): TServiceState;



//注册服务
///<summary>建立一个服务</summary>
function CreateServices(const SvrName, FilePath: string): Boolean;
///<summary>建立一个服务;并且有服务描述</summary>
function CreateServiceWithDesc(const SvrName, FilePath, SrvDesc: string): Boolean;


function AddServiceDesc(const SvrName, SrvDesc: String): Boolean;
//服务名,FilePath: 服务路径

//卸载服务
function DeleteServices(const SvrName: string): Boolean;
//服务名


procedure GetServiceNames(Names: TStrings; DisplayNames: TStrings = nil;
  const Service_Type: integer = $30; const Computer: PChar = nil);

我们在桌面程序界面上增加如下按键:安装服务、启动服务、停止服务、卸载服务。

 uMainForm_Application.pas单元代码如下:

unit uMainForm_Application;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  system.DateUtils,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm_Application = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Panel1: TPanel;
    Label1: TLabel;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    Button8: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form_Application: TForm_Application;

implementation

uses
  uWorkerThread, uszhnServiceUtils;

{$R *.dfm}

procedure TForm_Application.Button1Click(Sender: TObject);
begin
   //创建工作线程
  if WorkThread = nil then
     WorkThread := TWorkThread.Create;
  WorkThread.FreeOnTerminate := True;    //完成后直接释放
end;

procedure TForm_Application.Button2Click(Sender: TObject);
begin
  WorkThread.Pause;
end;

procedure TForm_Application.Button3Click(Sender: TObject);
begin
  WorkThread.Continue;
end;

procedure TForm_Application.Button4Click(Sender: TObject);
begin
  WorkThread.Terminate;
  while not WorkThread.Finished do
    begin
      Sleep(200);
    end;
  WorkThread := nil;
end;

procedure TForm_Application.Button5Click(Sender: TObject);
begin
  if CreateServices('Service1', ParamStr(0)) then
    begin
      Memo1.Lines.Add('服务安装成功: Service1');
    end
  else
    begin
       Memo1.Lines.Add('服务安装失败: Service1   xxxxx');
    end;
end;

procedure TForm_Application.Button6Click(Sender: TObject);
var
  T : TDateTime;
  FServiceState : TServiceState;
begin
  if StartServices('Service1') then
    begin
      FServiceState := QueryServiceState('Service1');
      T := IncSecond(Now,10);
      while FServiceState <> ssRuning do
        begin
          if Now > T then
            begin
              Memo1.Lines.Add('服务: Service1 启动失败!(Service), 超时未启动(10秒)');
              Exit;
            end;
          Application.ProcessMessages;
          Sleep(200);
          FServiceState := QueryServiceState('Service1');
        end;

      Memo1.Lines.Add('   ----------------------------------------------');
      Memo1.Lines.Add('   |  启动服务成功: Service1' );
      Memo1.Lines.Add('   ----------------------------------------------');
    end
  else
    begin
       Memo1.Lines.Add('*********************************************************');
       Memo1.Lines.Add('*                  Service  服务启动失败                *');
       Memo1.Lines.Add('* ServiceName: Service1 (服务启动后名称)');
       Memo1.Lines.Add('*********************************************************');
    end;
end;


procedure TForm_Application.Button7Click(Sender: TObject);
var
  FServiceState : TServiceState;
begin
  if StopServices('Service1') then
    begin
      FServiceState := QueryServiceState('Service1');
      while FServiceState <> ssStop do
       begin
         Application.ProcessMessages;
         Sleep(100);
         FServiceState := QueryServiceState('Service1');
       end;
      Memo1.Lines.Add('   ----------------------------------------------');
      Memo1.Lines.Add('   |  停止服务成功: Service1' );
      Memo1.Lines.Add('   ----------------------------------------------');
    end
  else
    begin
       Memo1.Lines.Add('*********************************************************');
       Memo1.Lines.Add('*                  Service  服务停止失败                *');
       Memo1.Lines.Add('* ServiceName: Service1 (服务启动后名称)');
       Memo1.Lines.Add('*********************************************************');
    end;
end;

procedure TForm_Application.Button8Click(Sender: TObject);
var
  FServiceState : TServiceState;
begin
  if DeleteServices('Service1') then
    begin
      FServiceState := QueryServiceState('Service1');
      while FServiceState <> ssUnInstall do
        begin
           FServiceState := QueryServiceState('Service1');
           Application.ProcessMessages;
        end;

      Memo1.Lines.Add('服务卸载成功: Service1');
    end
  else
    begin
       Memo1.Lines.Add('服务卸载失败: Service1');
    end;

end;

end.

经过以上步骤,就彻底实现了双模程序,及实现了windows服务程序的完美调试,也实现了在程序自身完成服务的安装、启动、停止、卸载等功能。

本系列文章完整程序目录:

下一篇:windows 服务程序和桌面程序集成(七)效果演示及源程序下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/636758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AntDesign——TableAPI学习

table表格用于展示数据 https://ant.design/components/table-cn#table 1.bordered false不显示每一个小表格的边框&#xff0c;true反之 2.columns 列名及列数据&#xff0c;接受columns数组 2.1 colums中必须声明的属性 title&#xff08;列标题&#xff09; dataInde…

为什么会被扣小红书品牌违规分,原因是什么

小红书在2022年经过一次较大点的规则变动&#xff0c;其中小红书品牌违规分就是其中亮点名词之一。很多人对此都不甚了解&#xff0c;今天为大家分享下为什么会被扣小红书品牌违规分&#xff0c;原因是什么&#xff1f; 一、什么是品牌违规分 品牌违规分是小红书在2022年4月20日…

工厂模式~

核心本质 ① 实例化对象不使用new&#xff0c;用工厂方法代替 ② 将选择实现类&#xff0c;创建对象统一管理和控制&#xff0c;从而将调用者跟我们的实现类解耦 简单工厂 public interface Car {void name(); }public class Tesla implements Car{Overridepublic void name()…

基于 opencv 的人脸识别上课考勤系统,附源码,可作为毕业设计

一、简介 这个人脸识别考勤签到系统是基于大佬的人脸识别陌生人报警系统二次开发的。 项目使用Python实现&#xff0c;基于OpenCV框架进行人脸识别和摄像头硬件调用&#xff0c;同时也用OpenCV工具包处理图片。交互界面使用pyqt5实现。 该系统实现了从学生信息输入、人脸数据…

ps复制图层警告 (不能从选区建立新图层,因为所选区域是空的。)解决方法

有时我们选完选区 按 CtrlJ 复制图层 会出现这种情况 问题出在你当前选的图层 因为 我选择的这块选区在第二个图层上 但很明显 选择的是一大个图层 简单说 你操作的选区必须在你当前选择的图层上才行 也就是 我现在要将选择区换成第二个图层才行 再按 CtrlJ 图层就出来了

AssetStudio工程导入VS各种报错解决

AssetStudio下载地址&#xff1a;https://github.com/Perfare/AssetStudio 工程导入&#xff0c;生成解决方案&#xff0c;然后报了一堆错。让我们来一个一个的解决 这个错误&#xff0c;是缺少System.Runtime.InteropServices.RuntimeInformation.dll文件&#xff0c;下载并添…

“爱心助考 为梦护航”雷锋志愿者在行动

为确保我市高考、学考工作顺利进行&#xff0c;为考生营造安全温馨的考试环境保驾护航&#xff0c;共青团怀化市委、市教育局、共青团鹤城区委、区教育局联合怀化市青少年关爱协会党支部&#xff0c;开展2023“爱心助考 为梦护航”雷锋志愿者服务活动。 6月7-9日高考三天&#…

开发新项目看过来,这3款基于 Vue 的免费开源的 admin 管理后台框架非常好用

三款 admin 框架&#xff0c;分别基于热门的前端 UI 组件库 ElementPlus / Ant Design / Naive UI 打造&#xff0c;开箱即用。 新项目的开始&#xff0c;一般是搭建 admin 系统&#xff0c;今天盘点一下3个好的选择。 Vue vben admin 了解详细&#xff1a;https://www.thos…

C型标准气动阀线圈插头安装距8mm

8mm针脚距气动阀插头、C型DIN标准电气插头。这些插头通常用于工业自动化、机械控制等领域。 工业标准&#xff0c;C型&#xff0c;DIN43650 / EN175301-803,插针中心距 8mm、3针脚、4针脚&#xff0c;额定电压 250V,工作电流 6A,最大接线 0.75mm2,电缆锁紧口 PG7,电缆外径 4-6…

Beyond Compare 4 无法打开

解决办法&#xff1a; 1.修改注册表。WINR呼出开始菜单&#xff0c;在搜索栏中输入 regedit&#xff0c;点击确定。 2.删除项目&#xff1a;\HKEY_CURRENT_USER\Software\ScooterSoftware\Beyond Compare 4\CacheId 根据这个路径找到cacheid 右击删除掉就可以

Allegro Design Entry CIS导出原理图BOM方法

1.Allegro Design Entry CIS导出原理图BOM方法 Tools->Bill of Materials 填入项分别为&#xff1a; Header:项次\t名称\t位号\t值\t封装\t数量 Combined property string: {Item}\t{PartName}\t{Reference}\t{Value}\t{PCB footprint}\t{Quantity} 点击OK生成如下表格

服务架构的进化之路:探索服务架构的演进之路

1、引言 服务架构是一种以服务为中心的软件设计模式&#xff0c;将应用程序拆分为一组小而自治的服务单元。随着互联网和信息技术的快速发展&#xff0c;软件系统变得越来越复杂。为了应对这种变化&#xff0c;服务架构也在不断地演变和发展。本文将简要介绍服务架构的发展史&…

基于BG/NBD概率模型的用户CLV预测

基于BG/NBD概率模型的用户CLV预测 小P&#xff1a;小H&#xff0c;我们最近想预测下用户的生命周期价值&#xff0c;有没有什么好的方法啊&#xff1f; 小H&#xff1a;简单啊&#xff0c; C L V 用户每月平均花费 ∗ 用户平均寿命 CLV用户每月平均花费*用户平均寿命 CLV用户每…

Masked Autoencoders As Spatiotemporal Learners

Masked Autoencoders As Spatiotemporal Learners 文章目录 Masked Autoencoders As Spatiotemporal Learners一、文章背景二、文章变量1 mask sampling 方式2 Mask ratio3 其余的ablation studies 一、文章背景 用于视频中的时间信息学习。 基本思想是重构&#xff0c;使用的…

bilibili记录

霹雳吧啦Wz的个人空间-霹雳吧啦Wz个人主页-哔哩哔哩视频 目标检测篇github地址&#xff1b;GitHub - WZMIAOMIAO/deep-learning-for-image-processing: deep learning for image processing including classification and object-detection etc.

mapbox分屏地图同步缩放拖拽旋转

成果图 之前写过一版&#xff0c;后来又经过一些优化&#xff0c;形成了现在的最终版本&#xff0c;之前是二维的&#xff0c;现在是三维的也可以了&#xff0c;地址在这儿 https://blog.csdn.net/Sakura1998gis/article/details/113175905 实现 监听动作 // 拖拽同步map.on(d…

pm3包1.8版本发布----一个用于3组倾向性评分的R包

目前&#xff0c;本人写的第二个R包pm3包的1.8版本已经正式在CRAN上线&#xff0c;用于3组倾向评分匹配&#xff0c;只能3组不能多也不能少。 可以使用以下代码安装 install.packages("pm3")什么是倾向性评分匹配&#xff1f;倾向评分匹配&#xff08;Propensity Sc…

经常被问道的这些类,佬们能够吊打面试官嘛(适合秋招和小白系列)?

前言&#xff1a; 本篇文章主要讲解Java中的几个类常被问到的面试题相关知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。 如果文章有什么需要改进的地方欢迎大佬提出&#xff0c;对大佬有帮助希望可以支持下哦~ 小威在此先感谢各位小伙伴儿了&#x1f601; 以…

宏病毒组研究大放异彩!| 凌恩生物1-5月高分宏病毒组文章大盘点!

凌恩生物现已在宏组学、基因组、表观遗传以及蛋白代谢等多组学及联合分析领域积累了深厚经验&#xff0c;打造出成熟的科研服务平台&#xff0c;以优质售前方案和优秀售后服务助力客户在Nature、Science、PNAS、ISME和MIcrobiome等高端国际期刊上发表了大量文章。 伴随着组学技…

【DevOps】Python+Golang(一)

Python is和的区别 is检查两个对象是否是同一个对象&#xff0c;即它们的内存地址是否相同。如果是同一个对象&#xff0c;则返回True&#xff0c;否则返回False。 检查两个对象是否相等&#xff0c;即它们的值是否相同。如果值相同&#xff0c;则返回True&#xff0c;否则返回…