// Service.cpp : Defines the entry point for the console application.
//

//服务程序主函数。

#include "stdafx.h"

#include "Windows.h"

#define SZAPPNAME      "serverSample"     //服务程序名

#define SZSERVICENAME  "serviceSample"    //标识服务的内部名

//内部变量

bool                   bDebugServer=false;

SERVICE_STATUS              ssStatus;

SERVICE_STATUS_HANDLE  sshStatusHandle;

DWORD                       dwErr=0;

TCHAR                       szErr[256];

//下面的函数由程序实现

void  WINAPI  Service_Main(DWORD dwArgc, LPTSTR *lpszArgv);

void  WINAPI  Service_Ctrl(DWORD dwCtrlCode);

void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv);//具体服务的初始化入口函数

void installService();

void removeService();

void debugService(int argc,char** argv);

bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint);

void AddToMessageLog(LPTSTR lpszMsg);

//int _tmain(int argc, _TCHAR* argv[])
int _tmain(int argc, TCHAR* argv[])

{

SERVICE_TABLE_ENTRY dispatchTable[]=
    {

{TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},

{ NULL,NULL}

};

if((argc>1)&&((*argv[1]=='-')||(argv[1]==TEXT("/"))))

{

if(_tcsicmp(TEXT("install"),argv[1]+1)==0)

{

installService();

}

else if(_tcsicmp(TEXT("remove"),argv[1]+1)==0)

{

removeService();

}

else if(_tcsicmp(TEXT("debug"),argv[1]+1)==0)

{

bDebugServer=true;

//debugService(argc,argv);

}

else

{        //如果未能和上面的如何参数匹配,则可能是服务控制管理程序来启动该程序。立即调用

//StartServiceCtrlDispatcher 函数。

printf("%s - install to install the service \n",SZAPPNAME);

printf("%s - remove to remove the service \n",SZAPPNAME);

printf("%s - debug to debug the service \n",SZAPPNAME);

printf("\n StartServiceCtrlDispatcher being called.\n");

printf("This may take several seconds.Please wait.\n");

if(!StartServiceCtrlDispatcher(dispatchTable))

AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));

else

AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));

}

exit(0);

}

return 0;

}

//服务入口点函数

void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv)    //具体服务的初始化入口函数
{
 printf("\n StartServiceCtrlDispatcher being called.\n");

}

void  WINAPI  Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)

{

//注册服务控制处理函数

sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);

//如果注册失败

if(!sshStatusHandle)

{

goto cleanup;

return;

}

//初始化 SERVICE_STATUS 结构中的成员

ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;

ssStatus.dwServiceSpecificExitCode=0;

//更新服务状态

if(!ReportStatusToSCMgr(

SERVICE_START_PENDING,//服务状态,The service is starting.

NO_ERROR,            //退出码

3000))                   //等待时间

goto cleanup;        //更新服务状态失败则转向 cleanup

ServiceStart(dwArgc,lpszArgv);

return;

cleanup:

//把服务状态更新为 SERVICE_STOPPED,并退出。

if(sshStatusHandle)

(void)ReportStatusToSCMgr(SERVICE_STOPPED,dwErr,0);

}

//控制处理程序函数

void WINAPI Service_Ctrl(DWORD dwCtrlCode)

{

//处理控制请求码

switch(dwCtrlCode)

{

// 先更新服务状态为 SERVICDE_STOP_PENDING,再停止服务。

case SERVICE_CONTROL_STOP:

ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

//ServiceStop();     //由具体的服务程序实现

return;

// 暂停服务

case SERVICE_CONTROL_PAUSE:

ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

//ServicePause();    //由具体的服务程序实现

ssStatus.dwCurrentState=SERVICE_PAUSED;

return;

// 继续服务

case SERVICE_CONTROL_CONTINUE:

ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

//ServiceContinue(); //由具体的服务程序实现

ssStatus.dwCurrentState=SERVICE_RUNNING;

return;

// 更新服务状态

case SERVICE_CONTROL_INTERROGATE:

break;

// 无效控制码

default:

break;

}

ReportStatusToSCMgr(ssStatus.dwCurrentState,NO_ERROR,0);

}

