刘总的笔记小站

生活常识,娱乐搞笑,编程技巧,智能家居,深度学习,网络神经,数据挖掘

win系统安装一个服务并且支持启动停止

// "C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat"
// "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
// g++ -O2 -std=c++11 lock.cpp
// cl.exe /O2 /std:c++11 lock.cpp
// cl.exe /O2 /std:c++14 stream.cpp

#include <iostream> // iostream istream ostream | wxxx
#include <fstream>  // fstream ifstream ofstream | wxxx
#include <sstream>  // stringstream istringstream ostringstream | wxxx
#include <string>
#include <ctime>

// #include <cstddef>
// #include <cstring>

#include <windows.h>
#include <tchar.h>

using namespace std;


#pragma comment(lib, "advapi32.lib")

#define SVCNAME TEXT("aboycando")
#define szSvcName TEXT("aboycando")

SERVICE_STATUS gSvcStatus;
SERVICE_STATUS_HANDLE gSvcStatusHandle;
HANDLE ghSvcStopEvent = NULL;

VOID SvcInstall();
BOOL DoQuerySvc();
BOOL DoCheckSvc();
VOID DoDeleteSvc();
VOID WINAPI SvcMain(DWORD, LPTSTR *);

bool logFile(string fileName, string fileText, int mode) {
    //fstream oftextStream(fileName.c_str(), mode); // ofstream::out ofstream::app
    fstream oftextStream(fileName.c_str(), (ios_base::openmode)mode);
    if (oftextStream){
        // char mbstr[64] = {'\0'};
        time_t timer = time(NULL); // ctime(&timer);// unsafe and endeith newline
        // std::strftime(mbstr, sizeof(mbstr), " %F %a %T", std::localtime(&timer));
        string strstext = ctime(&timer);
		strstext.assign(strstext, 0, strstext.size() - 1);
		strstext = strstext + " " + fileName + " " + fileText + "\n";
        oftextStream << strstext;
        // oftextStream << mbstr << " " << fileText.c_str() << endl;
        oftextStream.close();
    }
    return true;
}

int main(int argc, char *argv[]){
    logFile("aboycando.txt", "main call", fstream::out);
    
    while(argc--)
        logFile("aboycando.txt", "main argv=" + string(argv[argc]), fstream::app);
    
    if( (argv[0][0] == '.') && DoQuerySvc() ) { // DoCheckSvc() service exist difexe || if run stop
        logFile("aboycando.txt", "main DoDeleteSvc", fstream::app);
        DoDeleteSvc();
        return 1;
    }
    
    if(!DoQuerySvc()) { // service not exist
        logFile("aboycando.txt", "main SvcInstall", fstream::app);
        SvcInstall();
    } else { // service exist right
        logFile("aboycando.txt", "main DoStartSvc", fstream::app);
        SERVICE_TABLE_ENTRY DispatchTable[] = {
            { SVCNAME, (LPSERVICE_MAIN_FUNCTION) SvcMain },
            { NULL, NULL }
        };
        
        if (FALSE == StartServiceCtrlDispatcher( DispatchTable )) {
            logFile("aboycando.txt", "main StartServiceCtrlDispatcher FALSE", fstream::app);
        }
    }

    logFile("aboycando.txt", "main exit", fstream::app);
    
    return 0;
}




VOID SvcInstall()
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    TCHAR szPath[MAX_PATH];
    
    printf("SvcInstall exit\n");
    
    if (!GetModuleFileName(NULL, szPath, MAX_PATH)) {
        printf("SvcInstall Cannot install service (%d)\n", GetLastError());
        return;
    }

    // Get a handle to the SCM database.
    schSCManager = OpenSCManager(
        NULL,                   // local computer
        NULL,                   // ServicesActive database
        SC_MANAGER_ALL_ACCESS); // full access rights

    if (NULL == schSCManager) {
        printf("SvcInstall OpenSCManager failed (%d)\n", GetLastError());
        return;
    }

    // Create the service
    schService = CreateService(
        schSCManager,              // SCM database
        SVCNAME,                   // name of service
        SVCNAME,                   // service name to display
        SERVICE_ALL_ACCESS,        // desired access
        SERVICE_WIN32_OWN_PROCESS, // service type
        SERVICE_AUTO_START,        // start type // SERVICE_AUTO_START SERVICE_DEMAND_START
        SERVICE_ERROR_NORMAL,      // error control type
        szPath,                    // path to service's binary
        NULL,                      // no load ordering group
        NULL,                      // no tag identifier
        NULL,                      // no dependencies
        NULL,                      // LocalSystem account
        NULL);                     // no password

    SERVICE_DESCRIPTION sdBuf;
    sdBuf.lpDescription = _T("SERVICE_CONFIG_DESCRIPTION");
    ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdBuf);

    if (schService == NULL) {
        printf("SvcInstall CreateService failed (%d)\n", GetLastError());
        CloseServiceHandle(schSCManager);
        return;
    }
    else
        printf("SvcInstall Service installed successfully\n");

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);

    printf("SvcInstall SvcInstall exit\n");
}

