以下为 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;
}
本文地址:http://com.8s8s.com/it/it1525.htm