//安装服务程序

void installService()

{

SC_HANDLE schService;

SC_HANDLE schSCManager;

TCHAR szPath[512];

//得到程序磁盘文件的路径

if(GetModuleFileName(NULL,szPath,512)==0)

{

_tprintf(TEXT("Unable to install %s - %s \n"),

TEXT(SZAPPNAME),

GetLastError());//@1获取调用函数返回的最后错误码

return;

}

//打开服务管理数据库

schSCManager=OpenSCManager(

NULL,    //本地计算机

NULL,    //默认的数据库

SC_MANAGER_ALL_ACCESS  //要求所有的访问权

);

if(schSCManager)

{

// 登记服务程序

schService = CreateService(

schSCManager,                    //服务管理数据库句柄

TEXT(SZSERVICENAME),             //服务名

TEXT(SZAPPNAME),       //用于显示服务的标识

SERVICE_ALL_ACCESS,              //响应所有的访问请求

SERVICE_WIN32_OWN_PROCESS,       //服务类型

//SERVICE_DEMAND_START,            //启动类型
            SERVICE_AUTO_START,

SERVICE_ERROR_NORMAL,            //错误控制类型

szPath,                              //服务程序磁盘文件的路径

NULL,                                //服务不属于任何组

NULL,                                //没有tag标识符

NULL,              //启动服务所依赖的服务或服务组,这里仅仅是一个空字符串

NULL,                                //LocalSystem 帐号

NULL);

if(schService)

{

_tprintf(TEXT("%s installed. \n"),TEXT(SZAPPNAME));

CloseServiceHandle(schService);

}

else

{

_tprintf(TEXT("CreateService failed - %s \n"),GetLastError());

}

CloseServiceHandle(schSCManager);

}

else

_tprintf(TEXT("OpenSCManager failed - %s \n"),GetLastError());

}

void removeService()
{
    SC_HANDLE service, scm;             //定义服务句柄和服务控制管理数据库句柄
    SERVICE_STATUS status;                //定义服务状态结构
    //if (argc != 2)  return;             //如果命令行参数的个数小于2,则不执行卸载程序
    // 打开服务控制管理数据库,并返回服务控制管理数据库的句柄
    scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
    // 获得服务句柄,并添加服务访问中的删除选项
    //service = OpenService(scm, argv[1],SERVICE_ALL_ACCESS | DELETE);
    service = OpenService(scm, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS | DELETE);
    // 获得服务的当前状态
    QueryServiceStatus(service, &status);
    // 如果服务不处于停止状态,则将其状态设置为停止状态
    if (status.dwCurrentState != SERVICE_STOPPED)
        ControlService(service,SERVICE_CONTROL_STOP, &status);
    DeleteService(service);                // 删除服务
    CloseServiceHandle(service);        // 关闭新服务句柄
    CloseServiceHandle(scm);            // 关闭服务控制管理数据库句柄

}

void debugService(int argc,char** argv)
{

}

bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint)
{
   return true;
}

void AddToMessageLog(LPTSTR lpszMsg)
{

}

http://blog.chinaunix.net/u1/37538/showart_493320.html

http://www.wei2008.com/Code/softdown.asp?softid=35719

转载于:https://www.cnblogs.com/chenhs/archive/2010/07/14/1777635.html

