系统服务 为什么不能自动随机启动?

J_2004 2007-09-19 10:44:07

设置为自动启动,不能启动,日志有三条错误:
1.等待 BeepService 服务的连接超时(30000 毫秒)。
2.由于下列错误,BeepService 服务启动失败:
服务没有及时响应启动或控制请求。

但是能够手动启动!?
...全文
540 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Gavin001 2007-09-19
  • 打赏
  • 举报
回复
你的服务自己写的?我都用IDE自动生成的,基本上不会出现无法启动的问题
找了半天,没发现你的代码里有RegisterServer()
J_2004 2007-09-19
  • 打赏
  • 举报
回复

DWORD ServiceThread(LPDWORD param){
while (1) {
Beep(500,500);
Sleep(beepDelay);
}
return 0;
}

// Initializes the service by starting its thread
BOOL InitService(){
DWORD id;

// Start the service's thread
threadHandle = CreateThread(0, 0,(LPTHREAD_START_ROUTINE) ServiceThread,0, 0, &id);

if (threadHandle==0)
return FALSE;
else{
runningService = TRUE;
return TRUE;
}
}

// Dispatches events received from the SCM
VOID Handler (DWORD controlCode) {
DWORD currentState = 0;
BOOL success;

switch(controlCode)
{
// There is no START option because
// ServiceMain gets called on a start

// Stop the service
case SERVICE_CONTROL_STOP:
// Tell the SCM what's happening
success = SendStatusToSCM(SERVICE_STOP_PENDING, NO_ERROR, 0, 1, 5000);
runningService=FALSE;
// Set the event that is holding ServiceMain
// so that ServiceMain can return
SetEvent(terminateEvent);
return;

// Pause the service
case SERVICE_CONTROL_PAUSE:
if (runningService && !pauseService)
{
// Tell the SCM what's happening
success = SendStatusToSCM(SERVICE_PAUSE_PENDING,NO_ERROR, 0, 1, 1000);
pauseService = TRUE;
SuspendThread(threadHandle);
currentState = SERVICE_PAUSED;
}
break;

// Resume from a pause
case SERVICE_CONTROL_CONTINUE:
if (runningService && pauseService)
{
// Tell the SCM what's happening
success = SendStatusToSCM(SERVICE_CONTINUE_PENDING,NO_ERROR, 0, 1, 1000);
pauseService = FALSE;
ResumeThread(threadHandle);
currentState = SERVICE_RUNNING;
}
break;

// Update current status
case SERVICE_CONTROL_INTERROGATE:
// it will fall to bottom and send status
break;

// Do nothing in a shutdown. Could do cleanup
// here but it must be very quick.
case SERVICE_CONTROL_SHUTDOWN:
return;

default:
break;
}
SendStatusToSCM(currentState, NO_ERROR, 0, 0, 0);
}

// Handle an error from ServiceMain by cleaning up
// and telling SCM that the service didn't start.
VOID terminate(DWORD error){
// if terminateEvent has been created, close it.
if (terminateEvent)
CloseHandle(terminateEvent);

// Send a message to the scm to tell about stopage
if (serviceStatusHandle)
SendStatusToSCM(SERVICE_STOPPED, error, 0, 0, 0);

// If the thread has started, kill it off
if (threadHandle)
CloseHandle(threadHandle);

// Do not need to close serviceStatusHandle
}

// ServiceMain is called when the SCM wants to
// start the service. When it returns, the service
// has stopped. It therefore waits on an event
// just before the end of the function, and
// that event gets set when it is time to stop.
// It also returns on any error because the
// service cannot start if there is an eror.
VOID ServiceMain(DWORD argc, LPTSTR *argv)
{
BOOL success;

// immediately call Registration function
serviceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, (LPHANDLER_FUNCTION)Handler);
if (!serviceStatusHandle)
{
terminate(GetLastError());
return;
}

// Notify SCM of progress
success = SendStatusToSCM(SERVICE_START_PENDING,NO_ERROR, 0, 1, 5000);
if (!success) {
terminate(GetLastError());
return;
}

