编写服务程序

编写服务程序会用到这些函数:
*服务主函数
ServiceMain()
StartServiceCtrlDispatcher() //dispatcher n. 调度员;[计] 调度程序;[计] 分配器

*服务控制处理函数
ServiceCtrlHandle()
RegisterServiceCtrlHandle()

首先创建一个win32的空项目,然后添加源文件,编写代码

# include<stdio.h>
# include<stdlib.h>
# include<Windows.h>

# define FILE_PATH "e:\\log.txt"
# define SLEEP_TIME 5000  

void ServiceMain(int argc, char **argv);//服务主函数
void WINAPI ServiceCtrlHandler(DWORD Opcode);//服务控制函数
SERVICE_STATUS m_ServiceStatus;//服务状态
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;//服务状态句柄
int WriteToLog(char *str);

BOOL bRunning = TRUE;

int main()      //服务程序入口也是main
{
    SERVICE_TABLE_ENTRY DispatchTable[2];   //服务分派表
    //要用到此结构
    DispatchTable[0].lpServiceName = TEXT("服务名称");
    DispatchTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

    DispatchTable[1].lpServiceName = NULL;//数组最后一项一定要设为NULL(表示结束),这里只是简单的
    //做一个例子,所以数组大小为2,一个程序可以有多个服务
    DispatchTable[1].lpServiceProc = NULL;

    //1:注册服务的主函数
    StartServiceCtrlDispatcher(DispatchTable);
       //服务控制分派器
       //调用该函数,就会使用分派表里的主函数创建一个新的线程

    system("pause");
    return 0;
}

void ServiceMain(int argc, char **argv)
{
    MEMORYSTATUS memstatus;
    char str[100];
    int availmb;//内存大小转换成以兆为单位的

    //=========================1 设置服务状态=============================
    m_ServiceStatus.dwServiceType = SERVICE_WIN32;

    //服务当前状态
    m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;//panding 待定,未发生的,挂起
    //因为服务还未做好,正在初始化,所以当前的状态待定

    //服务可接受的控制
    m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;

    //这两个跟服务退出有关,都设为0
    m_ServiceStatus.dwWin32ExitCode = 0;
    m_ServiceStatus.dwWin32ExitCode = 0;

    //这两个一般都设为0,很少用到,如果服务启动时间超过了30秒,就需要改变这些参数了
    m_ServiceStatus.dwCheckPoint = 0;
    m_ServiceStatus.dwWaitHint = 0;//hint 暗示,提示

    //===========================1 注册服务=================================
    //注册服务控制函数
    m_ServiceStatusHandle=RegisterServiceCtrlHandler(TEXT("服务名称"), ServiceCtrlHandler);
    if (m_ServiceStatusHandle == 0)//注册失败
    {
        //失败就写入日志
        WriteToLog("RegisterServiceCtrlHandler failed");
        return;
    }

    WriteToLog("RegisterServiceCtrlHandler success");
    m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;//注册后就运行了

    //将服务状态报告给服务控制器
    SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
    bRunning = TRUE;
    //这个服务程序的例子就用来检查电脑内存大小吧

    memset(&memstatus,'\0',100);

    while (bRunning)
    {
        GlobalMemoryStatus(&memstatus);//检查电脑内存
        availmb = memstatus.dwAvailPhys / 1024 / 1024;
        sprintf_s(str, 100,"Available memory is %dMB", availmb);
        WriteToLog(str);

        //计算机运算速度太快,让每5秒钟就循环一次
        Sleep(SLEEP_TIME);
    }
    WriteToLog("service stopped");
}   

//当我们做好一个服务程序后,服务程序就会安装,可以在服务控制面板里找到,比如停止,启用服务等都是在
//服务控制函数里进行的
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
    switch (Opcode)
    {
    case SERVICE_CONTROL_STOP://停止服务
        bRunning = FALSE;
        m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        break;
    case SERVICE_CONTROL_SHUTDOWN://电脑关机
        bRunning = FALSE;
        m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        break;
    default:
        break;
    }
    SetServiceStatus(m_ServiceStatusHandle,&m_ServiceStatus);
}

