hur.cn - 华软网

 热门搜索

Windows Service 程序 编写问题

  作者:未知    来源:网络    更新时间:2011/7/15
小弟最近在学习service 程序,了解了service程序有三个函数:Service_main 函数,Service_control 函数,和主程序main,但是遇到一个问题,就是service的运行顺序。
首先service要Install是吧,需要CreateService,安装好了以后呢?需要配置入口函数Service_main 是吧,然后在Service_main 里边注册控制函数Service_control 的句柄,请问是这么个顺序吗?如果我只进行到安装,结果会是什么呢?这个时候还能删除吗?
希望大家不吝赐教
---华软 网友回答---
安装服务和服务本体没有关系,安装其实只是写注册表。
---华软网友回复---
如果是一个写好的服务程序,你要安装的话使用 SC 命令就可以了。

如果你自己写服务程序的话,你可以使用网上公开的 SERVICE.CPP 源码
这个是使用 -install 安装, -uninstall卸载  你可以自己更改。

无论怎么样,你都可以是使用SC命令去删除或者安装服务,所以楼主不用担心删除不了。
---华软网友回复---
引用 2 楼 xiaoc1026 的回复:
如果是一个写好的服务程序,你要安装的话使用 SC 命令就可以了。

如果你自己写服务程序的话,你可以使用网上公开的 SERVICE.CPP 源码
这个是使用 -install 安装, -uninstall卸载 你可以自己更改。

无论怎么样,你都可以是使用SC命令去删除或者安装服务,所以楼主不用担心删除不了。


网上的例子里边一般都有这么一种情况:{如果不带参数运行,则认为是服务控制管理出现启动该服务程序},这是什么意思呢?是说重启以后系统自动运行这个程序的情况吗?那应该让这个程序进行什么的操作呢?前提是服务已经安装过一次了
---华软网友回复---
网上的例子里边一般都有这么一种情况:{如果不带参数运行,则认为是服务控制管理出现启动该服务程序},这是什么意思呢?是说重启以后系统自动运行这个程序的情况吗?那应该让这个程序进行什么的操作呢?前提是服务已经安装过一次了
=======
上面已经说了,服务程序和服务的安装程序其实没有关系,不过网上很多程序都将这两个功能合在一起,于是就出现了带参数运行时,它执行安装或是删除的功能,而不带参数运行就相当于服务控制器启动服务的功能。
服务程序本身是比较特殊的,它只能由服务控制器来运行它。
---华软网友回复---
引用 4 楼 wltg2001 的回复:
网上的例子里边一般都有这么一种情况:{如果不带参数运行,则认为是服务控制管理出现启动该服务程序},这是什么意思呢?是说重启以后系统自动运行这个程序的情况吗?那应该让这个程序进行什么的操作呢?前提是服务已经安装过一次了
=======
上面已经说了,服务程序和服务的安装程序其实没有关系,不过网上很多程序都将这两个功能合在一起,于是就出现了带参数运行时,它执行安装或是删除的功能,而不带参数运行就相……


谢谢指导!我还有一个问题
那么系统重启以后服务管理器从哪里获取要运行的代码呢?也就说服务安装过后,下一次再运行该服务的时候,应该做些什么呢?那三个函数还要运行哪些呢?
---华软网友回复---
SERVICE_TABLE_ENTRY 表中记录了服务处理主函数。
---华软网友回复---
引用 5 楼 cjqpker 的回复:
引用 4 楼 wltg2001 的回复:
网上的例子里边一般都有这么一种情况:{如果不带参数运行,则认为是服务控制管理出现启动该服务程序},这是什么意思呢?是说重启以后系统自动运行这个程序的情况吗?那应该让这个程序进行什么的操作呢?前提是服务已经安装过一次了
=======
上面已经说了,服务程序和服务的安装程序其实没有关系,不过网上很多程序都将这两个功能合在一起,于是就出现了带参数运行时,……


C++">

