停止服务时出现错误997:重叠I/O操作在进行中,附代码

blldw 2005-04-23 12:43:51
代码如下:
/*
* 服务程序
*/

#define BEEPSVC_DEBUG

#include <tchar.h>
#include <windows.h>

#define SERVICE_NAME _T("BeepSvr")
#define DEFAULT_BEEP_DELAY 2000

void RetErrorString(DWORD dwError);
void WINAPI SvcMain(DWORD argc, LPTSTR *argv);
void WINAPI SvcCtrlHandler(DWORD dwControl);
DWORD WINAPI BeepSvcThread(LPVOID lParam);

BOOL InitSvc();
BOOL UpdateServiceStatus(DWORD dwCurrentStatus, DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);

// 全局变量
SERVICE_STATUS_HANDLE g_hSvcCtrlHandler = NULL; // 不能关闭该句柄
HANDLE g_hEvent = NULL; // 通知服务结束的事件句柄
HANDLE g_hBeep = NULL; // 工作线程句柄

DWORD dwBeepDelay = 0;
BOOL g_bSvcRunning = FALSE;
BOOL g_bSvcPause = FALSE;

// service entry point
int _tmain(int argc, TCHAR *argv[])
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("进入到服务程序入口点..."));
#endif

SERVICE_TABLE_ENTRY ste[] = {
{SERVICE_NAME, SvcMain},
{NULL, NULL}
};

// 立即调用StartServiceCtrlDispatcher
// 本服务程序只包含一项服务,所以如果有任何初始化代码,应放到SvcMain
if(!StartServiceCtrlDispatcher(ste))
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("调用StartServiceCtrlDispatcher()失败,退出..."));
#endif

return -1;
}

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("退出到服务程序入口点..."));
#endif

return 0;
}

// Service Main Function
// 当SCM启动服务时,它调用SvcMain,当SvcMain函数返回时,服务停止
// 如果需要传递服务参数,需要把服务类型设定为手工启动
void WINAPI SvcMain(DWORD argc, LPTSTR *argv)
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("进入到SvcMain()..."));
#endif

g_hSvcCtrlHandler = RegisterServiceCtrlHandler(SERVICE_NAME, SvcCtrlHandler);
if(g_hSvcCtrlHandler == (SERVICE_STATUS_HANDLE)0)
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("调用RegisterServiceCtrlHanlder()失败..."));
#endif

return;
}

// 启动服务,通知SCM启动服务的进度
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("准备启动服务,SERVICE_START_PENDING..."));
#endif

// 由于服务在正式启动成功前,需要做很多步工作,所以需要设置进度标志给dwCheckPoint
// 每完成一步操作,在下一步操作前将dwCheckPoint加一

// 通知
if(!UpdateServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 5000))
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("更新服务状态失败,SERVICE_START_PENDING_1..."));
#endif

goto SvcMainClean;
}
// 创建结束事件--第一步
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(g_hEvent == NULL)
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("第一步,创建结束事件失败..."));
#endif

goto SvcMainClean;
}

// 通知
if(!UpdateServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 2, 1000))
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("更新服务状态失败,SERVICE_START_PENDING_2..."));
#endif

goto SvcMainClean;
}
// 检查启动参数--第二步
if(argc == 2)
dwBeepDelay = _ttoi(argv[1]);
else
dwBeepDelay = DEFAULT_BEEP_DELAY;

if(dwBeepDelay < 1000)
dwBeepDelay = 1000;

// 通知
if(!UpdateServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 3, 5000))
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("更新服务状态失败,SERVICE_START_PENDING_3..."));
#endif

goto SvcMainClean;
}
// 创建线程--第三步
g_hBeep = CreateThread(NULL, 0, BeepSvcThread, NULL, 0, NULL);
if(g_hBeep == NULL)
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("第三步,创建工作线程失败..."));
#endif

goto SvcMainClean;
}
g_bSvcRunning = TRUE;

// 服务启动工作完毕,通知SCM
if(!UpdateServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0))
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("更新服务状态失败,SERVICE_RUNNING..."));
#endif

goto SvcMainClean;
}

// 等待结束事件的到来
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("启动并设置服务状态成功,等待结束事件到来..."));
#endif

WaitForSingleObject(g_hEvent, INFINITE);
WaitForSingleObject(g_hBeep, INFINITE);

// 结束服务
//
// SvcMainClean
//
SvcMainClean:

if(g_hBeep)
CloseHandle(g_hBeep);

if(g_hEvent)
CloseHandle(g_hEvent);

if(g_hSvcCtrlHandler)
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("结束事件到来,退出SvcMain之前发送SERVICE_STOPPED通知..."));
#endif

if(!UpdateServiceStatus(SERVICE_STOPPED, GetLastError(), 0, 0, 0))
{
#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("结束事件到来,退出SvcMain之前发送SERVICE_STOPPED通知,失败!..."));
#endif
}
}

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("结束事件到来,退出SvcMain..."));
#endif

}

...全文
282 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzheng318 2005-04-23
  • 打赏
  • 举报
回复
帮楼主顶!
blldw 2005-04-23
  • 打赏
  • 举报
回复
// 续上
// dispatch events received from SCM
void WINAPI SvcCtrlHandler(DWORD dwControl)
{
DWORD dwCurrentStatus = 0;

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("进入SvcCtrlHandler..."));
#endif

switch(dwControl)
{
// 没有START选项,因为SvcMain即是一个开始

// 停止服务
case SERVICE_CONTROL_STOP:

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("SvcCtrlHandler: 收到SERVICE_CONTROL_STOP..."));
#endif

dwCurrentStatus = SERVICE_STOP_PENDING;
UpdateServiceStatus(dwCurrentStatus, 0, 0, 1, 10000);
// 停止服务的代码
g_bSvcRunning = FALSE;
SetEvent(g_hEvent);
return;

// 暂停服务
case SERVICE_CONTROL_PAUSE:

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("SvcCtrlHandler: 收到SERVICE_CONTROL_PAUSE..."));
#endif

if(g_bSvcRunning && !g_bSvcPause)
{
UpdateServiceStatus(SERVICE_PAUSE_PENDING, NO_ERROR, 0, 1, 1000);
// 暂停服务的代码
g_bSvcPause = TRUE;
SuspendThread(g_hBeep);
dwCurrentStatus = SERVICE_PAUSED;
}
break;

// 继续服务
case SERVICE_CONTROL_CONTINUE:

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("SvcCtrlHandler: 收到SERVICE_CONTROL_CONTINUE..."));
#endif

if(g_bSvcRunning && g_bSvcPause)
{
UpdateServiceStatus(SERVICE_CONTINUE_PENDING, NO_ERROR, 0, 1, 1000);
// 继续服务的代码
g_bSvcPause = FALSE;
ResumeThread(g_hBeep);
dwCurrentStatus = SERVICE_RUNNING;
}
break;

case SERVICE_CONTROL_INTERROGATE:

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("SvcCtrlHandler: 收到SERVICE_CONTROL_INTERROGATE..."));
#endif

break;

case SERVICE_CONTROL_SHUTDOWN:

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("SvcCtrlHandler: 收到SERVICE_CONTROL_SHUTDOWN..."));
#endif

return;

default:
break;
}

// 更新服务的最后状态
UpdateServiceStatus(dwCurrentStatus, NO_ERROR, 0, 0, 0);
}

// 工作线程
DWORD WINAPI BeepSvcThread(LPVOID lParam)
{

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("进入到BeepSvcThread..."));
#endif

while(g_bSvcRunning)
{

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("BeepSvcThread while..."));
#endif

Beep(2000, 1000);
Sleep(dwBeepDelay);
}

#ifdef BEEPSVC_DEBUG
OutputDebugString(_T("退出BeepSvcThread..."));
#endif

return 0;
}

// 更新服务状态
BOOL UpdateServiceStatus(DWORD dwCurrentStatus, DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)
{
BOOL bSuccess;
SERVICE_STATUS ss;

// 填充SERVICE_STATUS结构的所有成员
ZeroMemory(&ss, sizeof(ss));
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ss.dwCurrentState = dwCurrentStatus;

// 不接受任何控制,如果是SERVICE_START_PENDING,因为在SvcMain完成了
if(dwCurrentStatus == SERVICE_START_PENDING)
ss.dwControlsAccepted = 0;
else
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;

// 如果指定了退出代码,就设置win32的退出代码
if(dwServiceSpecificExitCode == 0)
ss.dwWin32ExitCode = dwWin32ExitCode;
else
ss.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
ss.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
ss.dwCheckPoint = dwCheckPoint;
ss.dwWaitHint = dwWaitHint;

bSuccess = SetServiceStatus(g_hSvcCtrlHandler, &ss);
if(!bSuccess)
{
g_bSvcRunning = FALSE;
SetEvent(g_hEvent);
}

return bSuccess;
}
blldw 2005-04-23
  • 打赏
  • 举报
回复
各位高手,代码中哪部分涉及到了重叠I/O?

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