BOOL DoQuerySvc()
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    LPQUERY_SERVICE_CONFIG lpsc;
    LPSERVICE_DESCRIPTION lpsd;
    DWORD dwBytesNeeded, cbBufSize, dwError;
    BOOL reCode = FALSE;
    
    printf("DoQuerySvc DoQuerySvc init\n");
    
    // Get a handle to the SCM database.
    schSCManager = OpenSCManager(
        NULL,                   // local computer
        NULL,                   // ServicesActive database
        SC_MANAGER_ALL_ACCESS); // full access rights

    if (NULL == schSCManager) {
        printf("DoQuerySvc OpenSCManager failed (%d)\n", GetLastError());
        return reCode;
    }

    // Get a handle to the service.

    schService = OpenService(
        schSCManager,          // SCM database
        szSvcName,             // name of service
        SERVICE_QUERY_CONFIG); // need query config access

    if (schService == NULL) {
        printf("DoQuerySvc OpenService failed (%d)\n", GetLastError());
        CloseServiceHandle(schSCManager);
        return reCode;
    }

    // Get the configuration information.

    if (!QueryServiceConfig( schService, NULL, 0, &dwBytesNeeded)) {
        dwError = GetLastError();
        if (ERROR_INSUFFICIENT_BUFFER == dwError) {
            cbBufSize = dwBytesNeeded;
            lpsc = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, cbBufSize);
        } else {
            printf("DoQuerySvc QueryServiceConfig failed (%d)", dwError);
            goto cleanup;
        }
    }

    if (!QueryServiceConfig( schService, lpsc, cbBufSize, &dwBytesNeeded)) {
        printf("DoQuerySvc QueryServiceConfig failed (%d)", GetLastError());
        goto cleanup;
    }

    if (!QueryServiceConfig2(
            schService,
            SERVICE_CONFIG_DESCRIPTION,
            NULL,
            0,
            &dwBytesNeeded))
    {
        dwError = GetLastError();
        if (ERROR_INSUFFICIENT_BUFFER == dwError) {
            cbBufSize = dwBytesNeeded;
            lpsd = (LPSERVICE_DESCRIPTION)LocalAlloc(LMEM_FIXED, cbBufSize);
        } else {
            printf("DoQuerySvc QueryServiceConfig2 failed (%d)", dwError);
            goto cleanup;
        }
    }

    if (!QueryServiceConfig2(
            schService,
            SERVICE_CONFIG_DESCRIPTION,
            (LPBYTE)lpsd,
            cbBufSize,
            &dwBytesNeeded))
    {
        printf("DoQuerySvc QueryServiceConfig2 failed (%d)", GetLastError());
        goto cleanup;
    }

    // Print the configuration information.

    _tprintf(TEXT("%s configuration: \n"), szSvcName);
    _tprintf(TEXT("  Type: 0x%x\n"), lpsc->dwServiceType);
    _tprintf(TEXT("  Start Type: 0x%x\n"), lpsc->dwStartType);
    _tprintf(TEXT("  Error Control: 0x%x\n"), lpsc->dwErrorControl);
    _tprintf(TEXT("  Binary path: %s\n"), lpsc->lpBinaryPathName);
    _tprintf(TEXT("  Account: %s\n"), lpsc->lpServiceStartName);

    if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0)
        _tprintf(TEXT("  Description: %s\n"), lpsd->lpDescription);
    if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, TEXT("")) != 0)
        _tprintf(TEXT("  Load order group: %s\n"), lpsc->lpLoadOrderGroup);
    if (lpsc->dwTagId != 0)
        _tprintf(TEXT("  Tag ID: %d\n"), lpsc->dwTagId);
    if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)
        _tprintf(TEXT("  Dependencies: %s\n"), lpsc->lpDependencies);

    LocalFree(lpsc);
    LocalFree(lpsd);
    reCode = TRUE;
    
