Windows Services Programming 20

 

 

 

 

 

Building the Project

 

Build and run the project. This project used to install the service (service is defined in the program.)

 

A Complete Windows Service Working Program Example:  Building and running the Windows services program example

 

Then, verify the service installation using Windows Services snap-in.

 

Verifying the service installation using Windows Services snap-in

 

Adding New Project for Windows Service Configuration Application

 

Create another new Win32 console application project in the same solution. This application can be used to configure Windows services.

 

Adding New Project for Windows Service Configuration Application

 

As usual, give a suitable project's name.

 

Windows services example: Creating another new Win32 C++ console application project in Visual C++ .NET existing project

 

Then, add the source file and give it a suitable name.

 

Windows services example: Adding new C++ source file for C++ source code to the existing C++ project

 

Next, add the following source code.

 

#include <windows.h>

#include <strsafe.h>

#include <stdio.h>

 

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

 

WCHAR szCommand[10];

WCHAR szSvcName[80];

 

VOID __stdcall DisplayUsage(void);

VOID __stdcall DoQuerySvc(void);

VOID __stdcall DoUpdateSvcDesc(void);

VOID __stdcall DoDisableSvc(void);

VOID __stdcall DoEnableSvc(void);

VOID __stdcall DoAutoSvc(void);

VOID __stdcall DoDeleteSvc(void);

 

// Purpose: Entry point function. Executes specified command from user.

// Parameters: Command-line syntax is: svcconfig [command] [service_path]

// Return value: None

void wmain(int argc, WCHAR *argv[])

{

    wprintf(L"\n");

    if( argc != 3 )

    {

        wprintf(L"ERROR:\tIncorrect number of arguments!\n\n");

        DisplayUsage();

        return;

    }

 

    StringCchCopy(szCommand, 10, argv[1]);

    StringCchCopy(szSvcName, 80, argv[2]);

 

    if (lstrcmpi( szCommand, L"query") == 0 )

        DoQuerySvc();

    else if (lstrcmpi( szCommand, L"describe") == 0 )

        DoUpdateSvcDesc();

    else if (lstrcmpi( szCommand, L"disable") == 0 )

        DoDisableSvc();

    else if (lstrcmpi( szCommand, L"enable") == 0 )

        DoEnableSvc();

      else if (lstrcmpi( szCommand, L"auto") == 0 )

        DoAutoSvc();

    else if (lstrcmpi( szCommand, L"delete") == 0 )

        DoDeleteSvc();

    else

    {

        wprintf(L"Unknown command (%s)\n\n", szCommand);

        DisplayUsage();

    }

}

 

VOID __stdcall DisplayUsage()

{

    wprintf(L"Description:");

    wprintf(L"\tCommand-line tool that configures a service.\n\n");

    wprintf(L"Usage:");

    wprintf(L"\tsvcconfig [command] [service_name]\n\n");

    wprintf(L"\t[command]\n");

    wprintf(L"\t  query\n");

    wprintf(L"\t  describe\n");

    wprintf(L"\t  disable\n");

    wprintf(L"\t  enable\n");

    wprintf(L"\t  auto\n");

    wprintf(L"\t  delete\n");

}

 

// Purpose: Retrieves and displays the current service configuration.

// Parameters: None

// Return value: None

VOID __stdcall DoQuerySvc()

