当程序执行到StartServiceCtrlDispatcher()时,我的程序报告错误。
错误:ConsoleApplication33.exe中的0x74BFFF70(sechost.dll)抛出异常:0xC0000005:访问冲突读取位置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;
}
Run Code Online (Sandbox Code Playgroud)
SERVICE_TABLE_ENTRY结构数组要求最后一个成员为NULL,我们将其称为“ Sentinel”(所有值均为NULL),它表示服务表的末尾。服务启动后,将调用StartServiceCtrlDispatcher()来通知服务控制器该服务正在执行并提供地址。StartServiceCtrlDispatcher()仅需要至少两个SERVICE_TABLE_ENTRY结构的数组。
This is why access violations occur. When your program executes to StartServiceCtrlDispatcher(entrytable), It will acess the second element ofSERVICE_TABLE_ENTRY, but your array definition has only one element, so it results in access violation.
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50 次 |
| 最近记录: |