65,209
社区成员
发帖
与我相关
我的任务
分享
[/quote]
#define FRONT_START 0 // 服务允许启动前置
#define FRONT_STOP 1 // 服务停止前置
#define FRONT_PAUSE 2 // 服务暂停前置
int _tmain(int argc, _TCHAR* argv[])
{
// 安装服务
if ((argc == 2) && (::strcmp(argv[1] + 1, "install") == 0))
{
InstallService(ServiceName);
return 0;
}
hEvents[0] = CreateEvent(NULL, FALSE, FALSE, "FRONTSTART");
hEvents[1] = CreateEvent(NULL, FALSE, FALSE, "FRONTSTOP");
hEvents[2] = CreateEvent(NULL, FALSE, FALSE, "FRONTPAUSE");
hEvents[3] = (HANDLE)0;
// 定义服务入口表
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ServiceName, ServiceMain},
{NULL, NULL}
};
// 向SCM注册服务并进入循环,直到所有服务退出该函数才返回
if(!StartServiceCtrlDispatcher(DispatchTable))
{
int nError = GetLastError();
}
return 0;
}
// 安装服务
void InstallService(const char * szServiceName)
{
SC_HANDLE handle = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(handle == NULL)
{
DWORD dw = ::GetLastError();
OutputErrorMsg(dw);
return;
}
char szFilename[256];
::GetModuleFileName(NULL, szFilename, 255);
SC_HANDLE hService = ::CreateService(handle, szServiceName,
szServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, szFilename, NULL,
NULL, NULL, NULL, NULL);
if(hService)
{
::CloseServiceHandle(hService);
}
else
{
DWORD dw = ::GetLastError();
OutputErrorMsg(dw);
}
::CloseServiceHandle(handle);
}
// 服务控制处理器,接受SCM的指令并通知服务线程
void WINAPI ServiceCtrlHandler(DWORD dwControl)
{
//MessageBox(NULL, "ServiceCtrlHandler", NULL, MB_SERVICE_NOTIFICATION);
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
servicestatus.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[1]);
break;
case SERVICE_CONTROL_PAUSE:
servicestatus.dwCurrentState = SERVICE_PAUSE_PENDING ;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[2]);
break;
case SERVICE_CONTROL_CONTINUE:
servicestatus.dwCurrentState = SERVICE_CONTINUE_PENDING;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[0]);
break;
}
}
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
servicestatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0;
servicestatus.dwCheckPoint = 0;
servicestatus.dwWaitHint = 0;
servicestatushandle = ::RegisterServiceCtrlHandler(ServiceName, ServiceCtrlHandler);
if (servicestatushandle == (SERVICE_STATUS_HANDLE)0)
{
return;
}
// 设置服务状态为已开始但还没有初始化完成
::SetServiceStatus(servicestatushandle, &servicestatus);
CoInitialize(0);
char cPath0[MAX_PATH] = {0};
GetModuleFileName(NULL, cPath0, MAX_PATH);
char* pPos = strrchr(cPath0, '\\');
*(pPos + 1) = 0;
sprintf(g_cLogPath, "%slog", cPath0);
*(pPos + 1) = 0;
char cPath[MAX_PATH] = {0};
strcat(cPath, "E:\\test.exe");
STARTUPINFO si = { sizeof(si) };
// 服务已经启动
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(servicestatushandle, &servicestatus);
DWORD dwRet;
int iFlag = FRONT_START; // 服务当前的状态为允许启动
while(TRUE)
{
dwRet = WaitForMultipleObjects(4, hEvents, FALSE, 8 * 1000);
if((iFlag == FRONT_START || iFlag == FRONT_PAUSE) && (dwRet == WAIT_OBJECT_0 + 1)) // 要求停止前置服务的事件发生
{
TerminateProcess(g_ProcessInfo.hProcess, 0);
CloseHandle(g_ProcessInfo.hProcess);
servicestatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(servicestatushandle, &servicestatus);
iFlag = FRONT_STOP;
return ;
}
if((iFlag == FRONT_STOP || iFlag == FRONT_PAUSE) && (dwRet == WAIT_OBJECT_0)) // 要求启动前置服务的事件发生
{
iFlag = FRONT_START;
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(servicestatushandle, &servicestatus);
hEvents[3] = (HANDLE)-1;
}
if((iFlag == FRONT_START) && (dwRet == WAIT_OBJECT_0 + 2)) // 要求暂停前置服务的事件发生
{
TerminateProcess(g_ProcessInfo.hProcess, 0);
CloseHandle(g_ProcessInfo.hProcess);
servicestatus.dwCurrentState = SERVICE_PAUSED;
SetServiceStatus(servicestatushandle, &servicestatus);
iFlag = FRONT_PAUSE;
hEvents[3] = hEvents[2]; // 避免因为前置进程句柄失效导致的Wait函数总是返回WAIT_FAILED而不能收到其它事件
}
if(iFlag == FRONT_START) // 只在允许前置启动的情况下才去连接数据库和启动前置
{
if(dwRet == WAIT_OBJECT_0 + 3 || dwRet == WAIT_FAILED) // 前置进程意外退出或者还未启动
{
if(dwRet == WAIT_OBJECT_0 + 3)
{
Log("前置意外退出");
}
// 记录进程退出日志
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
BOOL ret = CreateProcess(cPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &g_ProcessInfo);
int nError = GetLastError();
if(ret)
{
hEvents[3] = g_ProcessInfo.hProcess;
// 记录进程重新启动日志
CloseHandle(g_ProcessInfo.hThread);
}
}
else if(dwRet == WAIT_TIMEOUT)
{
}
}
}
return ;
}
把主要的几个函数贴出来了,你看看[/quote]
谢谢了,内容不少,我先研究研究![/quote]
这个直接建一个win32 控制台程序,复制到cpp文件里面就行了么?还是需要别的操作。。。。小白,见谅!