void main(int argc, char **argv)
{

theApp.SZAPPNAME.LoadString( IDS_SZAPPNAME );
theApp.SZSERVICENAME.LoadString( IDS_SZSERVICENAME );
theApp.SZSERVICEDISPLAYNAME.LoadString( IDS_SZSERVICEDISPLAYNAME );
theApp.SZDEPENDENCIES.LoadString( IDS_SZDEPENDENCIES );
theApp.SZDEPENDENCIES.TrimLeft();
theApp.SZDEPENDENCIES.TrimRight();

    SERVICE_TABLE_ENTRY dispatchTable[] =
    {
        { TEXT((LPTSTR)(LPCTSTR)theApp.SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main },
        { NULL, NULL }
    };

    if ( (argc > 1) &&
         ((*argv[1] == '-') || (*argv[1] == '/')) )
    {
        if ( _stricmp( "install", argv[1]+1 ) == 0 )
        {
            if( !CmdInstallService() )
{
CmdRemoveService();
CmdInstallService();
}
        }
        else if ( _stricmp( "remove", argv[1]+1 ) == 0 )
        {
            CmdRemoveService();
        }
else if ( _stricmp( "stop", argv[1]+1 ) == 0 )
{
CmdStopService();
}
else if(  _stricmp( "start", argv[1]+1 ) == 0 )
{
CmdStartService();
}
        else if ( _stricmp( "debug", argv[1]+1 ) == 0 )
        {
            bDebug = TRUE;
            CmdDebugService(argc, argv);
        }
else if(_stricmp("protect",argv[1]+1)==0)
{
CmdProtectToService();
}
        else
        {
            goto dispatch;
        }
        exit(0);
    }

    // if it doesn't match any of the above parameters
    // the service control manager may be starting the service
    // so we must call StartServiceCtrlDispatcher
    dispatch:
        // this is just to be friendly
        printf( "%s -install          to install the service\n", theApp.SZAPPNAME );
        printf( "%s -remove           to remove the service\n", theApp.SZAPPNAME );
        printf( "%s -debug <params>   to run as a console app for debugging\n", theApp.SZAPPNAME );
        printf( "\nStartServiceCtrlDispatcher being called.\n" );
        printf( "This may take several seconds.  Please wait.\n" );

        if (!StartServiceCtrlDispatcher(dispatchTable))
            AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
}
BOOL CmdStartService()
{
BOOL bSucceed = FALSE;
SC_HANDLE   schService;
SC_HANDLE   schSCManager;

schSCManager = OpenSCManager(
NULL,                   // machine (NULL == local)
NULL,                   // database (NULL == default)
SC_MANAGER_ALL_ACCESS   // access required
);
if ( schSCManager )
{

schService = OpenService(schSCManager,TEXT(theApp.SZSERVICENAME),SERVICE_START);
if ( schService )
{
bSucceed = ::StartService(schService,0,NULL);
CloseServiceHandle(schService);
}

CloseServiceHandle(schSCManager);
}
return bSucceed;
}

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

    // register our service control handler:
    //
    sshStatusHandle = RegisterServiceCtrlHandler( TEXT(theApp.SZSERVICENAME), service_ctrl);

    if (!sshStatusHandle)
        goto cleanup;

    // SERVICE_STATUS members that don't change in example
    //
    ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    ssStatus.dwServiceSpecificExitCode = 0;


    // report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr(
        SERVICE_START_PENDING, // service state
        NO_ERROR,              // exit code
        3000))                 // wait hint
        goto cleanup;


    ServiceStart( dwArgc, lpszArgv );

cleanup:

    // try to report the stopped status to the service control manager.
    //
    if (sshStatusHandle)
        (VOID)ReportStatusToSCMgr(
                            SERVICE_STOPPED,
                            dwErr,
                            0);

::OutputDebugString("aqsysservice main quit");

    return;
}


服务启动后运行
::StartService(schService,0,NULL);
它会启动
 { TEXT((LPTSTR)(LPCTSTR)theApp.SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main },
这里设置的 service_main 函数会被运行,
你就可以把代码添加到
ServiceStart 这里就好了
---华软网友回复---
引用 7 楼 xiaoc1026 的回复:
引用 5 楼 cjqpker 的回复:
引用 4 楼 wltg2001 的回复:
网上的例子里边一般都有这么一种情况:{如果不带参数运行,则认为是服务控制管理出现启动该服务程序},这是什么意思呢?是说重启以后系统自动运行这个程序的情况吗?那应该让这个程序进行什么的操作呢?前提是服务已经安装过一次了
=======
上面已经说了,服务程序和服务的安装程序其实没有关系,不过网上很多程序都将这两……


小弟貌似明白了,也就是说每次系统启动,启动该服务时依然要从StartServiceCtrlDispatcher开始是吧。还有最后一个问题,在创建服务和删除服务的时候,对SCM的数据库注册表都要进行操作吗?      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。