如何编写windows服务程序

如何编写windows服务程序,第1张

Windows提供了一套后台服务程序编程接口,用户在编写后台服务程序时需要遵循一定的编程框架,否则服务程序不能正常运行。

服务程序通常编写成控制台类型的应用程序,总的来说,一个遵守服务控制管理程序接口要求的程序 包含下面三个函数

1)服务程序主函数(main):调用系统函数 StartServiceCtrlDispatcher 连接程序主线程到服务控制管理程序。

和其它进程一样,Main函数是服务进程的入口函数,服务控制管理器(SCM)在启动服务程序时,会从服务程序的main函数开始执行。在进入点函数里面要完成ServiceMain的初始化,准确点说是初始化一个SERVICE_TABLE_ENTRY结构数组,这个结构记录了这个服务程序里面所包含的所有服务的名称和服务的进入点函数。然后再调用接口StartServiceCtrlDispatcher 。

Main函数的函数框架如下:

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]=="/")))

{

/*

参数个数大于1是安装或者删除服务,该 *** 作是由用户来执行的

当然也可以讲这一部分功能另写一个程序来实现

*/

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

{

installService()

}

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

{

removeService()

}

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

{

bDebugServer=true

debugService(argc,argv)

}

}

else

{

/*

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

*/

g_logout.Logout("%s\n", "enter StartServiceCtrlDispatcher...")

//通知服务管理器为每一个服务创建服务线程

if(!StartServiceCtrlDispatcher(dispatchTable))

g_logout.Logout("%s\n", "StartServiceCtrlDispatcher failed.")

else

g_logout.Logout("%s\n", "StartServiceCtrlDispatcher OK.")

}

return 0

}

SCM启动一个服务程序之后,它会等待该程序的主线程去调StartServiceCtrlDispatcher。如果那个函数在两分钟内没有被调用,SCM将会认为这个服务有问题,并调用TerminateProcess去杀死这个进程。这就要求你的主线程要尽可能快的调用StartServiceCtrlDispatcher。

2)服务入口点函数(ServiceMain):执行服务初始化任务,同时执行多个服务的服务进程有多个服务入口函数。

在服务入口函数里,必须立即注册服务控制回调函数。然后调用函数SetServiceStatus 通知SCM 服务现在的状态,否则SCM会认为服务启动失败。

ServiceMain函数框架如下:

void WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)

{

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

sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl)

//如果注册失败

if(!sshStatusHandle)

{

g_logout.Logout("%s\n", "RegisterServiceCtrlHandler failed...")

return

}

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

ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS//可执行文件中只有一个单独的服务

ssStatus.dwServiceSpecificExitCode=0

ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP//允许用SCP去停止该服务

//更新服务状态

if(ReportStatusToSCMgr(SERVICE_START_PENDING,//服务状态,服务仍在初始化

NO_ERROR,

3000)) //等待时间

SvcInit( dwArgc, lpszArgv )//服务初始化函数

else

g_logout.Logout("%s\n", "ReportStatusToSCMgr SERVICE_START_PENDING failed...")

}

服务初始化函数SvcInit:

该函数的写法比较重要。在函数中创建一个等待事件,然后一直等待该事件。该线程在服务接到请求之前一直处于挂起状态,直到接到服务停止消息。

VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv)

{

/*创建事件*/

ghSvcStopEvent = CreateEvent(

NULL,// default security attributes

TRUE,// manual reset event

FALSE, // not signaled

NULL) // no name

if ( ghSvcStopEvent == NULL)

{

ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 )

return

}

// Report running status when initialization is complete.

ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 )

// 在这里执行服务线程的创建...

while(1)

{

// 等待停止事件被触发

WaitForSingleObject(ghSvcStopEvent, INFINITE)

ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 )

return

}

}

3)控制服务处理程序函数(Handler):在服务程序收到控制请求时由控制分发线程引用。(此处是Service_Ctrl)。

void WINAPI Service_Ctrl(DWORD dwCtrlCode)

{

//处理控制请求码

switch(dwCtrlCode)

{

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

case SERVICE_CONTROL_STOP:

ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500)

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

/*ssStatus.dwCurrentState=SERVICE_STOPPED*/

//其它控制请求...

default:

break

}

}