[/quote]
#define FRONT_START 0 // 服务允许启动前置
#define FRONT_STOP 1 // 服务停止前置
#define FRONT_PAUSE 2 // 服务暂停前置
int _tmain(int argc, _TCHAR* argv[])
{
// 安装服务
if ((argc == 2) && (::strcmp(argv[1] + 1, "install") == 0))
{
InstallService(ServiceName);
return 0;
}
hEvents[0] = CreateEvent(NULL, FALSE, FALSE, "FRONTSTART");
hEvents[1] = CreateEvent(NULL, FALSE, FALSE, "FRONTSTOP");
hEvents[2] = CreateEvent(NULL, FALSE, FALSE, "FRONTPAUSE");
hEvents[3] = (HANDLE)0;
// 定义服务入口表
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ServiceName, ServiceMain},
{NULL, NULL}
};
// 向SCM注册服务并进入循环,直到所有服务退出该函数才返回
if(!StartServiceCtrlDispatcher(DispatchTable))
{
int nError = GetLastError();
}
return 0;
}
// 安装服务
void InstallService(const char * szServiceName)
{
SC_HANDLE handle = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(handle == NULL)
{
DWORD dw = ::GetLastError();
OutputErrorMsg(dw);
return;
}
char szFilename[256];
::GetModuleFileName(NULL, szFilename, 255);
SC_HANDLE hService = ::CreateService(handle, szServiceName,
szServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, szFilename, NULL,
NULL, NULL, NULL, NULL);
if(hService)
{
::CloseServiceHandle(hService);
}
else
{
DWORD dw = ::GetLastError();
OutputErrorMsg(dw);
}
::CloseServiceHandle(handle);
}
// 服务控制处理器,接受SCM的指令并通知服务线程
void WINAPI ServiceCtrlHandler(DWORD dwControl)
{
//MessageBox(NULL, "ServiceCtrlHandler", NULL, MB_SERVICE_NOTIFICATION);
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
servicestatus.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[1]);
break;
case SERVICE_CONTROL_PAUSE:
servicestatus.dwCurrentState = SERVICE_PAUSE_PENDING ;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[2]);
break;
case SERVICE_CONTROL_CONTINUE:
servicestatus.dwCurrentState = SERVICE_CONTINUE_PENDING;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[0]);
break;
}
}
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
servicestatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0;
servicestatus.dwCheckPoint = 0;
servicestatus.dwWaitHint = 0;
servicestatushandle = ::RegisterServiceCtrlHandler(ServiceName, ServiceCtrlHandler);
if (servicestatushandle == (SERVICE_STATUS_HANDLE)0)
{
return;
}
// 设置服务状态为已开始但还没有初始化完成
::SetServiceStatus(servicestatushandle, &servicestatus);
CoInitialize(0);
char cPath0[MAX_PATH] = {0};
GetModuleFileName(NULL, cPath0, MAX_PATH);
char* pPos = strrchr(cPath0, '\\');
*(pPos + 1) = 0;
sprintf(g_cLogPath, "%slog", cPath0);
*(pPos + 1) = 0;
char cPath[MAX_PATH] = {0};
strcat(cPath, "E:\\test.exe");
STARTUPINFO si = { sizeof(si) };
// 服务已经启动
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(servicestatushandle, &servicestatus);
DWORD dwRet;
int iFlag = FRONT_START; // 服务当前的状态为允许启动
while(TRUE)
{
dwRet = WaitForMultipleObjects(4, hEvents, FALSE, 8 * 1000);
if((iFlag == FRONT_START || iFlag == FRONT_PAUSE) && (dwRet == WAIT_OBJECT_0 + 1)) // 要求停止前置服务的事件发生
{
TerminateProcess(g_ProcessInfo.hProcess, 0);
CloseHandle(g_ProcessInfo.hProcess);
servicestatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(servicestatushandle, &servicestatus);
iFlag = FRONT_STOP;
return ;
}
if((iFlag == FRONT_STOP || iFlag == FRONT_PAUSE) && (dwRet == WAIT_OBJECT_0)) // 要求启动前置服务的事件发生
{
iFlag = FRONT_START;
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(servicestatushandle, &servicestatus);
hEvents[3] = (HANDLE)-1;
}
if((iFlag == FRONT_START) && (dwRet == WAIT_OBJECT_0 + 2)) // 要求暂停前置服务的事件发生
{
TerminateProcess(g_ProcessInfo.hProcess, 0);
CloseHandle(g_ProcessInfo.hProcess);
servicestatus.dwCurrentState = SERVICE_PAUSED;
SetServiceStatus(servicestatushandle, &servicestatus);
iFlag = FRONT_PAUSE;
hEvents[3] = hEvents[2]; // 避免因为前置进程句柄失效导致的Wait函数总是返回WAIT_FAILED而不能收到其它事件
}
if(iFlag == FRONT_START) // 只在允许前置启动的情况下才去连接数据库和启动前置
{
if(dwRet == WAIT_OBJECT_0 + 3 || dwRet == WAIT_FAILED) // 前置进程意外退出或者还未启动
{
if(dwRet == WAIT_OBJECT_0 + 3)
{
Log("前置意外退出");
}
// 记录进程退出日志
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
BOOL ret = CreateProcess(cPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &g_ProcessInfo);
int nError = GetLastError();
if(ret)
{
hEvents[3] = g_ProcessInfo.hProcess;
// 记录进程重新启动日志
CloseHandle(g_ProcessInfo.hThread);
}
}
else if(dwRet == WAIT_TIMEOUT)
{
}
}
}
return ;
}
把主要的几个函数贴出来了,你看看[/quote]
谢谢了,内容不少,我先研究研究!
[/quote]
#define FRONT_START 0 // 服务允许启动前置
#define FRONT_STOP 1 // 服务停止前置
#define FRONT_PAUSE 2 // 服务暂停前置
int _tmain(int argc, _TCHAR* argv[])
{
// 安装服务
if ((argc == 2) && (::strcmp(argv[1] + 1, "install") == 0))
{
InstallService(ServiceName);
return 0;
}
hEvents[0] = CreateEvent(NULL, FALSE, FALSE, "FRONTSTART");
hEvents[1] = CreateEvent(NULL, FALSE, FALSE, "FRONTSTOP");
hEvents[2] = CreateEvent(NULL, FALSE, FALSE, "FRONTPAUSE");
hEvents[3] = (HANDLE)0;
// 定义服务入口表
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ServiceName, ServiceMain},
{NULL, NULL}
};
// 向SCM注册服务并进入循环,直到所有服务退出该函数才返回
if(!StartServiceCtrlDispatcher(DispatchTable))
{
int nError = GetLastError();
}
return 0;
}
// 安装服务
void InstallService(const char * szServiceName)
{
SC_HANDLE handle = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(handle == NULL)
{
DWORD dw = ::GetLastError();
OutputErrorMsg(dw);
return;
}
char szFilename[256];
::GetModuleFileName(NULL, szFilename, 255);
SC_HANDLE hService = ::CreateService(handle, szServiceName,
szServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, szFilename, NULL,
NULL, NULL, NULL, NULL);
if(hService)
{
::CloseServiceHandle(hService);
}
else
{
DWORD dw = ::GetLastError();
OutputErrorMsg(dw);
}
::CloseServiceHandle(handle);
}
// 服务控制处理器,接受SCM的指令并通知服务线程
void WINAPI ServiceCtrlHandler(DWORD dwControl)
{
//MessageBox(NULL, "ServiceCtrlHandler", NULL, MB_SERVICE_NOTIFICATION);
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
servicestatus.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[1]);
break;
case SERVICE_CONTROL_PAUSE:
servicestatus.dwCurrentState = SERVICE_PAUSE_PENDING ;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[2]);
break;
case SERVICE_CONTROL_CONTINUE:
servicestatus.dwCurrentState = SERVICE_CONTINUE_PENDING;
::SetServiceStatus(servicestatushandle, &servicestatus);
SetEvent(hEvents[0]);
break;
}
}
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
servicestatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0;
servicestatus.dwCheckPoint = 0;
servicestatus.dwWaitHint = 0;
servicestatushandle = ::RegisterServiceCtrlHandler(ServiceName, ServiceCtrlHandler);
if (servicestatushandle == (SERVICE_STATUS_HANDLE)0)
{
return;
}
// 设置服务状态为已开始但还没有初始化完成
::SetServiceStatus(servicestatushandle, &servicestatus);
CoInitialize(0);
char cPath0[MAX_PATH] = {0};
GetModuleFileName(NULL, cPath0, MAX_PATH);
char* pPos = strrchr(cPath0, '\\');
*(pPos + 1) = 0;
sprintf(g_cLogPath, "%slog", cPath0);
*(pPos + 1) = 0;
char cPath[MAX_PATH] = {0};
strcat(cPath, "E:\\test.exe");
STARTUPINFO si = { sizeof(si) };
// 服务已经启动
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(servicestatushandle, &servicestatus);
DWORD dwRet;
int iFlag = FRONT_START; // 服务当前的状态为允许启动
while(TRUE)
{
dwRet = WaitForMultipleObjects(4, hEvents, FALSE, 8 * 1000);
if((iFlag == FRONT_START || iFlag == FRONT_PAUSE) && (dwRet == WAIT_OBJECT_0 + 1)) // 要求停止前置服务的事件发生
{
TerminateProcess(g_ProcessInfo.hProcess, 0);
CloseHandle(g_ProcessInfo.hProcess);
servicestatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(servicestatushandle, &servicestatus);
iFlag = FRONT_STOP;
return ;
}
if((iFlag == FRONT_STOP || iFlag == FRONT_PAUSE) && (dwRet == WAIT_OBJECT_0)) // 要求启动前置服务的事件发生
{
iFlag = FRONT_START;
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(servicestatushandle, &servicestatus);
hEvents[3] = (HANDLE)-1;
}
if((iFlag == FRONT_START) && (dwRet == WAIT_OBJECT_0 + 2)) // 要求暂停前置服务的事件发生
{
TerminateProcess(g_ProcessInfo.hProcess, 0);
CloseHandle(g_ProcessInfo.hProcess);
servicestatus.dwCurrentState = SERVICE_PAUSED;
SetServiceStatus(servicestatushandle, &servicestatus);
iFlag = FRONT_PAUSE;
hEvents[3] = hEvents[2]; // 避免因为前置进程句柄失效导致的Wait函数总是返回WAIT_FAILED而不能收到其它事件
}
if(iFlag == FRONT_START) // 只在允许前置启动的情况下才去连接数据库和启动前置
{
if(dwRet == WAIT_OBJECT_0 + 3 || dwRet == WAIT_FAILED) // 前置进程意外退出或者还未启动
{
if(dwRet == WAIT_OBJECT_0 + 3)
{
Log("前置意外退出");
}
// 记录进程退出日志
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
BOOL ret = CreateProcess(cPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &g_ProcessInfo);
int nError = GetLastError();
if(ret)
{
hEvents[3] = g_ProcessInfo.hProcess;
// 记录进程重新启动日志
CloseHandle(g_ProcessInfo.hThread);
}
}
else if(dwRet == WAIT_TIMEOUT)
{
}
}
}
return ;
}
把主要的几个函数贴出来了,你看看

