当程序执行到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/

10-12 06:19