windows nt service 框架相关推荐

  1. windows下dbca删除OracleserviceXXX时遇到错误:dim-00014 Cannot open the Windows NT Service Control Manager

    windows下dbca删除OracleserviceXXX时遇到错误:dim-00014 Cannot open the Windows NT Service Control Manager  O/ ...

  2. 为什么某些Win32技术在Windows NT服务中行为不当?

    弗兰克·金 服务是具有特殊要求的后台Win32进程.它需要一个独特的入口点和一个回调函数.回调函数被称为服务控制处理程序.新的入口点通常称为ServiceMain,但您可以任意命名. 本文假定您熟悉W ...

  3. Windows NT 4.0

    下载 第23章Windows NT 4.0 作者:Kurt Hudson 本章内容包括: • Windows NT版本 • 体系结构 • 安装Windows NT 4.0 • 配置T C P / I ...

  4. windows下rpc框架thrift的环境配置

    windows下rpc框架thrift的环境配置 引用链接: https://www.cnblogs.com/49er/p/7193829.html 最近在弄windows下 的Facebook的rp ...

  5. Windows NT体系结构

    Windows NT中的NT意为New Technology,其实Microsoft自从93年推出的第一个windows NT 3.1到即将发布的windows 7都属于NT版本的范畴,只不过是Win ...

  6. 如何在 Windows XP Service Pack 2 上启用 SQL Server 连接

    如何在 Windows XP Service Pack 2 上启用 SQL Server 连接 文章编号 : 841251 最后修改 : 2006年2月20日 修订 : 3.0 目录: 简介 为每个 ...

  7. Windows XP Service Pack 3 修复程序列表

    编号文章标题类别274261 (http://support.microsoft.com/kb/274261/)超级终端缓冲区历史可能出现损坏修复297694 (http://support.micr ...

  8. Windows NT引导过程源代码分析

    Windows 引导过程 Windows 内核中的各个组件和各种机制在起作用以前,必须首先被初始化.此初始化工作是在系统引导时完成的.当用户打开计算机的电源开关时,计算机便开始运行,但操作系统并不立即 ...

  9. 本地用户和组 无法访问计算机 无效的语法,找不到Windows NT用户或组“DOMAIN \ USER”?...

    7 个答案: 答案 0 :(得分:4) 这只表示用户不在Administrator组中.如果您的问题与我的问题类似,您的Active Directory位于不同的虚拟机上,而您的SQL Server位 ...

最新文章

  1. oracle 查询、创建、删除 数据库用户
  2. 开发日记-20190706 关键词 读书笔记 《Perl语言入门》Day 3
  3. 菜鸟教程-css学习笔记
  4. Android NDK各版本下载
  5. 使用Spring boot,Thymeleaf,AngularJS从零开始构建新的Web应用程序-第2部分
  6. GPU环境配置指南(Ubuntu16.04+CUDA+CUDNN)
  7. 2017.3.6~2017.3.7 Harry And Magic Box 思考记录(特别不容易)
  8. dubbo负载均衡代码分析1(leastactive策略)
  9. Linux Socket学习--面向非连接的协议
  10. 关于算法—— 一维字符串数组之间组合问题的C#实现
  11. 使用MSDN学习ASP.NET的工作流程
  12. 示波器wvf导入matlab,运动控制系统实验
  13. Unity EmbeddedBrowser浏览器插件事件通讯
  14. 简历||STAR法则
  15. lol服务器维护补偿,LOL官方:服务器崩溃补偿!全服再次免费赠送皮肤一款!
  16. 2022年施工员-土建方向-岗位技能(施工员)考题模拟考试平台操作
  17. 这图怎么画| 相关性热图+柱状图
  18. mysql根据成绩排名次_用mysql语句 实现按成绩 排名次
  19. linux系统删除lammps任务,Linux 的常用命令
  20. php 用count 变量,countif函数的使用方法 PHP的可变变量名的使用方法分享

热门文章

  1. 取得Servlet文件的絕對路徑;文件讀寫操作
  2. android jni jbyteArray转char*
  3. 【android】EGL数据结构
  4. WebKit如何加载web页面
  5. Unity3D学习笔记(七):叉乘和四元素
  6. Scrapy学习-24-集成elasticsearch
  7. 页面按钮埋点+跟踪location.search
  8. element-ui的NavMenu置于顶部(mode=horizontal)时,让菜单可以滚动(overflow-x:auto)(主要用于移动端的菜单显示)...
  9. python中sort命令介绍以及list结构中统计各元素出现的个数的方法
  10. day11 函数的参数列表