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
Many windows api have input only parameters, declared as
T*
– pointer to the same typeT
. Despite it can be declared asconst 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 placePSTR
parameter. But now this produce error. If we sure that function actually use string as readonly, we can useconst_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 caseSERVICE_TABLE_ENTRY
actually const string used, despite it declared without const modifier. So i be select hereconst_cast
The error is on this line:
In your case,
SERVICE_TABLE_ENTRY
maps toSERVICE_TABLE_ENTRYA
, and theSERVICE_TABLE_ENTRYA::lpServiceName
field is anLPSTR
, ie a pointer to a non-constchar
string. However, you are passing it a narrow string literal, which decays into a pointer to a constchar
string.To fix the error, you need to remove the const-ness of the string. You can either:
In C:
In C++: