代码如下:
/*
* 服务程序
*/#define BEEPSVC_DEBUG#include <tchar.h>
#include <windows.h>#define SERVICE_NAME _T("BeepSvr")
#define DEFAULT_BEEP_DELAY 2000void 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
}
/*
* 服务程序
*/#define BEEPSVC_DEBUG#include <tchar.h>
#include <windows.h>#define SERVICE_NAME _T("BeepSvr")
#define DEFAULT_BEEP_DELAY 2000void 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
}
解决方案 »
- 如何使用MSXml来解析带命名空间的xml
- 送分: 怎样使工具栏中出现CImageList控件图标,设计时我可以把它拖到对话框窗体上去
- ODBC如何创建数据库文件
- OpenGL中如何使用求值器生成B样条曲线?
- 如何发送一个数据包 有一个结构定义的是这个包的一些标志信息 而真正的数据没在包里 ,数据每次发出时不固定大小
- 高分,重金!!!求Oracle打包问题
- 如何用VC写一个短信网关的平台(cmpp3.0)
- 如何在c++中改变光标的位置。。。。。。再线等待
- 串口通讯问题,麻烦下载代码帮忙看看
- 怎么用API函数获得被的程序的句柄
- 拖滚动块时候,nTrackPos 自动存放当前滚动块位置?
- 已知窗口句柄,如何去掉最大,最小按钮,最好直接去掉标题栏
// 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;
}