分享
 
 
 

Win2K 服务程序的源码(框架而已)

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

以下为 Win2000 下我所理解的服务程序的源码,可以创建一个服务,并可以随时启动,停止和移除该服务。使用VC6编译,下面是使用方法简介。

需要安装 Service 的,打开 Dos 窗口,然后输入程序名字加上 -install 参数

例如:

#Simple_Service -install

如果需要删除 Service 的,在 Dos 窗口,输入程序名字加上 -remove 参数

#Simple_Service -Remove

也可以使用工具 SC.exe 来删除服务,在 Dos 窗口输入 sc delete _Simple_Service_08 即可

如果要启动或停止服务,请在计算机管理-> 服务那里启动 ,服务名称为 _Simple_Service_08

/////////////////////////////////////////////////////////////////////////////////////

该服务程序会生成调试用的日志文件,需要包含 RunTimeLog.h 和 RunTimeLog.cpp

这两个文件在这里 http://www.csdn.net/develop/Read_Article.asp?Id=17477

下面的程序对刚刚入门的伙伴可能有用,"高手"们就省省墨水,免得我又被臭骂了(面对像这样的中国人,我不得不学乖一点)。

以下是完整的源程序,文件名称是: WinMain.cpp,详细的说明待我组织过后再附上。

//********************************************************************************

//*************** FileName: WinMain.cpp ********************************

//********************************************************************************

// 最小 Link 包含: msvcrt.lib kernel32.lib user32.lib Advapi32.lib Shell32.lib

#define WIN32_LEAN_AND_MEAN // Say No to MFC !!

#define UNICODE

#include <windows.h>

//#include <Winsvc.h>

//#include <Shellapi.h>

#include "RunTimeLog.h"

RunTimeLog log;

LPSTR MsgErr=NULL;

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// Define for Service

#define ServiceName "_Simple_Service_08"

#define StrInstall TEXT("install")

#define StrRemove TEXT("Remove")

void WINAPI service_ctrl(DWORD dwCtrlCode);

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

void WinMainCleanup(void);

SC_HANDLE schService=NULL, schSCManager=NULL;

SERVICE_STATUS ssStatus;

SERVICE_STATUS_HANDLE sshStatusHandle=NULL;

HANDLE hServerStopEvent = NULL;

//////////////////////////////////////////////////////////////////////////

// End of Define for Service

char temp[1024]="Temp77 is Bad!";

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////

void WinMainCleanup(void)

{

if(MsgErr){ LocalFree(MsgErr); MsgErr = NULL; }

if( schService ) CloseServiceHandle( schService );

if(schSCManager) CloseServiceHandle(schSCManager);

log.last(true);

//log.showResult(1500);

//log.write("after ShowResult!");

return;

}

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

// Name: WinMain()

// ------ ---------- ----------- ---------

int WINAPI WinMain( HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow )

{

log.nobuff = true;

log.write(ServiceName" WinMain start");

// 判断是否为 WinNT

OSVERSIONINFO osvi;

osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

if( GetVersionEx(&osvi) )

{

if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) log.write("WinNT 系统可用!");

else { log.write("非 WinNT 系统中,清场后退出"); WinMainCleanup(); return 1; }

}else

{

log.write("Failed to GetVersionEx.");

FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,

GetLastError(), NULL, (LPSTR)&MsgErr, 0, NULL );

log.write(MsgErr);

WinMainCleanup(); return 1;

}// End of if( GetVersionEx(&osvi) )

// 填充服务入口表

SERVICE_TABLE_ENTRY dispatchTable[] =

{

{ TEXT(ServiceName), LPSERVICE_MAIN_FUNCTION(service_main) },

{ NULL, NULL }

};

// 取得命令行以观察

LPSTR cmdline = GetCommandLineA();

log.write("CommandLine by following."); log.write(cmdline); log.write("");

// 取得当前目录以观察

GetCurrentDirectoryA(1024,temp);

log.write("CurrentDirectory by following."); log.write(temp); log.write("");

// 取得模块的文件名以观察

GetModuleFileNameA(NULL,temp,sizeof(temp));

log.write("Current Module FileName by following."); log.write(temp); log.write("");

for(int i1=lstrlenA(temp); i1>0; i1--) { if(temp[i1]=='\\') { temp[i1]=0;break; } }

SetCurrentDirectoryA(temp);

log.write("重新设置了当前目录的位置");

// 重新取得当前目录以观察

GetCurrentDirectoryA(1024,temp);

log.write("CurrentDirectory by following."); log.write(temp); log.write("");

// 分离出参数组以访问

int NumArgsCount = NULL;

LPWSTR * lpArgv = CommandLineToArgvW( GetCommandLineW(), &NumArgsCount );

log.numberwrite("NumArgsCount = ", (DWORD)NumArgsCount);

int i=0;

for(i=0;i<NumArgsCount;i++)

{

log.numberwrite("命令行参数 ",i);

WideCharToMultiByte(CP_ACP, NULL, lpArgv[i],-1,temp,sizeof(temp),NULL,NULL);

log.write(temp); log.write("");

}

// 判断参数的操作