cleanup:
    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);

    printf("DoQuerySvc DoQuerySvc exit\n");
    return reCode;
}

VOID DoDeleteSvc()
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    SERVICE_STATUS ssStatus;

    printf("DoDeleteSvc init\n");

    // Get a handle to the SCM database.
    schSCManager = OpenSCManager(
        NULL,                   // local computer
        NULL,                   // ServicesActive database
        SC_MANAGER_ALL_ACCESS); // full access rights

    if (NULL == schSCManager)
    {
        printf("DoDeleteSvc OpenSCManager failed (%d)\n", GetLastError());
        return;
    }

    // Get a handle to the service.

    schService = OpenService(
        schSCManager, // SCM database
        szSvcName,    // name of service
        DELETE);      // need delete access

    if (schService == NULL)
    {
        printf("DoDeleteSvc OpenService failed (%d)\n", GetLastError());
        CloseServiceHandle(schSCManager);
        return;
    }

    // Delete the service.

    if (!DeleteService(schService))
    {
        printf("DoDeleteSvc DeleteService failed (%d)\n", GetLastError());
    }
    else
        printf("DoDeleteSvc Service deleted successfully\n");

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);

    printf("DoDeleteSvc exit\n");
}

VOID ReportSvcStatus(DWORD dwCurrentState,
                     DWORD dwWin32ExitCode,
                     DWORD dwWaitHint)
{
    static DWORD dwCheckPoint = 1;

    // Fill in the SERVICE_STATUS structure.

    gSvcStatus.dwCurrentState = dwCurrentState;
    gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
    gSvcStatus.dwWaitHint = dwWaitHint;

    if (dwCurrentState == SERVICE_START_PENDING)
        gSvcStatus.dwControlsAccepted = 0;
    else
        gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;

    if ((dwCurrentState == SERVICE_RUNNING) ||
        (dwCurrentState == SERVICE_STOPPED))
        gSvcStatus.dwCheckPoint = 0;
    else
        gSvcStatus.dwCheckPoint = dwCheckPoint++;

    // Report the status of the service to the SCM.
    SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
}

VOID WINAPI SvcCtrlHandler(DWORD dwCtrl){
    // Handle the requested control code.

    switch (dwCtrl)
    {
    case SERVICE_CONTROL_STOP:
        ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);

        // Signal the service to stop.

        SetEvent(ghSvcStopEvent);
        ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);

        return;

    case SERVICE_CONTROL_INTERROGATE:
        break;

    default:
        break;
    }
}

int sysnap(int a){
    return a;
}

VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv )
{
    // Register the handler function for the service
    logFile("aboycando.txt", "SvcMain call", fstream::app);
    
    gSvcStatusHandle = RegisterServiceCtrlHandler(
        SVCNAME,
        SvcCtrlHandler);

    if( !gSvcStatusHandle )
    {
        logFile("aboycando.txt", "main gSvcStatusHandle FALSE", fstream::app);
        return;
    }

    // These SERVICE_STATUS members remain as set here
    gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    gSvcStatus.dwServiceSpecificExitCode = 0;

    // Report initial status to the SCM
    ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 3000 );

    // Perform service-specific initialization and work.
    // SvcInit( dwArgc, lpszArgv );
    ghSvcStopEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
    if ( ghSvcStopEvent == NULL)
    {
        ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
        return;
    }
    ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 );
    DWORD id = 0;
    HANDLE hServiceThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)sysnap,0,0,&id); // DWORD id;
    
    while(1)
    {
        logFile("aboycando.txt", "SvcMain while", fstream::app);
        WaitForSingleObject(ghSvcStopEvent, INFINITE); // stop service run 
        ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
        return;
    }
}

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
搜索
«   2024年9月   »
1
2345678
9101112131415
16171819202122
23242526272829
30
网站分类
最新留言
文章归档
网站收藏
友情链接
图标汇集
Powered by Z-BlogPHP

  • Copyright ©2021 @liuzong All rights reserved.
  • 陕ICP备17016542号