windows服务有两种,一种是驱动服务程序,另外一种是win32服务程序,我们这里只谈win32服务程序,
查看win32服务程序,可以这样:开始->运行->services.msc可以打开windows自带的服务程序控制程
序。这个大家都应该很熟悉了吧。下面来讲讲利用vc编程来对win32服务程序进行管理,包括创建、删除
已经对win32服务程序的运行状态进行管理。
在进入编程之前先要理解几样东西:
第一:服务控制管理器 service control manager(SCM),SCM在系统启动的时候就会启动,其主要的
作用有以下几个方面:
1)维持了一张已安装的服务的数据表
2)根据策略在系统启动时启动服务或者在需要的时候启动服务
4)枚举已经安装的服务
4)维持了正在运行的服务的状态信息
5)向正在运行的服务发送控制信息
6)对服务数据库的锁定管理
SCM所维持的数据库可以在注册表中找到:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services
SCM通过三类程序的方法来实现对服务的管理:Service program、Service configuration program 和
Service control program
Service Program: 也就是被注册成服务的程序主体,他必须符合服务控制器(SCM)的接口规范,这样
才能被SCM控制(包括启动,停止等等),一个服务程序内可以包含一个服务或多个服务的执行代码,但
是它们都拥有固定的三个部分:服务main函数,服务ServiceMain函数和服务Control Handler函数。
服务main函数:入口点函数,由于服务程序通常是以控制台的方式存在的,所以它们的入口点自然就是
main函数。在服务控制管理器开始一个服务程序时,会等待StartServiceCtrlDispatcher函数的执行。
如果服务类型是SERVICE_WIN32_OWN_PROCESS就会立即调用StartServiceCtrlDispatcher函数的执行;如
果服务类型是SERVICE_WIN32_SHARE_PROCESS,通常在初始化所有服务之后再调用它。
StartServiceCtrlDispatcher这个函数的作用就是把服务入口点函数和SCM连接起来。
服务ServiceMain函数:函数ServiceMain是服务的入口点。在服务控制程序请求一个新的服务启动时,
服务控制管理器启动一个服务,并发送一个开始请求到控制调度程序,而后控制调度程序创建一个新线
程来执行ServiceMain函数。ServiceMain须执行以下的任务:调用RegisterServiceCtrlHandler函数注
册一个HandlerEx函数来向服务发送控制请求信息,返回值是服务状态句柄用来向服务控制管理器传送服
务状态。初始化后调用SetServiceStatus函数设置服务状态为SERVICE_RUNNING。最后,就是执行服务所
要完成的任务。
服务Control Handler函数:每个服务都有一个控制句柄HandlerEx函数。它会在服务进程从服务控制程
序接收到一个控制请求时被控制调度程序所调用。无论何时在HandlerEx函数被调用时,都要调用
SetServiceStatus函数向服务控制管理器报告它当前的状态。在用户关闭系统时,所有的控制句柄都会
调用带有SERVICE_ACCEPT_SHUTDOW控制代码的SetServiceStatus函数来接收NSERVICE_CONTROL_SHUTDOWN
控制代码。
这里是一个 Service program的例子:
实现的功能就是打开一个端口一直监听,连接上来之后,发送一串数据,然后关闭连接。
#include "Afxwin.h"
#include "windows.h"
#include "stdio.h"
#include "winsock2.h"
#pragma comment(lib,"ws2_32")
HANDLE hMutex;
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
//Service Control Handler Function
void WINAPI CmdControl(DWORD dwCode)
{
switch(dwCode)
{
case SERVICE_CONTROL_PAUSE:
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
WaitForSingleObject(hMutex,INFINITE);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)
{
printf("SetServiceStatus in CmdControl in Switch Error !/n");
}
return ;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)
{
printf("SetServiceStatus in CmdControl out Switch Error !/n");
}
return ;
}
listenPort()
{
WSADATA wsa;
SOCKET sServer;
SOCKET sClient;
struct sockaddr_in sin;
WSAStartup(MAKEWORD(2,2),&wsa);
sServer = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sServer==INVALID_SOCKET)
{
printf("Socket Error !/n");
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons(20540);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if(bind(sServer,(const struct sockaddr *)&sin,sizeof(sin))==SOCKET_ERROR)
{
printf("Bind Error !/n");
return -1;
}
if(listen(sServer,5)==SOCKET_ERROR)
{
printf("Listen Error !/n");
return -1;
}
hMutex=CreateMutex(NULL,FALSE,NULL);
if(hMutex==NULL)
{
printf("Create Mutex Error !/n");
}
while(1)
{
sClient=accept(sServer,NULL,NULL);
send(sClient,"aa",sizeof("aa"),0);
closesocket(sClient);
Sleep(1000);
}
WSACleanup();
}
//Service ServiceMain Function
void WINAPI CmdStart(DWORD dwArgc,LPTSTR *lpArgv)
{
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP
| SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatusHandle=RegisterServiceCtrlHandler("ntkrnl",CmdControl); //注册控制响应
程序
if(ServiceStatusHandle==0)
{
printf("RegisterServiceCtrlHandler Error !/n");
return ;
}
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)
{
printf("SetServiceStatus in CmdStart Error !/n");
return ;
}
listenPort();
return ;
}
int main()
{
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{"ntkrnl",CmdStart},
{NULL ,NULL }
};
StartServiceCtrlDispatcher(DispatchTable); //注意:CmdStart函数
return 0;
}
Service Configuration Programs:其作用有两个方面,第一是创建、删除和枚举服务,第二是用来更
改或者查询已经安装的服务的信息。完成这些任务可以直接操作注册表,但是最好还是使用SCM 配置函
数。
SCM 配置函数需要一个SCManger对象或者一个service对象,要获得这些对象可以使用OpenSCManager函
数,或者使用OpenService、CreateService获得service对象。
这里顺便就把Service Control Programs说了,其实也就是包含一些函数可以控制服务的启动,停止,
相应的函数可以在msdn查询。
下面是一个创建服务的例子,首先使用OpenSCMagenager获得一个SCManger对象,然后使用
CreateService创建一个服务。
#include "windows.h"
#include "stdio.h"
#include "Winsvc.h"
#include "TCHAR.h"
#pragma comment(lib,"Advapi32.lib")
int main()
{
SC_HANDLE schManager;
SC_HANDLE schService;
DWORD dwBytesNeeded;
LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
LPSERVICE_DESCRIPTION lpServiceDescription = NULL;
SERVICE_STATUS ServiceStatus;
DWORD dwIndex;
schManager = OpenSCManager
(NULL,NULL,SC_MANAGER_ALL_ACCESS);//SC_MANAGER_ALL_ACCESS);
if(schManager == NULL)
{
printf("OpenschManager Error: %d/n",GetLastError());
return FALSE;
}
SC_HANDLE hdlServ = CreateService(
schManager,
_T("test"),
_T("test"),
SC_MANAGER_ALL_ACCESS,
0x00000010,
3,
//SERVICE_ALL_ACCESS,
//SERVICE_WIN32_OWN_PROCESS,
//SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
_T("d://test.exe"), //这个就是由上面那个程序生成的
exe文件
NULL,NULL,NULL,NULL,NULL
);
if (hdlServ == NULL)
{
DWORD gg = GetLastError();
printf("error!/n");
}
hdlServ = OpenService(schManager,_T
("test"),SC_MANAGER_ALL_ACCESS);//SERVICE_ALL_ACCESS);
if (hdlServ == NULL)
{
printf("OpenSerivce error/n");
}
/*
if (!DeleteService(hdlServ))
{
printf("delete error/n");
}
*/
//查看服务状态
SERVICE_STATUS ss;
if(QueryServiceStatus(hdlServ, &ss) == FALSE)
{
printf("Error Service Status! %d/n", GetLastError());
return FALSE;
}
//如果服务已经启动,则退出
if(ss.dwCurrentState == SERVICE_RUNNING)
return TRUE;
//启动服务
StartService(hdlServ, 0, NULL);
Sleep(1000);
//查看服务状态
if(QueryServiceStatus(hdlServ, &ss) == FALSE)
{
printf("Error Service Status! %d/n", GetLastError());
return FALSE;
}
if(ss.dwCurrentState != SERVICE_RUNNING)
{
printf("Error in Starting Service! %d/n", GetLastError());
CloseHandle(hdlServ);
return FALSE;
}
printf("/nend/n");
return 0;
}
最后,再举一个例子。
ServiceAll()枚举所有的服务,并打印出来
ServiceInformation(char *szServiceName)查询特定服务的具体信息
#include "windows.h"
#include "stdio.h"
#include "Winsvc.h"
#include "TCHAR.h"
#pragma comment(lib,"Advapi32.lib")
BOOL ServiceAll()
{
SC_HANDLE schManager;
DWORD dwServiceType;
DWORD dwServiceState;
DWORD dwIndex;
DWORD cbBufSize;
DWORD ResumeHandle;
DWORD cbBytesNeeded;
DWORD ServicesReturned;
ENUM_SERVICE_STATUS EnumStatus[512];
schManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(schManager == NULL)
{
printf("OpenschManager Error: %d/n",GetLastError());
return FALSE;
}
dwServiceType = SERVICE_WIN32;
dwServiceState = SERVICE_STATE_ALL;
cbBufSize = sizeof(EnumStatus);
cbBytesNeeded = 0;
ServicesReturned = 0;
ResumeHandle = 0;
if(!EnumServicesStatus(schManager,dwServiceType,dwServiceState,
EnumStatus,cbBufSize,&cbBytesNeeded,
&ServicesReturned,&ResumeHandle))
{
cbBufSize += cbBytesNeeded;
if(!EnumServicesStatus(schManager,dwServiceType,dwServiceState,
EnumStatus,cbBufSize,&cbBytesNeeded,
&ServicesReturned,&ResumeHandle))
{
printf("EnumServicesStatus Error: %d/n",GetLastError());
return FALSE;
}
else
{
printf("Services:/t %d/n",ServicesReturned);
}
}
printf("/t/t=== Services ===/n/n");
printf("%-20s/t%-10s%s/n/n","ServiceName","Status","DisplayName");
for(dwIndex = 0;dwIndex < ServicesReturned; dwIndex ++)
{
printf("%-20s/t",EnumStatus[dwIndex].lpServiceName);
switch(EnumStatus[dwIndex].ServiceStatus.dwCurrentState)
{
case SERVICE_STOPPED:
printf("%-10s","Stopped");
break;
case SERVICE_START_PENDING:
printf("%-10s","Starting");
break;
case SERVICE_STOP_PENDING:
printf("%-10s","Stopping");
break;
case SERVICE_RUNNING:
printf("%-10s","Running");
break;
case SERVICE_CONTINUE_PENDING:
printf("%-10s","Continue");
break;
case SERVICE_PAUSE_PENDING:
printf("%-10s","Pausing");
break;
case SERVICE_PAUSED:
printf("%-10s","Paused");
break;
default:
printf("%-10s","");
break;
}
printf("%s/n",EnumStatus[dwIndex].lpDisplayName);
}
printf("/nTotal:/t %d/n",ServicesReturned);
if(schManager != NULL)
{
CloseServiceHandle(schManager);
}
return TRUE;
}
BOOL ServiceInformation(char *szServiceName)
{
SC_HANDLE schManager;
SC_HANDLE schService;
DWORD dwBytesNeeded;
LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
LPSERVICE_DESCRIPTION lpServiceDescription = NULL;
SERVICE_STATUS ServiceStatus;
DWORD dwIndex;
schManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(schManager == NULL)
{
printf("OpenschManager Error: %d/n",GetLastError());
return FALSE;
}
schService = OpenService(schManager,szServiceName,SERVICE_ALL_ACCESS);
if(schService == NULL)
{
if(GetLastError() == ERROR_INVALID_NAME)
{
printf("%s no Found !/n",szServiceName);
return TRUE;
}
printf("OpenService Error: %d/n",GetLastError());
return FALSE;
}
lpServiceConfig = (LPQUERY_SERVICE_CONFIG)malloc(1024*8);
printf("/t/t=== Configuration ===/n/n");
if(!QueryServiceConfig(schService,lpServiceConfig,1024*8,&dwBytesNeeded))
{
printf("QueryServiceConfig Error: %d/n",GetLastError());
}
else
{
if(lpServiceConfig->lpDisplayName != NULL)
printf("DisplayName:/t %s/n",lpServiceConfig->lpDisplayName);
if(lpServiceConfig->dwTagId != 0)
printf("TagID:/t/t %d/n",lpServiceConfig->dwTagId);
printf("FilePath:/t %s/n",lpServiceConfig->lpBinaryPathName);
printf("ServiceType:/t ");
switch(lpServiceConfig->dwServiceType)
{
case SERVICE_WIN32_OWN_PROCESS:
printf("Win32 Own Process/n");
break;
case SERVICE_WIN32_SHARE_PROCESS:
printf("Win32 Share Process/n");
break;
default:
printf("/n");
break;
}
printf("StartType:/t ");
switch(lpServiceConfig->dwStartType)
{
case SERVICE_AUTO_START:
printf("Auto Start/n");
break;
case SERVICE_BOOT_START:
printf("Boot Start/n");
break;
case SERVICE_DEMAND_START:
printf("Demand Start/n");
break;
case SERVICE_DISABLED:
printf("Disabled/n");
break;
case SERVICE_SYSTEM_START:
printf("System Start/n");
break;
default:
printf("/n");
break;
}
printf("ErrorControl:/t ");
switch(lpServiceConfig->dwErrorControl)
{
case SERVICE_ERROR_IGNORE:
printf("Ignore/n");
break;
case SERVICE_ERROR_NORMAL:
printf("Normal/n");
break;
case SERVICE_ERROR_SEVERE:
printf("Server/n");
break;
case SERVICE_ERROR_CRITICAL:
printf("Critical/n");
break;
default:
printf("/n");
break;
}
if(lpServiceConfig->lpServiceStartName != NULL)
printf("StartName:/t %s/n",lpServiceConfig->lpServiceStartName);
printf("LoadOrderGroup:/t ");
if(lpServiceConfig->lpLoadOrderGroup[0] != '/0')
{
printf("%s/n",lpServiceConfig->lpLoadOrderGroup);
}
else
{
printf("(none)/n");
}
dwIndex = 0;
printf("Dependendencies: ");
if(lpServiceConfig->lpDependencies[0] != '/0')
{
while(lpServiceConfig->lpDependencies[dwIndex] != '/0'
|| lpServiceConfig->lpDependencies[dwIndex+1] != '/0')
{
if(lpServiceConfig->lpDependencies[dwIndex] == '/0')
{
printf("; ");
}
else
{
printf("%c",lpServiceConfig->lpDependencies
[dwIndex]);
}
dwIndex ++;
}
}
else
{
printf("(none)");
}
printf("/n");
}
if(!QueryServiceStatus(schService,&ServiceStatus))
{
printf("QueryServiceStatus Error: %d/n",GetLastError());
}
else
{
printf("CurrentState:/t ");
switch(ServiceStatus.dwCurrentState)
{
case SERVICE_CONTINUE_PENDING:
printf("Continue/n");
break;
case SERVICE_PAUSE_PENDING:
printf("Pausing/n");
break;
case SERVICE_PAUSED:
printf("Paused/n");
break;
case SERVICE_RUNNING:
printf("Running/n");
break;
case SERVICE_START_PENDING:
printf("Starting/n");
break;
case SERVICE_STOP_PENDING:
printf("Stopping/n");
break;
case SERVICE_STOPPED:
printf("Stopped/n");
break;
default:
printf("/n");
break;
}
printf("Win32ExitCode:/t %d/n",ServiceStatus.dwWin32ExitCode);
printf("SpecialExitCode: %d/n",ServiceStatus.dwServiceSpecificExitCode);
printf("CheckPoint:/t %d/n",ServiceStatus.dwCheckPoint);
printf("WaitHint:/t %d/n",ServiceStatus.dwWaitHint);
}
lpServiceDescription = (LPSERVICE_DESCRIPTION) malloc(1024*8);
if(!QueryServiceConfig2(schService,SERVICE_CONFIG_DESCRIPTION,(LPBYTE)
lpServiceDescription,
8*1024,&dwBytesNeeded))
{
printf("QueryServiceConfig2 Error: %d/n",GetLastError());
}
else
{
printf("Description:/t %s/n",lpServiceDescription->lpDescription);
}
if(lpServiceConfig != NULL)
{
free(lpServiceConfig);
}
if(lpServiceDescription != NULL)
{
free(lpServiceDescription);
}
if(schService != NULL)
{
CloseServiceHandle(schService);
}
if(schManager != NULL)
{
CloseServiceHandle(schManager);
}
return TRUE;
}
BOOL ServiceControl(char *szServiceName,DWORD dwSignature)
{
SC_HANDLE schManager;
SC_HANDLE schService;
SERVICE_STATUS ServiceStatus;
schManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(schManager == NULL)
{
printf("OpenschManager Error: %d/n",GetLastError());
return FALSE;
}
schService = OpenService(schManager,szServiceName,SERVICE_ALL_ACCESS);
if(schService == NULL)
{
if(GetLastError() == ERROR_INVALID_NAME)
{
printf("%s no Found !/n",szServiceName);
return TRUE;
}
printf("OpenService Error: %d/n",GetLastError());
return FALSE;
}
if(!QueryServiceStatus(schService,&ServiceStatus))
{
printf("QueryServiceStatus Error: %d/n",GetLastError());
}
else
{
if(dwSignature == 0)
{
if(ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
printf("Already Running !/n");
}
else
{
if(!StartService(schService,0,NULL))
{
printf("Start %s Error: %
d/n",szServiceName,GetLastError());
}
else
{
printf("Start %s Success !/n",szServiceName);
}
}
}
else if(dwSignature == 1)
{
if(ServiceStatus.dwCheckPoint == SERVICE_STOPPED)
{
printf("Already Stopped !/n");
}
else
{
if(!ControlService
(schService,SERVICE_CONTROL_STOP,&ServiceStatus))
{
printf("Stop %s Error: %
d/n",szServiceName,GetLastError());
}
else
{
Sleep(50);
while(ServiceStatus.dwCheckPoint ==
SERVICE_STOP_PENDING)
{
Sleep(30);
QueryServiceStatus
(schService,&ServiceStatus);
}
if(ServiceStatus.dwCurrentState != SERVICE_STOPPED)
{
printf("Stop %s Error: %
d/n",szServiceName,GetLastError());
}
else
{
printf("Stop %s Success !
/n",szServiceName);
}
}
}
}
else if(dwSignature == 2)
{
if(ServiceStatus.dwCurrentState != SERVICE_STOPPED)
{
if(!ControlService
(schService,SERVICE_CONTROL_STOP,&ServiceStatus))
{
printf("Stop %s Error: %
d/n",szServiceName,GetLastError());
return FALSE;
}
}
if(!DeleteService(schService))
{
printf("Delete %s Error: %d/n",szServiceName,GetLastError
());
}
else
{
printf("Delte %s Success !/n",szServiceName,GetLastError
());
}
}
}
if(schService != NULL)
{
CloseServiceHandle(schService);
}
if(schManager != NULL)
{
CloseServiceHandle(schManager);
}
return TRUE;
}
int main()
{
ServiceAll(); //查询所有服务
ServiceInformation("Serv-u"); //查询Serv-u这个服务
printf("/nend/n");
return 0;
}
后记:
开始没有懂起服务程序还有一定的规范,自己理解可以把任意的程序注册成服务,并且在网上看到一篇
文章叫“让程序以服务形式运行”,他利用instsrv.exe把QQ注册成服务了,然后我测试发现确实可以注
册成服务成功,但是不能正常启动,搞的我整了N久,后来也去搞了instsrv.exe来测试,发觉确实不能
//DEMO2
#include "stdafx.h "
#include "jiankong.h "
#include "winsvc.h "
#include <atlbase.h> //CRegKey类需要的头文件
#include <Afxtempl.h> //CArray类需要的头文件
#include <tlhelp32.h> //ToolHelp函数需要的头文件
#include "pop3.h "
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// The one and only application object
CWinApp theApp;
using namespace std;
SERVICE_STATUS_HANDLE ssh;
SC_HANDLE scm,svc;
SERVICE_STATUS ss;
CArray <PROCESSENTRY32,PROCESSENTRY32 &> m_PEArray;
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
void WINAPI Handler(DWORD Opcode);
void InstallService();
UINT jiankong(LPVOID lpvoid);
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr < < _T( "Fatal Error: MFC initialization failed ") < < endl;
nRetCode = 1;
}
else
{
// TODO: code your application 's behavior here.
SERVICE_TABLE_ENTRY ste[2];
//线程入口表
ste[0].lpServiceName= "jiankong "; //线程名字
ste[0].lpServiceProc=ServiceMain; //线程入口地址
//可以有多个线程,最后一个必须为NULL
ste[1].lpServiceName=NULL;
ste[1].lpServiceProc=NULL;
StartServiceCtrlDispatcher(ste);
InstallService();
}
return nRetCode;
}
//安装并启动服务
void InstallService()
{
LPTSTR lpSysPath=new char[MAX_PATH];
::GetSystemDirectory(lpSysPath,MAX_PATH);
LPCTSTR lpsysfilename;
lpsysfilename=(LPCTSTR)lstrcat(lpSysPath, "//jiankong.exe ");
scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(scm!=NULL)
svc=CreateService(scm, "jiankong ", "jiankong ",SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,SERVICE_AUTO_START,SERVICE_ERROR_IGNORE,lpsysfilename,NULL,NULL,NULL,NULL,NULL);
if(svc!=NULL)
svc=OpenService(scm, "jiankong ",SERVICE_START);
if (svc!=NULL)
{
StartService(svc,0,NULL);
CloseServiceHandle(svc);
}
CloseServiceHandle(scm);
}
//服务的真正入口点函数
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
ss.dwServiceType = SERVICE_WIN32;
ss.dwCurrentState = SERVICE_START_PENDING;
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP| SERVICE_ACCEPT_PAUSE_CONTINUE;
ss.dwServiceSpecificExitCode = 0;
ss.dwWin32ExitCode = 0;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
ssh=RegisterServiceCtrlHandler( "jiankong ",Handler);
ss.dwCurrentState = SERVICE_RUNNING;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
SetServiceStatus(ssh,&ss);
AfxBeginThread(jiankong,NULL,NULL); //开始一个工作线程实现程序功能
ss.dwCurrentState = SERVICE_RUNNING;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
SetServiceStatus(ssh,&ss);
}
//处理服务要求
void WINAPI Handler(DWORD Opcode)
{
switch(Opcode)
{
case SERVICE_CONTROL_STOP:
ss.dwCurrentState =SERVICE_STOPPED;
SetServiceStatus (ssh,&ss);
break;
case SERVICE_CONTROL_CONTINUE:
ss.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (ssh,&ss);
break;
case SERVICE_CONTROL_PAUSE:
ss.dwCurrentState = SERVICE_PAUSED;
SetServiceStatus (ssh,&ss);
break;
case SERVICE_CONTROL_INTERROGATE:
break;
}
SetServiceStatus (ssh,&ss);
}
//在进程列表中监控邮箱进程的线程函数
UINT jiankong(LPVOID lParam)
{
::Sleep(600000);
if (!AfxSocketInit())
{
AfxMessageBox( "error ");
return 0;
}
CPop3 m_pop;//用来进行连接的pop3类对象
while(1)
{
if(!m_pop.Connect( "10.231.235.244 ", "kaifabu ", "88888 ",110))
{
// AfxMessageBox(_T( "无法与服务器建立连接! "));
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1; // 设置一个权限
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0);
}
m_pop.Disconnect();
}
return 0;
}