WIN32 service program (III): complete service program instance, win32 service program instance

Source: Internet
Author: User

WIN32 service program (III): complete service program instance, win32 service program instance

The "service program" we mentioned above is more accurately a service control program. For example, we add an application to the Service Control Manager by entering the Application Path. A service control program can add a program to the Service Control Manager and control its operation, stop, and delete. So how can we avoid manual addition and directly add the code we want to run to the service? This requires us to establish a complete service program, including both the service master program and Service Control Program.

About the Service Main Program

The main service program includes a main function as the standard entry of the program, a ServiceMain function as the entry of the service program, a Handler function to enable or stop the service, and a MyWork function, you can write the code we want to run, that is, the function that the Service implements.

Let's look at a program. The function implemented by this program is to cyclically execute the MessageBox function during service running. You can run the application on cmd and PASS Parameters to it to implement service control. This program in the logic implementation is relatively simple, some functions can directly view the msdn documentation, attached link address https://technet.microsoft.com/zh-cn/library/

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsvc.h>
#include <stdio.h>

#define SLEEP_TIME 5000
#define LOG_FILE "c: \\ MemoryWatch.txt"
#define SERVICE_NAME "servitest"
#define SERVICE_DESC "test"
#define SERVICE_DISPLAY_NAME "test"

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
SC_HANDLE scm;
SC_HANDLE scv;

void ServiceMain (int argc, char ** argv);
void ControlHandler (DWORD request);
void Log (char * filename);
int startFunc ();
void OnStart ();
void OnCreate ();
void OnDelete ();
void OnStop ();

int main (int argc, char * argv [])
{
    // Service Name: MemoryStatus
    // Service Handle Function: ServiceMain ()
    SERVICE_TABLE_ENTRY ServiceTable [2] =
    {

        {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain},

        {NULL, NULL}
    };

    if (argc == 2)
    {
        if (! stricmp (argv [1], "-create"))
        {
            OnCreate ();
            return 0;
        }
        else if (! stricmp (argv [1], "-delete"))
        {
            OnDelete ();
            return 0;
        }
        else if (! stricmp (argv [1], "-start"))
        {
            OnStart ();
            return 0;
        }
        else if (! stricmp (argv [1], "-stop"))
        {
            OnStop ();
            return 0;
        }
        else
        {
            printf ("invailid parameter \ n");
            return 0;
        }
    }


    StartServiceCtrlDispatcher (ServiceTable);
    return 0;
}

void Log (char * str)
{
    FILE * fp = fopen (LOG_FILE, "a +");
    if (fp == NULL)
    {
        printf ("error to open file:% d \ n", GetLastError ());
        return;
    }
    
    fprintf (fp, "% s \ n", str);
    fflush (fp);
    fclose (fp);
}

void ServiceMain (int argc, char ** argv)
{
    BOOL bRet;
    int result;

    bRet = TRUE;

    ServiceStatus.dwWin32ExitCode = 0;
    ServiceStatus.dwCheckPoint = 0;
    ServiceStatus.dwWaitHint = 0;
    ServiceStatus.dwServiceType = SERVICE_WIN32;
    ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwServiceSpecificExitCode = 0;

    hStatus = RegisterServiceCtrlHandler (SERVICE_NAME, (LPHANDLER_FUNCTION) ControlHandler);
    if (hStatus == (SERVICE_STATUS_HANDLE) 0)
    {
        // log failed
        return;
    }
    // service status update
    ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus (hStatus, & ServiceStatus);

    while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
    {
        result = startFunc ();
        if (result)
        {
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            ServiceStatus.dwWin32ExitCode = -1;
            SetServiceStatus (hStatus, & ServiceStatus);
            return;
        }
    }
}

int startFunc ()
{
    MessageBox (NULL, "startFunc", SERVICE_NAME, MB_OK);
    return 0;
}

void ControlHandler (DWORD request)
{
    switch (request)
    {
        case SERVICE_CONTROL_STOP:
            Log ("Monitoring stopped.");
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus (hStatus, & ServiceStatus);
            return;

        case SERVICE_CONTROL_SHUTDOWN:
            Log ("Monitoring stopped.");
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus (hStatus, & ServiceStatus);
            return;
        default:
            break;
    }

    SetServiceStatus (hStatus, & ServiceStatus);
}