int WriteToLog(char *str)
{
    FILE *pfile;
    fopen_s(&pfile, FILE_PATH, "a+");
    if (pfile == NULL)
        return -1;
    fprintf_s(pfile, "%s\n", str);
    fclose(pfile);
    return 0;
}

然后生成解决方案,为了后来使用cmd敲路径比较方便,把生成的.exe文件复制到c盘的test文件夹下吧,
这里写图片描述
这里我编写的服务名字是”服务名称”,然后安装服务,如果现在直接去看(右击计算机-管理-计算机管理(本地)-双击服务)的话,
这里写图片描述
是看不到的,这里可以用sc.exe工具去完成
按下Win+R键,输入cmd,回车,然后输入sc,回车,然后输入:
sc create 服务名称 binpath= c:\test\编写服务程序.exe
create表示根据自己写的服务程序创建一个服务,第三个是服务的名字,注意binpath和等于号之间有空格,后面就是解决方案生成的.exe文件所在路径了
然后再去查看,注意要 操作-刷新
这里写图片描述

这里要注意一点, !!可能会提示失败,访问权限不足,可以右击计算机-管理-计算机管理(本地)-系统工具-本地用户和组-用户-双击Administrator,将账户已禁用的勾去掉,重启就可以了,或者去注册表改也行,具体可以自己去搜

  //安装后,在服务里刷新一下就可以看到编写的服务了
  sc start 服务名称      //启用服务
  sc delete 服务名称     //删除服务 

这里写图片描述
这里实例的服务程序是用来检查可用运行内存大小的,将结果写入日志(文本文件),启用服务后,每五秒就循环检查一次并写入日志,这里是在e盘,
启用服务:这里写图片描述
这里写图片描述
这里写图片描述
关闭该文本,再打开

这里写图片描述
关闭服务
这里写图片描述
删除服务的话只有用sc了,
这里写图片描述
这里删除不了,输入sc delete 服务名称
回车就可以删除了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Qt中编写服务程序需要使用Qt Service Framework。Qt Service Framework是一个用于编写跨平台服务程序的框架,它提供了一个抽象的服务接口,并且可以让你方便地实现自己的服务。 下面是一个简单的步骤: 1. 创建一个Qt应用程序项目 2. 在main函数中使用QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);启用高分辨率缩放 3. 创建一个继承自QService服务,并实现它的虚函数 4. 在main函数中创建一个QServiceApplication对象,并将服务实例化后传入构造函数 5. 调用QServiceApplication的exec()函数启动服务 以下是一个简单的示例代码: ```cpp #include <QtCore/QCoreApplication> #include <QtCore/QDebug> #include <QtCore/QServiceApplication> #include <QtCore/QServiceManager> #include <QtCore/QServicePluginInterface> class MyService : public QService { public: MyService(const QString &name, QObject *parent = nullptr) : QService(name, parent) {} protected: void start() override { qDebug() << "MyService started"; } void stop() override { qDebug() << "MyService stopped"; } }; class MyServicePlugin : public QObject, public QServicePluginInterface { Q_OBJECT Q_PLUGIN_METADATA(IID QServicePluginInterface_iid) Q_INTERFACES(QServicePluginInterface) public: QService *create(const QString &key) override { if (key == "MyService") return new MyService(key); else return nullptr; } }; int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication app(argc, argv); QServiceApplication serviceApp(argc, argv); serviceApp.addPlugin(new MyServicePlugin); serviceApp.exec(); return app.exec(); } #include "main.moc" ``` 这个示例程序中创建了一个名为"MyService"的服务,它在启动时输出"MyService started",在停止时输出"MyService stopped"。这个服务通过MyServicePlugin插件注册到了服务管理器中。在main函数中创建了一个QServiceApplication对象,并将MyServicePlugin插件实例添加到了它的插件列表中,然后调用了exec()函数启动服务

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值