{

    SC_HANDLE schSCManager;

    SC_HANDLE schService;

    LPQUERY_SERVICE_CONFIG lpsc;

    LPSERVICE_DESCRIPTION lpsd;

    DWORD dwBytesNeeded, cbBufSize, dwError;

 

    // 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)

    {

        wprintf(L"OpenSCManager() failed, error %d\n", GetLastError());

        return;

    }

 

    // 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)

    {

        wprintf(L"OpenService() failed, error %d\n", GetLastError());

        CloseServiceHandle(schSCManager);

        return;

    }

 

    // 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

        {

            wprintf(L"QueryServiceConfig() failed, error %d", dwError);

            goto cleanup;

        }

    }

 

    if( !QueryServiceConfig(schService, lpsc, cbBufSize, &dwBytesNeeded) )

    {

        wprintf(L"QueryServiceConfig() failed, error %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

        {

            wprintf(L"QueryServiceConfig2() failed, error %d", dwError);

            goto cleanup;

        }

    }

 

    if (! QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE) lpsd, cbBufSize, &dwBytesNeeded) )

    {

        wprintf(L"QueryServiceConfig2() failed, error %d", GetLastError());

        goto cleanup;

    }

 

    // Print the configuration information

    wprintf(L"%s configuration: \n", szSvcName);

    wprintf(L"  Type: 0x%x\n", lpsc->dwServiceType);

    wprintf(L"  Start Type: 0x%x\n", lpsc->dwStartType);

    wprintf(L"  Error Control: 0x%x\n", lpsc->dwErrorControl);

    wprintf(L"  Binary path: %s\n", lpsc->lpBinaryPathName);

    wprintf(L"  Account: %s\n", lpsc->lpServiceStartName);

 

    if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, L"") != 0)

        wprintf(L"  Description: %s\n", lpsd->lpDescription);

    if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, L"") != 0)

        wprintf(L"  Load order group: %s\n", lpsc->lpLoadOrderGroup);

    if (lpsc->dwTagId != 0)

        wprintf(L"  Tag ID: %d\n", lpsc->dwTagId);

    if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)

        wprintf(L"  Dependencies: %s\n", lpsc->lpDependencies);

 

    LocalFree(lpsc);

    LocalFree(lpsd);

 

cleanup:

    CloseServiceHandle(schService);

    CloseServiceHandle(schSCManager);

}

 

// Purpose: Disables the service

// Parameters: None

// Return value: None

VOID __stdcall DoDisableSvc()

{

    SC_HANDLE schSCManager;

    SC_HANDLE schService;

 

    // 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)

    {

        wprintf(L"OpenSCManager() failed, error %d\n", GetLastError());

        return;

    }

 

    // Get a handle to the service

    schService = OpenService(

        schSCManager,            // SCM database

        szSvcName,               // name of service

        SERVICE_CHANGE_CONFIG);  // need change config access

 

    if (schService == NULL)

    {

        wprintf(L"OpenService() failed, error %d\n", GetLastError());

        CloseServiceHandle(schSCManager);

        return;

    }   

 

    // Change the service start type

    if (! ChangeServiceConfig(

        schService,        // handle of service

        SERVICE_NO_CHANGE, // service type: no change

        SERVICE_DISABLED,  // service start type

        SERVICE_NO_CHANGE, // error control: no change

        NULL,              // binary path: no change

        NULL,              // load order group: no change

        NULL,              // tag ID: no change

        NULL,              // dependencies: no change

        NULL,              // account name: no change

        NULL,              // password: no change

        NULL) )            // display name: no change

    {

        wprintf(L"ChangeServiceConfig() failed, error %d\n", GetLastError());

    }

    else

            wprintf(L"Service disabled successfully.\n");

 

    CloseServiceHandle(schService);

    CloseServiceHandle(schSCManager);

}

 

// Purpose: Enables the service.

// Parameters: None

// Return value: None

VOID __stdcall DoEnableSvc()

{

    SC_HANDLE schSCManager;

    SC_HANDLE schService;

 

    // 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)

    {

        wprintf(L"OpenSCManager() failed, error %d\n", GetLastError());

        return;

    }

 

    // Get a handle to the service

    schService = OpenService(

        schSCManager,            // SCM database

        szSvcName,               // name of service

        SERVICE_CHANGE_CONFIG);  // need change config access

 

    if (schService == NULL)

    {

        wprintf(L"OpenService() failed, error %d\n", GetLastError());

        CloseServiceHandle(schSCManager);

        return;

    }   

 

    // Change the service start type

    if (! ChangeServiceConfig(

        schService,            // handle of service

        SERVICE_NO_CHANGE,     // service type: no change

        SERVICE_DEMAND_START,  // service start type

        SERVICE_NO_CHANGE,     // error control: no change

        NULL,                  // binary path: no change

        NULL,                  // load order group: no change

        NULL,                  // tag ID: no change

        NULL,                  // dependencies: no change

        NULL,                  // account name: no change

        NULL,                  // password: no change

        NULL) )                // display name: no change

    {

        wprintf(L"ChangeServiceConfig() failed, error %d\n", GetLastError());

    }

    else

            wprintf(L"Service enabled successfully.\n");

 

    CloseServiceHandle(schService);

    CloseServiceHandle(schSCManager);

}

 