void OnCreate ()
{
    char filename [MAX_PATH];
    DWORD dwErrorCode;
    GetModuleFileName (NULL, filename, MAX_PATH);
    printf ("Creating Service ....");
    scm = OpenSCManager (0 / * localhost * /,
                        NULL / * SERVICES_ACTIVE_DATABASE * /,
                        SC_MANAGER_ALL_ACCESS / * ACCESS * /);
    if (scm == NULL)
    {
        printf ("OpenSCManager error:% d \ n", GetLastError ());
        return;
    }
    scv = CreateService (scm, // handle
    SERVICE_NAME, // Service start name
    SERVICE_DISPLAY_NAME, // Show service name
    SERVICE_ALL_ACCESS, // Service access type
    SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // Service type
    SERVICE_AUTO_START, // Automatically start the service
    SERVICE_ERROR_IGNORE, // Ignore errors
    filename, // The name of the startup file
    NULL, // name of load ordering group
    NULL, // Label identifier
    NULL, // correlation array name
    NULL, // account (current)
    NULL); // Password (current)

    if (scv == NULL)
    {
        dwErrorCode = GetLastError ();
        if (dwErrorCode! = ERROR_SERVICE_EXISTS)
        {
            printf ("Failure! \ n");
            CloseServiceHandle (scm);
            return;
        }
        else
        {
            printf ("already Exists! \ n");
        }
    }
    else
    {
        printf ("Success! \ n");
        CloseServiceHandle (scv);

    }

    CloseServiceHandle (scm);
    scm = scv = NULL;
}

void OnDelete ()
{
    scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (scm! = NULL)
    {
        scv = OpenService (scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
        if (scv! = NULL)
        {
            Query ServiceStatus (scv, & ServiceStatus);
            if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
            {
                ControlService (scv, SERVICE_CONTROL_STOP, & ServiceStatus);
            }
        DeleteService (scv);
        CloseServiceHandle (scv);
        }
    CloseServiceHandle (scm);
    }
    scm = scv = NULL;
}


void OnStart ()
{
    DWORD dwErrorCode;
    // Starting Service
    printf ("Starting Service ....");
    scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (scm! = NULL)
    {
        scv = OpenService (scm, SERVICE_NAME, SERVICE_ALL_ACCESS);
        if (scv! = NULL)
        {
            if (StartService (scv, 0, NULL) == 0)
            {
                dwErrorCode = GetLastError ();
                if (dwErrorCode == ERROR_SERVICE_ALREADY_RUNNING)
                {
                    printf ("already Running! \ n");
                    CloseServiceHandle (scv);
                    CloseServiceHandle (scm);
                    return;
                }
            }
        else
        {
            printf ("Pending ...");
        }

        // wait until the servics started
        while (QueryServiceStatus (scv, & ServiceStatus)! = 0)
        {
            if (ServiceStatus.dwCurrentState == SERVICE_START_PENDING)
            {
                Sleep (100);

            }
            else
            {
                break;

            }
        }

        CloseServiceHandle (scv);
        }
        else
        {
            // error to OpenService
            printf ("error to OpenService \ n");
        }

        CloseServiceHandle (scm);
    }
    else
    {
        // fail to OpenSCManager
    }
    / *
    if (InstallServiceStatus.dwCurrentState! = SERVICE_RUNNING)
    {
        printf ("Failure! \ n");
    }
    else
    {
        printf ("Success! \ nDumping Description to Registry ... \ n");
        RegOpenKeyEx (HKEY_LOCAL_MACHINE,
        "SYSTEM \\ CurrentControlSet \\ Services \\ NtBoot",
        0,
        KEY_ALL_ACCESS,
        & hkResult);
        RegSetValueEx (hkResult,
        "Description",
        0,
        REG_SZ,
        (unsigned char *) "Driver Booting Service",
        twenty three);

        RegCloseKey (hkResult);
    }

    CloseServiceHandle (schSCManager);
    CloseServiceHandle (schService);
    } //
    * /

    scm = scv = NULL;
}


void OnStop ()
{
    scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (scm! = NULL)
    {
        scv = OpenService (scm, SERVICE_NAME, SERVICE_STOP | SERVICE_QUERY_STATUS);
        if (scv! = NULL)
        {
            QueryServiceStatus (scv, & ServiceStatus);
            if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
            {
                ControlService (scv, SERVICE_CONTROL_STOP, & ServiceStatus);
            }
            CloseServiceHandle (scv);
        }
        CloseServiceHandle (scm);
    }
    scm = scv = NULL;
}  

After the program is compiled, run cmd. The complete path of the compiled program is C: \ hi \ Debug \ hi.exe.

Run C: \ hi \ Debug \ hi.exe-create to create a service.

Run C: \ hi \ Debug \ hi.exe-start to start the service.

......

There are log files in cdisk memorywatch.txt

 


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.