// create the termination event
terminateEvent = CreateEvent (0, TRUE, FALSE, 0);
if (!terminateEvent)
{
terminate(GetLastError());
return;
}

// Notify SCM of progress
success = SendStatusToSCM(SERVICE_START_PENDING,NO_ERROR, 0, 2, 1000);
if (!success)
{
terminate(GetLastError());
return;
}

// Check for startup params
if (argc == 2)
{
int temp = atoi(argv[1]);
if (temp & 1000)
beepDelay = DEFAULT_BEEP_DELAY;
else
beepDelay = temp;
}

// Notify SCM of progress
success = SendStatusToSCM(SERVICE_START_PENDING,NO_ERROR, 0, 3, 5000);
if (!success)
{
terminate(GetLastError());
return;
}

// Start the service itself
success = InitService();
if (!success)
{
terminate(GetLastError());
return;
}

// The service is now running.
// Notify SCM of progress
success = SendStatusToSCM(SERVICE_RUNNING,NO_ERROR, 0, 0, 0);
if (!success)
{
terminate(GetLastError());
return;
}

// Wait for stop signal, and then terminate
WaitForSingleObject (terminateEvent, INFINITE);

terminate(0);
}

VOID main(VOID){
SERVICE_TABLE_ENTRY serviceTable[] =
{
{ SERVICE_NAME,(LPSERVICE_MAIN_FUNCTION) ServiceMain},
{ NULL, NULL }
};

BOOL success;
// Register with the SCM
success = StartServiceCtrlDispatcher(serviceTable);
if (!success)
ErrorHandler("In StartServiceCtrlDispatcher",GetLastError());
}
J_2004 2007-09-19
  • 打赏
  • 举报
回复
代码如下:
//
//***************************************************************
// From the book "Win32 System Services: The Heart of Windows NT"
// by Marshall Brain
// Published by Prentice Hall
//
// This code implements the simplest possible service.
// It beeps every 2 seconds, or at a user specified interval.
//***************************************************************

// beepserv.cpp

#include <WINDOWS.H>
#include <STDIO.H>
#include <IOSTREAM.H>
#include <STDLIB.H>

#define DEFAULT_BEEP_DELAY 3000

// Global variables

// The name of the service
char *SERVICE_NAME = "BeepService";
// Event used to hold ServiceMain from completing
HANDLE terminateEvent = NULL;
// Handle used to communicate status info with
// the SCM. Created by RegisterServiceCtrlHandler
SERVICE_STATUS_HANDLE serviceStatusHandle;
// The beep interval in ms.
int beepDelay = DEFAULT_BEEP_DELAY;
// Flags holding current state of service
BOOL pauseService = FALSE;
BOOL runningService = FALSE;
// Thread for the actual work
HANDLE threadHandle = 0;

void ErrorHandler(char *s, DWORD err)
{
cout && s && endl;
cout && "Error number: " && err && endl;
ExitProcess(err);
}

// This function consolidates the activities of
// updating the service status with
// SetServiceStatus
BOOL SendStatusToSCM (
DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode,
DWORD dwCheckPoint,
DWORD dwWaitHint){
BOOL success;
SERVICE_STATUS serviceStatus;

// Fill in all of the SERVICE_STATUS fields
serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = dwCurrentState;

// If in the process of doing something, then accept
// no control events, else accept anything
if (dwCurrentState == SERVICE_START_PENDING)
serviceStatus.dwControlsAccepted = 0;
else
serviceStatus.dwControlsAccepted =
SERVICE_ACCEPT_STOP ¦
SERVICE_ACCEPT_PAUSE_CONTINUE ¦
SERVICE_ACCEPT_SHUTDOWN;

// if a specific exit code is defined, set up
// the win32 exit code properly
if (dwServiceSpecificExitCode == 0)
serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
else
serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;

serviceStatus.dwCheckPoint = dwCheckPoint;
serviceStatus.dwWaitHint = dwWaitHint;

// Pass the status record to the SCM
success = SetServiceStatus (serviceStatusHandle, &serviceStatus);
return success;
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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