当程序执行到StartServiceCtrlDispatcher()时,我的程序会报告错误。
错误:在ConsoleApplication33.exe中的0x74bff70(sechost.dll)处引发异常:0xc000005:访问冲突读取位置0xCCCCCCCC。
我试了很多方法,但都失败了我哪里写错了。请告诉我。提前谢谢你代码如下:
#include "pch.h"
#include<Windows.h>
#include<iostream>
#include<atlstr.h>
#include<fstream>
#include<tchar.h>
bool brun = false;
SERVICE_STATUS servicestatus;
SERVICE_STATUS_HANDLE hstatus;
void WriteToLog(const std::string &str)
{
std::ofstream p("D:/log.txt", std::ios::app);
if (!p.is_open())
return;
p << str << std::endl;
p.close();
}
void WINAPI CtrlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
brun = false;
servicestatus.dwCurrentState = SERVICE_STOPPED;
break;
case SERVICE_CONTROL_SHUTDOWN:
brun = false;
servicestatus.dwCurrentState = SERVICE_STOPPED;
}
SetServiceStatus(hstatus, &servicestatus);
}
void WINAPI ServiceMain(int argc, char **argv)
{
servicestatus.dwServiceType = SERVICE_WIN32;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0;
servicestatus.dwCheckPoint = 0;
servicestatus.dwWaitHint = 0;
hstatus = ::RegisterServiceCtrlHandler("MyService", CtrlHandler);
if (hstatus == 0)
{
WriteToLog("RegisterServiceCtrlHandler failed");
return;
}
WriteToLog("RegisterServiceCtrlHandler success");
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hstatus, &servicestatus);
brun = true;
MEMORYSTATUSEX memstatus;
char str[100];
memset(str, '\0', 100);
while (brun)
{
GlobalMemoryStatusEx(&memstatus);
SIZE_T availmb = memstatus.ullAvailPhys / 1024 / 1024;
sprintf_s(str, 100, "available memory is %zdMB", availmb);
WriteToLog(str);
Sleep(2000);
}
WriteToLog("service stopped");
}
int _tmain(int argc, _TCHAR **argv)
{
SERVICE_TABLE_ENTRY entrytable[1];
CString cstr("MyService");
entrytable[0].lpServiceName = cstr.GetBuffer();
cstr.ReleaseBuffer();
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
StartServiceCtrlDispatcher(entrytable);
return 0;
}
最佳答案
服务表条目结构数组要求最后一个成员为空,我们称之为“Sentinel”(所有值都为空),它表示服务表的结束一旦服务启动,就会调用StartServiceCtrlDispatcher()来通知服务控制器服务正在执行并提供地址StartServiceCtrlDispatcher()只需要至少两个服务表条目结构的数组。
这就是为什么会发生访问冲突当程序执行到StartServiceCtrlDispatcher(entrytable)时,它将访问服务表项的第二个元素,但数组定义只有一个元素,因此会导致访问冲突。
int _tmain(int argc, _TCHAR **argv)
{
//SERVICE_TABLE_ENTRY entrytable[] =
//{
// {(LPWSTR)"MyService", (LPSERVICE_MAIN_FUNCTION)ServiceMain},
// {NULL, NULL}
//};
SERVICE_TABLE_ENTRY entrytable[2];
CString cstr("MyService");
entrytable[0].lpServiceName = cstr.GetBuffer();
cstr.ReleaseBuffer();
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
entrytable[1].lpServiceName = NULL;
entrytable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(entrytable);
return 0;
}
关于c - 报告错误:使用StartServiceCtrlDispatcher(entrytable)时访问冲突,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57601169/