我现在有一个应用程序,想要把它变成系统的后台服务,系统一启动就可以启动应用程序,
然后可以可以在服务控制台控制,我现在注册服务到是好用了,删除服务也好用了,但是控制服务不行,那位大哥做过,请指点我一下,最好有原代码,帮帮小妹!
然后可以可以在服务控制台控制,我现在注册服务到是好用了,删除服务也好用了,但是控制服务不行,那位大哥做过,请指点我一下,最好有原代码,帮帮小妹!
解决方案 »
- 在CGridCtrl中,请问如何用回车键实现使其输入焦点转移到下一个单元格?谢谢
- 求助各位大佬,如何往window打印机里发送cmyk数据?有没有方法?
- SetTimer+OnTimer计时器不起作用!
- 谁做过K-均值分割或FCM聚类分割来分割图象啊。
- 成功用socket的到了web网页的内容,如何只得到<html>和</html>的内容
- 如何制作可以注册ODBC和控件的文件?
- 请问如何让MSCOMM控件响应自己的OnComm消息?
- vc那里可以下载访问Informix数据库Windows下的ODBC驱动程序
- Inno Setup 修改只读INI文件出错提示请问如何解决
- 菜鸟提问:CMyButton
- 用C/C++如何开发一个DLL文件呢.
- 关于控件的几个小问题
在基于Nt的系统中,全部服务任务都是由服务控制管理器(SCM)系统管理。SCM维持注册表中已知服务列表,打开各项服务(即可以是开机时自动打开,也可以使用户请求打开)。SCM把服务列表和它们的打开状态保存在注册表中,新服务项在安装时加入此列表中。另外也可以删除服务项目。
作为服务任务的程序是一个普通的exe文件,但是必须满足特定的要求才能确切地与SCM连接。微软已经详细编制了这些函数的程序流,必须紧密依据此流程表,否则服务项目就不能运行。要求如下:
1.服务项目的exe文件必须有一个普通的main或WinMain函数,此函数必须立即(特定情况下是在30秒之内)调用函数StartServiceCrtlDispatcher。调用之后,EXE文件就在SCM中注册,并且给出一个调用函数ServiceMain(在启动服务时调用)的指针。可以更改函数ServiceMain的函数名,然后就能在ServiceMain下面的记录文本中找到所用函数名的描述。main函数应该在注册ServiceMain之后返回。
不能用命令行方式运行服务的exe文件。而应该在SCM知道的服务列表中安装,SCM会调用main函数,打开EXE文件。偶然用命令行方式执行服务时一定会出错,因为它不能连接SCM。
2.SCM在打开服务时将调用函数ServiceMain。例如,当管理员选择“控制面板”上“服务”的start按钮时,SCM将在一个工作线程中执行函数ServiceMain。
函数ServiceMain完成多项工作。其中最为主要的是立即调用函数RegisterServiceCtrlHandler,该函数能用SCM注册一个函数Handler以调用控制要求。此函数的函数名可以随便更改,但大会在Handler下面的记录文本中列出。函数RegisterServiceCtrlHandler返回一个句柄,服务在给SCM发送状态信息时将用到该句柄。
函数ServiceMain还开始将完成实际服务任务的工作现程。一旦线程开始,函数ServiceMain就等待一个事件的发生。直道服务停止,函数ServiceMain才返回。之后,重新调用函数ServiceMain,SCM将重新开始该项服务。
3.函数Handler包含一个转换语句,用于分析来自SCM的控制请求。默认时,SCM发送以下控制常数:
SERVICE_CONTROL_STOP 通知服务停止
SERVICE_CONTROL_PAUSE 通知服务暂停
SERVICE_CONTROL_CONTINUE 通知服务重新开始
SERVICE_CONTROL_INTERROGATE 通知服务立即报告当前状态
SERVICE_CONTROL_SHUTDOWN 通知服务紧急关闭
用户也可以创建自定义常数(128~255之间),通过SCM把它们发送到服务项。
当创建一个包含上述main、ServiceMain和Handler等函数的EXE文件以及一个包含服务线程的函数时,就得到了一个完整的服务任务。
#include<windwos.h>
#include<stdio.h>
#include<iostream>
#include<stdlib.h>using namespace std;char *SERVICE_NAME = "BeepService";
HANDLE terminateEvent = NULL;
SERVICE_STATUS_HANDLE serviceStatusHandle;
int beepDelay = 2000;
BOOL pauseService = FALSE;
BOOL runningService = FALSE;
HANDLE threadHandle = 0;void ErrorHandler( char *s, DWORD err )
{
cout<<s<<endl;
cout<<"Error number: "<<err<<endl;
ExitProcess(err);
}DWORD ServiceThread( LPDWORD param )
{
while( 1 )
{
Beep( 200, 200 );
Sleep( beepDelay );
}
return 0;
}BOOL InitService()
{
DWORD id;
threadHandle = CreateThread( 0, 0,
(LPTHREAD_START_ROUTINE)ServiceThread,
0, 0, &id );
if(threadHandle == 0 )
{
return FALSE;
}
else
{
runningService = TRUE;
return TRUE;
}
}void ResumeService()
{
pasuuService = FALSE;
ResumeThread( threadHandle );
}void PauseService()
{
pauseService = TRUE;
SuspendThread( threadHandle );
}void StopService()
{
runningService = FALSE;
SetEvent( terminateEvent );
}BOOL SendStatusToSCM( DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode,
DWORD dwCheckPoint,
DWORD dwWaitHint )
{
BOOL success;
SERVICE_STATES serviceStatus; serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
if( dwCurrentState == SERVICE_START_PENDING )
{
serviceStatus.dwControlsAccepted = 0;
}
else
{
serviceStatue.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;
}
if( dwServiceSpecificExitCode == 0 )
{
serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
}
else
{
serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
}
serviceStatus.dwCheckPoint = dwCheckPoint;
serviceStatus.dwWaitHint = dwWaitHint; success = SetServiceStatus( serviceStatuseHandle,
&serviceStatus );
if( !success )
{
StopService();
}
return success;
}void ServiceCtrlHandler( DWORD controlCode )
{
DWORD currentState = 0;
BOOL success;
switch( controCode )
{
case SERVICE_CONTROL_STOP:
currentState = SERVICE_STOP_PENDING;
success = SendStatusToSCM( SERVICE_STOP_PENDING,
NO_ERROR, 0, 1, 5000 ); StopService();
return;
case SERVICE_CONTROL_PAUSE:
if( runningService && !pauseService )
{
success = SendStatusToSCM( SERVICE_PAUSE_PENDING,
NO_ERROR, 0, 1, 1000);
PauseService();
currentState = SERVICE_PAUSED;
}
break;
case SERVICE_CONTROL_CONTINUE:
if( runningService && pauseService )
{
success = SendStatusToSCM( SERVICE_CONTINUE_PENDING,
NO_ERROR, 0, 1, 1000 );
ResumeService();
currentState = SERVICE_RUNNING;
}
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
return;
default:
break;
}
}void terminate( DWORD error )
{
if( terminateEvent )
{
CloseHandle( terminateEvent );
} if( serviceStatusHandle )
{
SendStatusToSCM( SERVICE_STOPPED, error, 0, 0, 0 );
} if( threadHandle )
{
CloseHandle( threadHandle );
}
}void ServiceMain( DWORD arcg, LPTSTR* argv )
{
BOOL success;
serviceStatusHandle = RegisterServiceCtrlHandler( SERVICE_NAME,
(LPHANDLER_FUNCTION)SerivceCtrlHandler);
if( !serviceStatusHandle )
{
rerminate( GetLastError() );
return;
} success = SendStatusToSCM( SERVICE_START_PENDING,
NO_ERROR, 0, 1, 5000 );
if( !success )
{
terminate( GetLastError() );
return;
} terminateEvent = CreateEvent( 0, TRUE, FALSE, 0 );
if( !terminateEvent )
{
terminate( GetLastError() );
return;
}
success = SendStatusToSCM( SERVICE_START_PENDING,
NO_ERROR, 0, 2 1000 );
if( !success )
{
terminate( GetLastError() );
return;
} if( argc == 2 )
{
int temp = atoi( argv[1] );
if( temp < 1000 )
{
beepDelay = 2000;
}
else
{
beepDelay = temp;
}
} success = SendStatusToSCM( SERVICE_START_PENDING,
NO_ERROR, 0, 3, 5000 );
if( !success )
{
terminate( GetLastError() );
return;
}
success = InitService();
if ( !success )
{
terminate( GetLastError() );
return;
} success = SendStatusToSCM( SERVICE_RUNNING,
NO_ERROR, 0, 0, 0 );
if( !success )
{
terminate( GetLastError() );
return;
} WaitForSingleObject( terminateEvent, INFINITE );
rerminate( 0 );
}int main( int argc, char* argv[] )
{
SERVICE_TABLE_ENTRY serviceTable[] =
{
{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL}
};
BOOL success; success = StartServiceCtrlDispatcher( serviceTable );
if( !success )
{
ErrorHandler( "IN StartServiceCtrlDispatcher", GetLastError() );
} return 0;
}下面是安装这个程序的代码:
//install.cpp#include<windows.h>
#include<iostream>using namespace std;void ErrorHandler( char *s, DWORD err )
{
cout<<s<<endl;
cout<<"Error number: "<<err<<endl;
ExitProcess(err);
}int main( int argc, char* argv[] )
{
SC_HANDLE newService, scm;
if( argc != 4 )
{
cout<<"Usage:\n";
cout<<" install service_name service_lable executable\n";
cout<<" service_name is the name used internally by the SCM\n";
cout<<" service_label is the name that appears in the Services applet\n";
cout<<" executable is the full path to the EXE\";
cout<<endl;
return -1;
} cout<<"Starting...\n";
scm = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );
if( !scm )
{
ErrorHandler("In OpenScManager", GetLastError() );
newService = CreateService( scm, argv[1],
argv[2],
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
argv[3],
0, 0, 0, 0, 0 );
if( !newService )
{
ErrorHandler("In CreateService", GetLastError() );
}
else
{
cout<<"Service installed\";
} CloseServiceHandle( newService );
CloseServiceHandle( scm );
cout<<"Ending...\n";
}
}剩下的细节部分,请楼主参考MSDN。程序的注视我没有写,主要是大字快要把手指打断了:)