skip to Main Content

I have this code:

MyService:

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>

#define PIPE_NAME TEXT("\\.\pipe\MyNamedPipe")

SERVICE_STATUS_HANDLE g_ServiceStatusHandle = NULL;
SERVICE_STATUS g_ServiceStatus = { 0 };
HANDLE g_hStopEvent = NULL;

void WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
void WINAPI ServiceCtrlHandler(DWORD CtrlCode);
void ReportServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);
void ServiceWorkerThread();

int main() {
    SERVICE_TABLE_ENTRY ServiceTable[] = {
        { TEXT("MyService"), ServiceMain },
        { NULL, NULL }
    };

    if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) {
        printf("StartServiceCtrlDispatcher failed (%d)n", GetLastError());
    }
    return 0;
}

void WINAPI ServiceMain(DWORD argc, LPTSTR* argv) {
    g_ServiceStatusHandle = RegisterServiceCtrlHandler(TEXT("MyService"), ServiceCtrlHandler);
    if (g_ServiceStatusHandle == 0) {
        return;
    }

    g_ServiceStatus.dwServiceType = SERVICE_WIN32;
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    ReportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 3000);

    g_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (g_hStopEvent == NULL) {
        ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);
        return;
    }

    ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
    ServiceWorkerThread();

    ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0);
}

void WINAPI ServiceCtrlHandler(DWORD CtrlCode) {
    switch (CtrlCode) {
    case SERVICE_CONTROL_STOP:
        ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 0);
        SetEvent(g_hStopEvent);
        break;
    default:
        break;
    }
}

void ReportServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) {
    g_ServiceStatus.dwCurrentState = dwCurrentState;
    g_ServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
    g_ServiceStatus.dwCheckPoint = dwCheckPoint;
    g_ServiceStatus.dwWaitHint = dwWaitHint;

    SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
}

void ServiceWorkerThread() {
    // Здесь можно добавить логику для работы службы
    while (WaitForSingleObject(g_hStopEvent, 0) != WAIT_OBJECT_0) {
        Sleep(1000); // Имитация работы
    }
}

We need to fix this error:

MyService.cpp (18,11): error C2440: initialization: unable to convert "const char [10]" to "LPSTR"

I don’t understand how to do this correctly, so as not to lose logic.

It is necessary to use multi-byte encoding in Visual Studio.

Here is the task itself:

To write and debug a system service containing a function
for registering its events in a text file (start, stop,
execution errors, data exchange with the client), implementing a server process. Methods of data exchange with the client application:: named pipes.

MyClient code compiles without errors, and it does not need to be corrected much, it is needed to process the file: opening the file, reading and deleting a given character, counting deletions and displaying the number of substitutions.

2

Answers


  1. Many windows api have input only parameters, declared as T* – pointer to the same type T. Despite it can be declared as const T* because it never try modify data by this pointer ( rare exception here, CreateProcessW 2-d parameter ). Old compilers accept pass const string literal "…" In place PSTR parameter. But now this produce error. If we sure that function actually use string as readonly, we can use const_cast<PSTR>("...") for avoid error. Or we can allocate some read-write buffer ( probably in stack) copy string to this buffer, and pass it pointer. In case SERVICE_TABLE_ENTRY actually const string used, despite it declared without const modifier. So i be select here const_cast

    Login or Signup to reply.
  2. The error is on this line:

    SERVICE_TABLE_ENTRY ServiceTable[] = {
        { TEXT("MyService"), ServiceMain }, // <-- HERE
        { NULL, NULL }
    };
    

    In your case, SERVICE_TABLE_ENTRY maps to SERVICE_TABLE_ENTRYA, and the SERVICE_TABLE_ENTRYA::lpServiceName field is an LPSTR, ie a pointer to a non-const char string. However, you are passing it a narrow string literal, which decays into a pointer to a const char string.

    To fix the error, you need to remove the const-ness of the string. You can either:

    • copy the literal data into a local non-const buffer:
    TCHAR szServiceName[] = TEXT("MyService");
    SERVICE_TABLE_ENTRY ServiceTable[] = {
        { szServiceName, ServiceMain },
        { NULL, NULL }
    };
    
    • use a type-cast:

    In C:

    SERVICE_TABLE_ENTRY ServiceTable[] = {
        { (LPTSTR) TEXT("MyService"), ServiceMain },
        { NULL, NULL }
    };
    

    In C++:

    SERVICE_TABLE_ENTRY ServiceTable[] = {
        { const_cast<LPTSTR>(TEXT("MyService")), ServiceMain },
        { NULL, NULL }
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search