if(NumArgsCount>1) // 只有参数个数大于 1 的时候

{

if( (lpArgv[1][0]==(WORD)'/') || (lpArgv[1][0]==(WORD)'-') )

{

log.write("判断参数");

if(!_wcsicmp(StrInstall, lpArgv[1]+1))

{

log.write("Install specify.");

//CmdInstalService();

if(!GetModuleFileNameA(NULL,temp,sizeof(temp))) { log.write("GetMouduleFileName failed."); WinMainCleanup(); return 0; }

// SC_HANDLE schService=NULL, schSCManager=NULL;

schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

if(schSCManager)

{

log.write("OpenSCManager 成功");

// 打开成功才创建

schService =

CreateServiceA( schSCManager, ServiceName, ServiceName"(Dsp)",

SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,

temp,NULL,NULL,NULL,NULL,NULL );

if(schService)

{

log.write("CreateService "ServiceName" 成功");

CloseServiceHandle(schService); schService = NULL;

}

else

{

log.write("CreateService "ServiceName" failed.");

FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,

GetLastError(), NULL, (LPSTR)&MsgErr, 0, NULL );

log.write(MsgErr);

WinMainCleanup(); return 0;

}

CloseServiceHandle(schSCManager); schSCManager = NULL;

}

else { log.write("OpenSCManager failed."); WinMainCleanup(); return 0; }

log.write("");

log.write("完成了服务的安装");

log.write("");

}

else if(!_wcsicmp(StrRemove, lpArgv[1]+1))

{

log.write("Remove specify.");

//CmdRemoveService();

// SC_HANDLE schService=NULL, schSCManager=NULL;

schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

if(schSCManager)

{

log.write("OpenSCManager 成功");

// 打开成功才进行下一步

schService = OpenServiceA( schSCManager, ServiceName, SERVICE_ALL_ACCESS);

if(schService)

{

log.write("OpenService "ServiceName" 成功");

QueryServiceStatus( schService, &ssStatus);

if(ssStatus.dwCurrentState == SERVICE_STOPPED) log.write("Service already Stopped.");

else

{

// try to Stop the Service

log.write("try to Stop the Service");

if( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ))

{

Sleep(50);

while ( QueryServiceStatus( schService, &ssStatus))

{

if( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )

{

Sleep(500);

log.write("仍在停止 Service 中。。。");

}

else break;

}//End of while ( QueryServiceStatus( schService, &ssStatus))

}

}//End of if(ssStatus.dwCurrentState == SERVICE_STOPPED) else

// 如果已经停止了 Service ,那么就删除服务

if(ssStatus.dwCurrentState == SERVICE_STOPPED )

{

Sleep(1000);

if( DeleteService( schService) ) log.write("成功删除 "ServiceName" Service");

else log.write("删除 "ServiceName" 失败"); log.write("");

}

else log.write("failed to Stop Service.");

CloseServiceHandle(schService); schService = NULL;

}

else

{

log.write("OpenService "ServiceName" failed.");

FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,

GetLastError(), NULL, (LPSTR)&MsgErr, 0, NULL );

log.write(MsgErr);

WinMainCleanup(); return 0;

}

CloseServiceHandle(schSCManager); schSCManager = NULL;

}

else { log.write("OpenSCManager failed."); WinMainCleanup(); return 0; }

}

}

WinMainCleanup();

return 0;

} // End of if(NumArgsCount>1) // 只有参数个数大于 1 的时候

log.write("");

if(StartServiceCtrlDispatcher(dispatchTable)) log.write("StartServiceCtrlDispatcher Complete.");

else

{

log.write("StartServiceCtrlDispatcher failed.");

FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,

GetLastError(), NULL, (LPSTR)&MsgErr, 0, NULL );

log.write(MsgErr);

}

WinMainCleanup();

//ExitProcess(0);

log.last(true);

return NULL;

}

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

void WINAPI service_ctrl(DWORD dwCtrlCode)

{

// Handle the requested control code

log.write("");

log.write("Go into service_ctrl Function.");

log.write("");

int i2=0;

switch(dwCtrlCode)

{

// Stop the Service

case SERVICE_CONTROL_STOP:

log.write("recive SERVICE_CONTROL_STOP");

ssStatus.dwCheckPoint = ssStatus.dwCheckPoint++;

ssStatus.dwWin32ExitCode = NO_ERROR;

ssStatus.dwCurrentState = SERVICE_STOP_PENDING;

SetServiceStatus(sshStatusHandle,&ssStatus);

SetEvent(hServerStopEvent);

log.write("已经设置 Service 状态为 SERVICE_STOP_PENDING ,并将同步对象设置为激发状态.");

for(i2=0; i2<12; i2++)

{

QueryServiceStatus( schService, &ssStatus);

if( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) Sleep(200);

else break;

}

ResetEvent(hServerStopEvent);

if(ssStatus.dwCurrentState == SERVICE_STOPPED )

{

log.write("The Service is now Stoped");

ssStatus.dwCheckPoint = 0;

ssStatus.dwWin32ExitCode = NO_ERROR;

ssStatus.dwCurrentState = SERVICE_STOP;

SetServiceStatus(sshStatusHandle,&ssStatus);

} else log.write("Stoped Service Failed.");

return;

break;

case SERVICE_CONTROL_INTERROGATE:

log.write("recive SERVICE_CONTROL_INTERROGATE");

break;

default:

log.numberwrite("recive CtrlCode = ",dwCtrlCode);

break;

}

//ssStatus.dwCurrentState = SERVICE_STOP_PENDING;

ssStatus.dwCheckPoint = ssStatus.dwCheckPoint++;

ssStatus.dwWin32ExitCode = NO_ERROR;

SetServiceStatus(sshStatusHandle,&ssStatus);

return;

}

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////

void service_mainCleanup(void)

{

log.write("");

log.write("service_mainCleanup!"); log.write("");

if(hServerStopEvent){ CloseHandle(hServerStopEvent); hServerStopEvent = NULL; }

ssStatus.dwWin32ExitCode = 0;

ssStatus.dwCurrentState = SERVICE_STOPPED;

ssStatus.dwWaitHint = 1000;

if(SetServiceStatus(sshStatusHandle,&ssStatus))

{

log.write("SetServiceStatus to SERVICE_STOPPED 成功!");

}

else

{

log.write("SetServiceStatus to SERVICE_STOPPED 失败!");

FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,

GetLastError(), NULL, (LPSTR)&MsgErr, 0, NULL );

log.write(MsgErr);

}

//log.showResult(false);

return;

}

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////

void WINAPI service_main(DWORD dwArgc,LPTSTR *lpszArgv)

{

// 注册我们的 Service 控制处理函数

sshStatusHandle = RegisterServiceCtrlHandlerA(ServiceName,service_ctrl);

if(!sshStatusHandle)

{

FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,

GetLastError(), NULL, (LPSTR)&MsgErr, 0, NULL );

log.write(MsgErr);

log.write("Failed to RegisterServiceCtrlHandler");

service_mainCleanup();

}

log.write("");

log.write("We now Running in service_main.");

log.write("Success to RegisterServiceCtrlHandler");

hServerStopEvent = CreateEvent(NULL,TRUE,false,NULL);

if(hServerStopEvent) log.write("创建了同步对象");

else log.write("创建同步对象失败");

// 以下是测试同步信号的代码

DWORD dwWait = NULL;

dwWait = WaitForSingleObject(hServerStopEvent,200);

{

if(dwWait==WAIT_TIMEOUT) log.write("等待同步信号超时");

if(dwWait==WAIT_OBJECT_0) log.write("同步对象被触发了");

}

// 继续报告现在 Service 启动的进度

ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

ssStatus.dwServiceSpecificExitCode = 0;

ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP ;//| SERVICE_ACCEPT_PAUSE_CONTINUE;

ssStatus.dwWaitHint = 1000;

// 设置以后放送

ssStatus.dwCheckPoint = 0;

ssStatus.dwWin32ExitCode = NO_ERROR;

ssStatus.dwCurrentState = SERVICE_START_PENDING;

if(SetServiceStatus(sshStatusHandle,&ssStatus))

{

log.write("SetServiceStatus 成功!");

}

else

{

log.write("SetServiceStatus 失败!");

FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,

GetLastError(), NULL, (LPSTR)&MsgErr, 0, NULL );

log.write(MsgErr);

}

Sleep(300);

// 设置以后放送

ssStatus.dwCheckPoint++;

log.numberwrite("Progress = ",ssStatus.dwCheckPoint);

ssStatus.dwWin32ExitCode = NO_ERROR;

ssStatus.dwCurrentState = SERVICE_START_PENDING;

SetServiceStatus(sshStatusHandle,&ssStatus);

for(int i1=0; i1<6;i1++)

{

Sleep(300);

// 设置以后放送

//ssStatus.dwCheckPoint++;

ssStatus.dwCheckPoint = ssStatus.dwCheckPoint + 20;

log.numberwrite("Progress = ",ssStatus.dwCheckPoint);

ssStatus.dwWin32ExitCode = NO_ERROR;

ssStatus.dwCurrentState = SERVICE_START_PENDING;

SetServiceStatus(sshStatusHandle,&ssStatus);

}

Sleep(200);

// 设置以后放送

ssStatus.dwCheckPoint = 0;

ssStatus.dwWin32ExitCode = NO_ERROR;

ssStatus.dwCurrentState = SERVICE_RUNNING;

SetServiceStatus(sshStatusHandle,&ssStatus);

log.write("SetServiceStatus to SERVICE_RUNNING !");

Sleep(500);

// 放入代码运行服务

while (true)

{

dwWait = WaitForSingleObject(hServerStopEvent,1);

{

//if(dwWait==WAIT_TIMEOUT) log.write("等待同步信号超时");

if(dwWait==WAIT_OBJECT_0) { log.write("同步对象被触发了"); ResetEvent(hServerStopEvent); break; }

}

//////////////////////////////////////////////////////////////////////////

log.write("Doing Something...");

Sleep(100); // 假设要运行100毫秒的操作

//////////////////////////////////////////////////////////////////////////

}// End of while (true)

service_mainCleanup();

return;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有