我在调用 OpenService 和 ControlService 来启动和关闭一个服务的时候,这两个函数很快就返回了,但是服务好像还没有真正启动起来,如果这个时候,我再调用这两个函数启动或者关闭其他依存于刚才启动的那个服务的时候,就会报告“XXXX 内存不能read”这样的错误,请问我该怎么解决这个问题?是不是需要等待服务进行到某个状态的时候才能允许进行相关联的操作?最好能给出一段示范性的代码,出学VC6,概念性的东西领悟起来不是很快,谢谢!

解决方案 »

  1.   


    服务本身的状态是由服务程序本身通知给"服务器控制器".
    1:如果这个服务是你自己写的,你这个问题就不存在了.
    2:在控制某个服务前,先读写这个服务当前的状态,然后再去控制.如:启动服务if( 服务停止 )
    {
       让其启动    while(当服务状态不为"已启动"时继续等待)
       { 
          sleep(200); 
          继续取的服务状态
        }
    }
      

  2.   

    下面是一个保护进程监控服务状态的例子:void CT01App::ProtectIBSservice()
    {
    SC_HANDLE hSC = ::OpenSCManager( NULL, 
    NULL, GENERIC_EXECUTE);
    if( hSC == NULL)
    {
    TRACE( "open SCManager error");
    return;
    }
    SC_HANDLE hSvc = ::OpenService( hSC, "IBSservice",
    SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_STOP);
    if( hSvc == NULL)
    {
    TRACE( "Open www erron。");
    ::CloseServiceHandle( hSC);
    return; 
    }
    // 获得服务的状态
    SERVICE_STATUS status;
    if( ::QueryServiceStatus( hSvc, &status) == FALSE)
    {
    ::CloseServiceHandle( hSvc);
    ::CloseServiceHandle( hSC);
    return;
    }
    if( status.dwCurrentState == SERVICE_STOPPED)
    {
    if( ::StartService( hSvc, NULL, NULL) == FALSE)
    {
    ::CloseServiceHandle( hSvc);
    ::CloseServiceHandle( hSC);
    return;
    }
    int nRetryTime = 5;
    while( ::QueryServiceStatus( hSvc, &status) == TRUE)
    {
    ::Sleep( status.dwWaitHint);
    if( status.dwCurrentState == SERVICE_RUNNING)
    {
    ::CloseServiceHandle( hSvc);
    ::CloseServiceHandle( hSC);
    return;
    }
    if( nRetryTime-- < 0 )
    {
    break;
    }
    }
    }
    ::CloseServiceHandle( hSvc);
    ::CloseServiceHandle( hSC);
    return;
    }
      

  3.   

    Thanks yinshisike and xiaoc1026 !!这个服务不是我写的,我是想给这些服务做一个前台的控制程序。我想问一下,启动一个服务过程是不是要经过几个过程?比如,我调用 StartService 启动某个服务的时候,是不是这个服务从开始启动到完全启动起来这之间要经历几个状态过程,我通过调用 QueryServiceStatus 这个函数来查询,最终得到服务的状态为 SERVICE_RUNNING 的时候,就表示服务已经完全启动起来了,是这样的嘛?如果是这样的话,我可以在程序里做一个循环来等待服务完全启动起来,希望大家指点,谢谢!
      

  4.   

    请问我这样调用 ControlService 函数停止服务的时候,为什么总是报告“0x00da6dc8 指令应用 0x00000038 内存。该内存不能为 read”,
    if ( !ControlService(
            m_hSCService,             // handle to service
            SERVICE_CONTROL_STOP,       // service status handle
            &serStatus                  // status buffer
            ) )
    {
           …………
    }
    serStatus 和 m_hSCService 的定义如下:
    SERVICE_STATUS serStatus;
    SC_HANDLE m_hSCService;m_hSCService 已经调用 OpenService 了。
    我跟了程序,就是这句的问题,但是不知道是那里错了?!谁帮我看一下,谢谢
      

  5.   

    如果查询到的状态为SERVICE_RUNNING,那么就说明这个服务启动成功了。实际上这个状态是服务程序设置的。当它完成了所有的初始化工作后,通知服务管理器将状态由PENDING改为RUNNING,也就是说这是服务程序的功能的一部分。如果这个服务程序写得不严谨,还没初始化完就把状态设置为RUNNING,那也没办法另外,调用ControlService停止服务的时候报错,这个是服务程序的问题,跟你的前台管理程序没关系。如果是有依赖关系的话,先去停止那些依赖于它的服务,然后在停止该服务本身。
      

  6.   

    果然是服务程序的问题,不是服务管理程序的问题,谢谢!请问谁有 Services.msc 中那样能带进度提示的控制进程启动和停止的服务界面代码,谢谢!