您的位置:首页 > 其它

windows系统服务的注册及运行服务方法

2009-01-08 12:42 459 查看
如果不想将程序放入注册表的启动项又想让程序随windows自动运行,那么可以通过将程序注册为windows服务来达到自动运行的效果。步骤可分为两步,第一:首先将要启动的程序进行注册加入至服务中。第二:在程序中响应服务控制的请求,这一步必须要实现,否则当你在启动服务时会出现"错误10053:服务没有及时响应启动或控制请求"。

以下代码为注册及启动服务方法:

一、将程序注册为windows服务

(1)注册为服务:

BOOL CreateSampleService()
{
SC_HANDLE schSCManager;

// Open a handle to the SC Manager database.
schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights

if (NULL == schSCManager)
printf("OpenSCManager failed (%d)/n", GetLastError());

TCHAR szPath[MAX_PATH];

strcpy(szPath, "E://tttt//Debug//tttt.exe");
SC_HANDLE schService = CreateService(
schSCManager, // SCManager database
TEXT("MyServer"), // name of service
"Application Service", // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password

if (schService == NULL)
{
printf("CreateService failed (%d)/n", GetLastError());
return FALSE;
}
else
{
if ( !StartService(schService, NULL, NULL) )

{

CloseServiceHandle(schService);

printf("StartService failed (%d)/n", GetLastError());

return FALSE;

}

CloseServiceHandle(schService);
return TRUE;
}
}

(2)删除服务

BOOL DeleteSampleService()
{
SC_HANDLE schSCManager;

// Open a handle to the SC Manager database.
schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights

if (NULL == schSCManager)
printf("OpenSCManager failed (%d)/n", GetLastError());

SC_HANDLE schService = OpenService(
schSCManager, // SCManager database
TEXT("MyServer"), // name of service
DELETE); // only need DELETE access

if (schService == NULL)
{
printf("OpenService failed (%d)/n", GetLastError());
return FALSE;
}

if (! DeleteService(schService) )
{
printf("DeleteService failed (%d)/n", GetLastError());
return FALSE;
}
else
printf("DeleteService succeeded/n");

CloseServiceHandle(schService);
return TRUE;
}

二、响应服务的程序实现

/*
响应系统服务的程序执行方法
*/
#include <stdio.h>
#include <windows.h>
#include <winsvc.h>

// 服务名称,如果服务为SERVICE_WIN32_OWN_PROCESS 类型,则服务名称被忽略
#define SERVICE_NAME "MyServer"

// 启动服务入口函数
void WINAPI MyServiceMain(DWORD argc, LPTSTR *argv);
// 服务控制函数
void WINAPI MyServiceControl(DWORD nControlCode);
// 服务所执行函数
BOOL MyExecuteService();
// 服务终止函数
void MyTerminateService();
// 服务运行后的处理线程
DWORD WINAPI MyServiceProc(LPVOID lpParameter);
// 更新服务状态
BOOL MyUpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,DWORD dwWaitHint);

// 服务状态句柄
SERVICE_STATUS_HANDLE hServiceStatus;
DWORD ServiceCurrentStatus;
HANDLE hServiceThread;
BOOL bServiceRunning;
HANDLE hServiceEvent;

// 信息输出
VOID SvcDebugOut(LPSTR String, DWORD Status)
{
CHAR Buffer[1024];
if (strlen(String) < 1000)
{
sprintf(Buffer, String, Status);
OutputDebugStringA(Buffer);
}
}

void main(int argc, char* argv[])
{
// 服务入口表, ServiceMain为响应服务函数
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{ SERVICE_NAME, MyServiceMain },
{ NULL, NULL}
};

if(!StartServiceCtrlDispatcher(ServiceTable))
{
SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher (%d)/n",
GetLastError());
}
}

void WINAPI MyServiceMain(DWORD argc, LPTSTR *argv)
{
// 这里可获得指定的服务启动参数个数,及参数内容
char ddd[128] = {'/0'};
sprintf(ddd, "参数共有%d个", argc);

// 注册服务控制回调
hServiceStatus = RegisterServiceCtrlHandler(SERVERNAME,(LPHANDLER_FUNCTION)MyServiceControl);
if(!hServiceStatus || !MyUpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,3000))
{
return;
}

// 创建等待事件
hServiceEvent = CreateEvent(0,TRUE,FALSE,0);
if(!hServiceEvent || !MyUpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,2,1000))
{
return;
}

// 运行服务
if( !MyExecuteService() )
{
return;
}

ServiceCurrentStatus = SERVICE_RUNNING;

if(!MyUpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0))
{
return;
}

// 等待受信
WaitForSingleObject(hServiceEvent,INFINITE);
CloseHandle(hServiceEvent);

}

// 服务消息处理线程
void WINAPI MyServiceControl(DWORD dwControlCode)
{
switch(dwControlCode)
{
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
ServiceCurrentStatus = SERVICE_STOP_PENDING;
MyUpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);
MyTerminateService();
return;
default:
break;
}

MyUpdateServiceStatus(ServiceCurrentStatus,NO_ERROR,0,0,0);
}

// 执行服务内容线程
BOOL MyExecuteService()
{
DWORD dwThreadID;
// 启动服务线程
hServiceThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)MyServiceProc,0,0,&dwThreadID);

if(hServiceThread != NULL)
{
bServiceRunning = TRUE;
return TRUE;
}
else
{
return FALSE;
}
}

// 停止服务时执行的方法
void MyTerminateService()
{
// ::MessageBox(NULL, "hello","you kill me ?", MB_ICONWARNING | MB_TOPMOST);
bServiceRunning = FALSE;
SetEvent(hServiceEvent);
MyUpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0);
}

// 所要进行的操作在此线程中处理
DWORD WINAPI MyServiceProc(LPVOID lpParameter)
{
while(bServiceRunning)
{
Beep(450,150);
Sleep(4000);
}

return 0;
}

BOOL MyUpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,DWORD dwWaitHint)
{
SERVICE_STATUS ServiceStatus;
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = dwCurrentState;

if(dwCurrentState == SERVICE_START_PENDING)
{
ServiceStatus.dwControlsAccepted = 0;
}
else
{
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
}

if(dwServiceSpecificExitCode == 0)
{
ServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
}
else
{
ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
}

ServiceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
ServiceStatus.dwCheckPoint = dwCheckPoint;
ServiceStatus.dwWaitHint = dwWaitHint;

if(!SetServiceStatus(hServiceStatus,&ServiceStatus))
{
MyTerminateService();
return FALSE;
}
return TRUE;
}

实现以上方法后程序即可成为windows服务运行了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: