用C/C++创建windows服务程序
Posted 小哈龙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C/C++创建windows服务程序相关的知识,希望对你有一定的参考价值。
一、演示过程
下方代码演示了如何使用vs(C/C++)创建windows服务程序
工程文件下载地址: http://download.csdn.net/download/sooth2008/2759082
使用visual studio创建一个win32控制台应用程序,编译后就OK了。
然后开始->运行->cmd->回车,输入 sc create test binPath= 编译成功后的可执行文件的路径回车就创建了一个服务.
注意这里的格式,“=”后面是必须空一格的,否则会出现错误。
然后开始->运行->services.msc->回车就可以看到刚刚创建的服务了。
描述:
SC 是用于与服务控制管理器和服务进行通信的命令行程序。
用法:
sc <server> [command] [service name] <option1> <option2>...
选项 <server> 的格式为 "\\\\ServerName"
键入 "sc [command]" 可以获得有关命令的进一步帮助
命令:
query-----------查询服务的状态,
或枚举服务类型的状态。
queryex---------查询服务的扩展状态,
或枚举服务类型的状态。
start-----------启动服务。
pause-----------向服务发送 PAUSE 控制请求。
interrogate-----向服务发送 INTERROGATE 控制请求。
continue--------向服务发送 CONTINUE 控制请求。
stop------------向服务发送 STOP 请求。
config----------更改服务的配置(永久)。
description-----更改服务的描述。
failure---------更改服务失败时执行的操作。
failureflag-----更改服务的失败操作标志。
sidtype---------更改服务的服务 SID 类型。
privs-----------更改服务的所需权限。
qc--------------查询服务的配置信息。
qdescription----查询服务的描述。
qfailure--------查询失败时服务执行的操作。
qfailureflag----查询服务的失败操作标志。
qsidtype--------查询服务的服务 SID 类型。
qprivs----------查询服务的所需权限。
delete----------(从注册表)删除服务。
create----------创建服务(将其添加到注册表)。
control---------向服务发送控制。
sdshow----------显示服务的安全描述符。
sdset-----------设置服务的安全描述符。
showsid---------显示相应于假定名称的 SID 字符串。
GetDisplayName--获取服务的 DisplayName。
GetKeyName------获取服务的 ServiceKeyName。
EnumDepend------枚举服务的依存关系。
示例:
sc start MyService
----------------------------------
实际上sc所完成的功能就是“控制面板.管理工具”中看到的“服务”完成的功能。
在命令行中输入下面的命令,可以看到详细语法:
----------------------------------
sc config hlep
----------------------------------
sc config 服务名 start= AUTO (自动)
sc config 服务名 start= DEMAND (手动)
sc config 服务名 start= DISABLED(禁用)
注意:等号后面必须有一个空格。
1、启动服务:
右键点击->启动 大功告成。(或者在提示建立成功后,可以直接输入“net start Test” 来启动服务)
此时可以在任务栏管理器中看到这个exe在运行。
PS:该服务每隔5秒往d:/test.txt 写入一条记录你的代码就应该加在srv_core_thread中,当然你也可以添加多个类似srv_core_thread的线程.
在服务停止时我们可以看到D:\\下生成了test.txt文档
异常情况:假如启动服务时提示
这是因为运行作为服务的应用程序不是按服务的流程写的。所以运行提示“ 服务没有及时响应启动或控制请求”
2、停止服务
3、删除服务 :
在 "开始->运行->cmd" 中输入 sc delete TEST
此时虽然把服务删除了,但是从->services.msc->还是可以看到test服务的状态不审“已经启动".
任务栏管理器上还是有此进程的存在。
4、
这样在开机会会自动启动此服务,经实验,在XP开机弹出登陆框时,服务已经启动了。
问题:何时加载这些服务?
答: 请参照我的文章:<<Winlogon、LSASS、Userinit>>
里面有这样一句“winlogon创建服务控制管理器(SCM)进程(\\windows\\system32\\Services.exe),而SCM进程又依次加载所有被标记为自动-启动斩服务和设备驱动程序”。
5、在服务启动时弹出窗口
void WINAPI service_main(int argc, char** argv)
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hServiceStatusHandle = RegisterServiceCtrlHandler(_T(SERVICE_NAME), ServiceHandler);
if (hServiceStatusHandle==0)
DWORD nError = GetLastError();
::MessageBox(NULL, L"Service test start Ok", L"OK", MB_OK);
运行时出现提示:
6、脚本启动服务
打开一个Txt,写上下面的内容,保存“服务名.bat”文
:启动服务名
echo 启动服务名
net start 服务名
pause
关闭也一样(打开一个Txt,写上下面的内容,保存“服务名.bat”文件):
:关闭服务名
echo 关闭服务名
net stop 服务名
pause
@echo off
sc.exe create test type= own type= interact start= auto binPath= %CD%\\test.exe
二、代码
1、不加服务事件
/*******************************************************************************
Written by: shiyang sun
First: you can used this code free,absolutely free!
Second:of course,you can remove this header unconstrained!
but this header might useful if you sometimes want to kick my ass or praise me.
Copyright:none
Get more message on:http://blog.sina.com.cn/lipfreedom
Address:sunshiyang shenzhen city guangdong province china
E-mail:zyy6569@163.com
Create date:2010/10/14
********************************************************************************/
#include "stdafx.h"
#include "Windows.h"
#define SERVICE_NAME "srv_demo"
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hServiceStatusHandle;
void WINAPI service_main(int argc, char** argv);
void WINAPI ServiceHandler(DWORD fdwControl);
TCHAR szSvcName[80];
SC_HANDLE schSCManager;
SC_HANDLE schService;
int uaquit;
FILE* log;
DWORD WINAPI srv_core_thread(LPVOID para)
int i = 0;
for(;;)
if(uaquit)
break;
fprintf(log,"srv_core_thread run time count:%d\\n",i++);
Sleep(5000);
return NULL;
void WINAPI ServiceHandler(DWORD fdwControl)
switch(fdwControl)
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
uaquit= 1;
//add you quit code here
if(log != NULL)
fclose(log);
break;
default:
return;
;
if (!SetServiceStatus(hServiceStatusHandle, &ServiceStatus))
DWORD nError = GetLastError();
void WINAPI service_main(int argc, char** argv)
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hServiceStatusHandle = RegisterServiceCtrlHandler(_T(SERVICE_NAME), ServiceHandler);
if (hServiceStatusHandle==0)
DWORD nError = GetLastError();
//add your init code here
log = fopen("d:\\\\test.txt","w");
//add your service thread here
HANDLE task_handle = CreateThread(NULL,NULL,srv_core_thread,NULL,NULL,NULL);
if(task_handle == NULL)
fprintf(log,"create srv_core_thread failed\\n");
// Initialization complete - report running status
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 9000;
if(!SetServiceStatus(hServiceStatusHandle, &ServiceStatus))
DWORD nError = GetLastError();
//do not change main function
int main (int argc, const char *argv[])
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = _T(SERVICE_NAME);
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)service_main;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// 启动服务的控制分派机线程
StartServiceCtrlDispatcher(ServiceTable);
return 0;
2、加服务事件
// ServiceTest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "stdio.h"
#include "tchar.h"
#include <windows.h>
#include<iostream>
using namespace std;
//定义全局函数变量
void Init();
BOOL IsInstalled();
BOOL Install();
BOOL Uninstall();
void LogEvent(LPCTSTR pszFormat, ...);
void WINAPI ServiceMain();
void WINAPI ServiceStrl(DWORD dwOpcode);
TCHAR szServiceName[] = _T("ServiceTest");
BOOL bInstall;
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
DWORD dwThreadID;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
Init();
dwThreadID = ::GetCurrentThreadId();
SERVICE_TABLE_ENTRY st[] =
szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain ,
NULL, NULL
;
if (stricmp(lpCmdLine, "/install") == 0)
Install();
else if (stricmp(lpCmdLine, "/uninstall") == 0)
Uninstall();
else
if (!::StartServiceCtrlDispatcher(st))
LogEvent(_T("Register Service Main Function Error!"));
return 0;
//*********************************************************
//Functiopn: Init
//Description: 初始化
//Calls: main
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
void Init()
hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
//*********************************************************
//Functiopn: ServiceMain
//Description: 服务主函数,这在里进行控制对服务控制的注册
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
void WINAPI ServiceMain()
// Register the control request handler
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
//注册服务控制
hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
if (hServiceStatus == NULL)
LogEvent(_T("Handler not installed"));
return;
SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hServiceStatus, &status);
//模拟服务的运行,10后自动退出。应用时将主要任务放于此即可
int i = 0;
while (i < 10)
//新建文件
FILE * fp0=fopen("c:/tt.txt","a");
fclose(fp0);
Sleep(10000);
i++;
//
status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &status);
LogEvent(_T("Service stopped"));
//*********************************************************
//Functiopn: ServiceStrl
//Description: 服务控制主函数,这里实现对服务的控制,
// 当在服务管理器上停止或其它操作时,将会运行此处代码
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input: dwOpcode:控制服务的状态
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
void WINAPI ServiceStrl(DWORD dwOpcode)
switch (dwOpcode)
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(hServiceStatus, &status);
PostThreadMessage(dwThreadID, WM_CLOSE, 0, 0);
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
LogEvent(_T("Bad service request"));
//*********************************************************
//Functiopn: IsInstalled
//Description: 判断服务是否已经被安装
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
BOOL IsInstalled()
BOOL bResult = FALSE;
//打开服务控制管理器
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM != NULL)
//打开服务
SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);
if (hService != NULL)
bResult = TRUE;
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return bResult;
//*********************************************************
//Functiopn: Install
//Description: 安装服务函数
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
BOOL Install()
if (IsInstalled())
return TRUE;
//打开服务控制管理器
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
MessageBox(NULL, _T("Couldn't open service manager"), szServiceName, MB_OK);
return FALSE;
// Get the executable file path
TCHAR szFilePath[MAX_PATH];
::GetModuleFileName(NULL, szFilePath, MAX_PATH);
//创建服务
SC_HANDLE hService = ::CreateService(
hSCM, szServiceName, szServiceName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, _T(""), NULL, NULL);
if (hService == NULL)
::CloseServiceHandle(hSCM);
MessageBox(NULL, _T("Couldn't create service"), szServiceName, MB_OK);
return FALSE;
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return TRUE;
//*********************************************************
//Functiopn: Uninstall
//Description: 删除服务函数
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
BOOL Uninstall()
if (!IsInstalled())
return TRUE;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
MessageBox(NULL, _T("Couldn't open service manager"), szServiceName, MB_OK);
return FALSE;
SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
if (hService == NULL)
::CloseServiceHandle(hSCM);
MessageBox(NULL, _T("Couldn't open service"), szServiceName, MB_OK);
return FALSE;
SERVICE_STATUS status;
::ControlService(hService, SERVICE_CONTROL_STOP, &status);
//删除服务
BOOL bDelete = ::DeleteService(hService);
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
if (bDelete)
return TRUE;
LogEvent(_T("Service could not be deleted"));
return FALSE;
//*********************************************************
//Functiopn: LogEvent
//Description: 记录服务事件
//Calls:
//Called By:
//Table Accessed:
//Table Updated:
//Input:
//Output:
//Return:
//Others:
//History:
// <author>niying <time>2006-8-10 <version> <desc>
//*********************************************************
void LogEvent(LPCTSTR pFormat, ...)
TCHAR chMsg[256];
HANDLE hEventSource;
LPTSTR lpszStrings[1];
va_list pArg;
va_start(pArg, pFormat);
_vstprintf(chMsg, pFormat, pArg);
va_end(pArg);
lpszStrings[0] = chMsg;
hEventSource = RegisterEventSource(NULL, szServiceName);
if (hEventSource != NULL)
ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
DeregisterEventSource(hEventSource);
版权声明:本文为CSDN博主「Jackchenyj」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chenyujing1234/article/details/8023816
以上是关于用C/C++创建windows服务程序的主要内容,如果未能解决你的问题,请参考以下文章