随笔-379  评论-37  文章-0  trackbacks-0
1、源代码

//服务器状态切换响应函数
void WINAPI ServiceHandler(DWORD fdwControl)
{
    FILE* log = NULL;
    switch (fdwControl)
    {
    case SERVICE_CONTROL_STOP:
    case SERVICE_CONTROL_SHUTDOWN:
        ServiceStatus.dwWin32ExitCode = 0;
        ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        ServiceStatus.dwCheckPoint = 0;
        ServiceStatus.dwWaitHint = 0;
        //add you quit code here
        log = fopen("D:\\log.txt", "a+");
        if (log)
        {
            fprintf(log, "ServiceHandler: %s\n", "service stop");
            fclose(log);
        }
        break;
    default:
        return;
    };
    if (!SetServiceStatus(hServiceStatusHandle, &ServiceStatus))
    {
        DWORD nError = GetLastError();
    }
}

//自定义工作线程回调函数,服务器启动前,调试附加进程->选择服务进程名称,并在此函数中加断点
void MyFunction()
{
    FILE* fp = fopen("D:\\log.txt", "a+");
    if (fp)
    {
        fputs("\n", fp);
        fputs("work thread start!", fp);
        fputs("\n", fp);
        fclose(fp);
    }
     while(true)
    {
         Sleep(1);
    }
}

//启动服务响应函数
void WINAPI service_main(int argc, char** argv)
{
    ServiceStatus.dwServiceType = SERVICE_WIN32;
    ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
    ServiceStatus.dwWin32ExitCode = 0;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwCheckPoint = 0;
    ServiceStatus.dwWaitHint = 0;
    hServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceHandler);
    if (hServiceStatusHandle == 0)
    {
        DWORD nError = GetLastError();
    }
    std::cout << "my service start!" << std::endl;
    //add your init code here
    FILE* log = fopen("D:\\log.txt", "a+");
    for (int i = 0; i < argc; ++i)
    {
        fprintf(log, "service_main: %s\n", argv[i]);
    }
    fclose(log);
    //add your service thread here
    std::thread wnd_thread(MyFunction);
    wnd_thread.detach();
    // Initialization complete - report running status 
    ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    ServiceStatus.dwCheckPoint = 0;
    ServiceStatus.dwWaitHint = 9000;
    if (!SetServiceStatus(hServiceStatusHandle, &ServiceStatus))
    {
        DWORD nError = GetLastError();
    }
}

int main(int argc, const char* argv[])
{
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = (LPSTR)SERVICE_NAME;
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)service_main;
    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;
    // 启动服务的控制分派机线程
    StartServiceCtrlDispatcher(ServiceTable);
    return 0;
}

2、创建服务
打开控制台,输入命令:
sc create ServiceTest binPath= "编译生成的可执行文件绝对路径及文件名"
例如,上面示例程序编译输出路径及生成可执行文件名为:
D:\Test\ServiceTest\Debug\ServiceTest.exe
则,控制台输入命令为:
sc create ServiceTest binPath= "D:\Test\ServiceTest\Debug\ServiceTest.exe"

3、启动服务
(如果需要调试的话,此时附加调试进程ServiceTest,并在自定义工作线程回调函数中加断点)
控制台中输入命令:
sc start ServiceTest

4、关闭服务
sc stop ServiceTest

5、删除服务
sc delete ServiceTest

O了!
posted on 2022-04-09 01:10 小王 阅读(142) 评论(0)  编辑 收藏 引用 所属分类: VCWin32

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理