代码如下:
/*
 * 服务程序
 */#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

}

解决方案 »

  1.   

    // 续上
    // 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;
    }