编写服务程序会用到这些函数:
*服务主函数
ServiceMain()
StartServiceCtrlDispatcher() //dispatcher n. 调度员;[计] 调度程序;[计] 分配器
*服务控制处理函数
ServiceCtrlHandle()
RegisterServiceCtrlHandle()
首先创建一个win32的空项目,然后添加源文件,编写代码
# include<stdio.h>
# include<stdlib.h>
# include<Windows.h>
# define FILE_PATH "e:\\log.txt"
# define SLEEP_TIME 5000
void ServiceMain(int argc, char **argv);//服务主函数
void WINAPI ServiceCtrlHandler(DWORD Opcode);//服务控制函数
SERVICE_STATUS m_ServiceStatus;//服务状态
SERVICE_STATUS_HANDLE m_ServiceStatusHandle;//服务状态句柄
int WriteToLog(char *str);
BOOL bRunning = TRUE;
int main() //服务程序入口也是main
{
SERVICE_TABLE_ENTRY DispatchTable[2]; //服务分派表
//要用到此结构
DispatchTable[0].lpServiceName = TEXT("服务名称");
DispatchTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
DispatchTable[1].lpServiceName = NULL;//数组最后一项一定要设为NULL(表示结束),这里只是简单的
//做一个例子,所以数组大小为2,一个程序可以有多个服务
DispatchTable[1].lpServiceProc = NULL;
//1:注册服务的主函数
StartServiceCtrlDispatcher(DispatchTable);
//服务控制分派器
//调用该函数,就会使用分派表里的主函数创建一个新的线程
system("pause");
return 0;
}
void ServiceMain(int argc, char **argv)
{
MEMORYSTATUS memstatus;
char str[100];
int availmb;//内存大小转换成以兆为单位的
//=========================1 设置服务状态=============================
m_ServiceStatus.dwServiceType = SERVICE_WIN32;
//服务当前状态
m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;//panding 待定,未发生的,挂起
//因为服务还未做好,正在初始化,所以当前的状态待定
//服务可接受的控制
m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
//这两个跟服务退出有关,都设为0
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwWin32ExitCode = 0;
//这两个一般都设为0,很少用到,如果服务启动时间超过了30秒,就需要改变这些参数了
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;//hint 暗示,提示
//===========================1 注册服务=================================
//注册服务控制函数
m_ServiceStatusHandle=RegisterServiceCtrlHandler(TEXT("服务名称"), ServiceCtrlHandler);
if (m_ServiceStatusHandle == 0)//注册失败
{
//失败就写入日志
WriteToLog("RegisterServiceCtrlHandler failed");
return;
}
WriteToLog("RegisterServiceCtrlHandler success");
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;//注册后就运行了
//将服务状态报告给服务控制器
SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
bRunning = TRUE;
//这个服务程序的例子就用来检查电脑内存大小吧
memset(&memstatus,'\0',100);
while (bRunning)
{
GlobalMemoryStatus(&memstatus);//检查电脑内存
availmb = memstatus.dwAvailPhys / 1024 / 1024;
sprintf_s(str, 100,"Available memory is %dMB", availmb);
WriteToLog(str);
//计算机运算速度太快,让每5秒钟就循环一次
Sleep(SLEEP_TIME);
}
WriteToLog("service stopped");
}
//当我们做好一个服务程序后,服务程序就会安装,可以在服务控制面板里找到,比如停止,启用服务等都是在
//服务控制函数里进行的
void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
switch (Opcode)
{
case SERVICE_CONTROL_STOP://停止服务
bRunning = FALSE;
m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
break;
case SERVICE_CONTROL_SHUTDOWN://电脑关机
bRunning = FALSE;
m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
break;
default:
break;
}
SetServiceStatus(m_ServiceStatusHandle,&m_ServiceStatus);
}
int WriteToLog(char *str)
{
FILE *pfile;
fopen_s(&pfile, FILE_PATH, "a+");
if (pfile == NULL)
return -1;
fprintf_s(pfile, "%s\n", str);
fclose(pfile);
return 0;
}
然后生成解决方案,为了后来使用cmd敲路径比较方便,把生成的.exe文件复制到c盘的test文件夹下吧,
这里我编写的服务名字是”服务名称”,然后安装服务,如果现在直接去看(右击计算机-管理-计算机管理(本地)-双击服务)的话,
是看不到的,这里可以用sc.exe工具去完成
按下Win+R键,输入cmd,回车,然后输入sc,回车,然后输入:
sc create 服务名称 binpath= c:\test\编写服务程序.exe
create表示根据自己写的服务程序创建一个服务,第三个是服务的名字,注意binpath和等于号之间有空格,后面就是解决方案生成的.exe文件所在路径了
然后再去查看,注意要 操作-刷新
这里要注意一点, !!可能会提示失败,访问权限不足,可以右击计算机-管理-计算机管理(本地)-系统工具-本地用户和组-用户-双击Administrator,将账户已禁用的勾去掉,重启就可以了,或者去注册表改也行,具体可以自己去搜
//安装后,在服务里刷新一下就可以看到编写的服务了
sc start 服务名称 //启用服务
sc delete 服务名称 //删除服务
这里实例的服务程序是用来检查可用运行内存大小的,将结果写入日志(文本文件),启用服务后,每五秒就循环检查一次并写入日志,这里是在e盘,
启用服务:
关闭该文本,再打开
关闭服务
删除服务的话只有用sc了,
这里删除不了,输入sc delete 服务名称
回车就可以删除了