3. 注意事项

1)安装服务可以另写一个程序,也可以并在服务程序当中,比较简单,这里就不介绍了。

2)服务初始化函数SvcInit里创建等待事件比较重要,在服务接收到服务停止消息后,触发该事件。

3)Service_Main在等待事件触发后立即返回,服务进程就会退出了

首先个人觉得不能说哪种语言比较好比较流行,在一个平台下开发软件,是根据软件的要求来选择具体的语言,当然“懂技术”的甲方有时候也会“要求”你用哪种语言:)

Windows平台下,具体说:

1、如果性能有限,稳定性优先(甲方也不差钱),那当然最好就是用C/C++;当然说到这里又不免要争论一番到底是用MFC还是QT。。嗯,要我这个骨灰级的来说呢,,我的心中只有MFC。。:)

2、如果是考虑开发效率和稳定性,那么C#是最好选择,,真是方便啊!但悲剧的C#程序猿的工资,,,不说了,说多了都是泪:(

3、如果手下技术比较上不了台阶,那不妨搞搞Delphi,甚至VB,,不过这两个现在号偏门。。

4、如果大量的复杂计算,还要画图,还要外部调用各种古怪的系统,而且还不在乎跑的慢。。。那么,恭喜你,matlab,python是个好选择。

5、哎,手下实在没有合适的人,只有一堆做web的,能做C的也就我这几个老东西,而且客户也不那么在乎性能。。。那么,恭喜你,你有了低成本好选择,你可以用electron这个神器,简单低成本漂亮!还可以用C来做混合编程搞定密集运算部分!

其他诸如Java之类的你就看着用吧:)

如果开发时间周期少,界面要求高,选c#或.net其它

如果可以有较长开发周期,且对程序执行效率要求高,图形图像处理复杂,选C++,(vs、QT、Clion、DevC++、Code::Blocks均可开发)

如果涉及算法较多,选Python

如果要考虑今后需要跨多种平台托展,选Java或Python。windows的C++程序如果要转Linux,也可转,但若不是用QT等开发,会有一些改动,尤其如果是MFC框架开发的程序转Linux,改动不小。

编写windows的窗口化程序就需要调用windows提供的API。可以通过大概3种办法:

一是学习win32API就是windows为开发者提供的接口,需用C++语言来调用。

二是学习MFC,MFC是微软提供给开发者的一个类库,以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。三是你可以学习C#语言,C#语言生成面向.net的环境代码,也是可以实现可视化窗口程序的。至于IOS这个你可以查看IOSAPI帮助文档,里面会有一些例子。android开发需要用androidSDK当然android开发需要用到JAVA语言所以还需安装JAVASDK。编辑器可以用Eclipse。

目前,商业客户端如果需要保密一般用C/C++。

以前还有VB、Delphi啥的,现在越来越少了。

.NET、Java之类容易被逆向。

我是从老VB6(非.net的)、Delphi开始学起的,现在都已经逐渐淘汰了,用的人也是越来越少了,我觉得主要看你开发什么样的软件来选择语言,我个人推荐C#或者C++。

C++一般用于开发个人应用,大多数的通用商业程序都是C++开发的,比如迅雷影音。而C#更多用于企业应用,更适合快速开发,调用API,COM组件,DLL都很方便,便于团队合作和使用第三方代码。以前缺点是部署必须带运行库或者用户安转.net依赖,现在win7以上系统已经自带了,况且c#上手比较简单,学习难度小,跨平台容易,首选c#。

其它还有像国产的e语言,中文编程概念方便的很多初学者学习,编写一个进销存的简单软件也可以。

建议用微软的.NET比较好,其实有很多,开发高性能的就用VC

windows 编程就是编译的程序可以在windows环境下运行 可以用的语言很多了,如VB,VC,Delphi,java,C#等等,很多编程软件要调用系统的API函数,MFC,微软基础类(Microsoft Foundation Classes),同VCL(delphi的库)类似,是一种Application Framework,随微软Visual C++ 开发工具发布。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12082760.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存