// Purpose: Updates the service description to "This is a test description".

// Parameters: None

// Return value: None

VOID __stdcall DoUpdateSvcDesc()

{

    SC_HANDLE schSCManager;

    SC_HANDLE schService;

    SERVICE_DESCRIPTION sd;

    LPTSTR szDesc = L"This is a test description for a Windows service";

 

    // 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)

    {

        wprintf(L"OpenSCManager() failed, error %d\n", GetLastError());

        return;

    }

 

    // Get a handle to the service

    schService = OpenService(

        schSCManager,            // SCM database

        szSvcName,               // name of service

        SERVICE_CHANGE_CONFIG);  // need change config access

 

    if (schService == NULL)

    {

        wprintf(L"OpenService() failed, error %d\n", GetLastError());

        CloseServiceHandle(schSCManager);

        return;

    }

 

    // Change the service description

    sd.lpDescription = szDesc;

 

    if( !ChangeServiceConfig2(

        schService,                 // handle to service

        SERVICE_CONFIG_DESCRIPTION, // change: description

        &sd) )                      // new description

    {

        wprintf(L"ChangeServiceConfig2() failed, error %d\n", GetLastError());

    }

    else

            wprintf(L"Service description updated successfully.\n");

 

    CloseServiceHandle(schService);

    CloseServiceHandle(schSCManager);

}

 

// Purpose: Enables the service to start automatically.

// Parameters: None

// Return value: None

VOID __stdcall DoAutoSvc(void)

{

    SC_HANDLE schSCManager;

    SC_HANDLE schService;

 

    // 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)

    {

        wprintf(L"OpenSCManager() failed, error %d\n", GetLastError());

        return;

    }

 

    // Get a handle to the service

    schService = OpenService(

        schSCManager,            // SCM database

        szSvcName,               // name of service

        SERVICE_CHANGE_CONFIG);  // need change config access

 

    if (schService == NULL)

    {

        wprintf(L"OpenService() failed, error %d\n", GetLastError());

        CloseServiceHandle(schSCManager);

        return;

    }   

 

    // Change the service start type

    if (! ChangeServiceConfig(

        schService,            // handle of service

        SERVICE_NO_CHANGE,     // service type: no change

        SERVICE_AUTO_START,  // service start type

        SERVICE_NO_CHANGE,     // error control: no change

        NULL,                  // binary path: no change

        NULL,                  // load order group: no change

        NULL,                  // tag ID: no change

        NULL,                  // dependencies: no change

        NULL,                  // account name: no change

        NULL,                  // password: no change

        NULL) )                // display name: no change

    {

        wprintf(L"ChangeServiceConfig() failed, error %d\n", GetLastError());

    }

    else

            wprintf(L"Service was set to automatic start successfully.\n");

 

    CloseServiceHandle(schService);

    CloseServiceHandle(schSCManager);

}

 

// Purpose: Deletes a service from the SCM database

// Parameters: None

// Return value: None

VOID __stdcall DoDeleteSvc()

{

    SC_HANDLE schSCManager;

    SC_HANDLE schService;

    // SERVICE_STATUS ssStatus;

 

    // 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)

    {

        wprintf(L"OpenSCManager() failed, error %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)

    {

        wprintf(L"OpenService() failed, error %d\n", GetLastError());

        CloseServiceHandle(schSCManager);

        return;

    }

 

    // Delete the service

    if (! DeleteService(schService) )

    {

        wprintf(L"DeleteService() failed, error %d\n", GetLastError());

    }

    else

            wprintf(L"Service %s deleted successfully!\n", szSvcName);

 

    CloseServiceHandle(schService);

    CloseServiceHandle(schSCManager);

}

 

Select the newly created project folder, right-click mouse and select Build sub-menu so that we just build the project that previously created, independently.

 

Building the C++ project independently

 

 

 

 

< Windows Services 19 | Win32 Programming | Windows Services Win32 Programming | Windows Services 21 >