我没现成的服务代码,楼上坛友但帖无妨。
C:\>sc /?
错误: 未知命令
描述:
SC 是用于与
服务控制管理器和服务进行通信的命令行程序。
用法:
sc <server> [command] [service name] <option1> <option2>...
选项 <server> 的格式为 "\\ServerName"
可以键入 "sc [command]" 以获得命令的进一步帮助
命令:
query-----------查询服务的状态, 或
枚举服务类型的状态。
queryex---------查询服务的扩展状态, 或
枚举服务类型的状态。
start-----------启动服务。
pause-----------向服务发送 PAUSE 控制请求。
interrogate-----向服务发送 INTERROGATE 控制请求。
continue--------向服务发送 CONTINUE 控制请求。
stop------------向服务发送 STOP 请求。
config----------更改服务的配置(永久)。
description-----更改服务的描述。
failure---------更改服务失败时所进行的操作。
sidtype---------更改服务的服务 SID 类型。
qc--------------查询服务的配置信息。
qdescription----查询服务的描述。
qfailure--------查询服务失败时所进行的操作。
qsidtype--------查询服务的服务 SID 类型。
delete----------(从注册表)删除服务。
create----------创建服务(将其添加到注册表)。
control---------向服务发送控制。
sdshow----------显示服务的安全描述符。
sdset-----------设置服务的安全描述符。
showsid---------显示与
任意名称相对应的服务 SID 字符串。
GetDisplayName--获取服务的 DisplayName。
GetKeyName------获取服务的 ServiceKeyName。
EnumDepend------枚举服务的依存关系。
下列命令不要求服务名称:
sc <server> <command> <option>
boot------------(ok | bad) 表明是否将最后一次启动
保存为最后一次的正确启动配置
Lock------------锁定服务数据库
QueryLock-------查询 SCManager 数据库的 LockStatus
示例:
sc start MyService
是否要查看 QUERY 和 QUERYEX 命令的帮助? [ y | n ]:
n
