用DeleteService之后服务只是作了一个删除标志,再创建服务就会失败,返回ERROR_SERVICE_MARKED_FOR_DELETE。如果直接删除注册表,windows的服务管理器还是会显示那个服务(还存在哪里了?),只是属性都没有所以我现在是先DeleteService,然后删除注册表不知道windows是否提供了API彻底的删除服务?ps,关于CreateService返回ERROR_SERVICE_MARKED_FOR_DELETE的这个问题,我看网上的例子似乎都没有说明这个问题,真是没这个问题码?

解决方案 »

  1.   

    比如有一个服务程序 a.exeShellExecute "a.exe /UnregServer"取消注册就可以了
    或者导放 a.exe的输出节调用
      

  2.   

    “或者导放 a.exe的输出节调用”
    楼上高,这个话我都没看懂,呵呵
      

  3.   


    void CServerCallDlg::CreateBtnClick()
    {

    UpdateData(true);
    m_scm=OpenSCManager(
           NULL,                      // 指定计算机名为本机
       NULL,                      // 指定要打开的service control managerdatabase名, 默认为空
       SC_MANAGER_CREATE_SERVICE  // 允许创建服务对象并把它加入database
       );
    if (m_scm!=NULL)//if open server database succeeds
    {
         /*SC_HANDLE*/m_svc=CreateService(
                    m_scm,                 // server database 的句柄
    "AlarmService",        // Service名字
    "AlarmService",        // 为Service显示用名
                    SERVICE_ALL_ACCESS,    // 指定server的使用权限,可使用所有的权限
    // 指定server的类型,
                                // Service that runs in its own process
    // The service can interact with the desktop
                    SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
                    SERVICE_AUTO_START,    // 以自动方式开始
                    SERVICE_ERROR_IGNORE,  //说明当Service在启动中出错时采取什么动作
    //"D:\\Program Files\\安放服务\\AlarmService.exe",
    m_ExeFile,
    NULL,NULL,NULL,NULL,NULL
                    );
    if (m_svc!=NULL)
    {
    MessageBox("CREATE  SERVIVR SUCCEEDS ! ");
    }
        else
    {
       MessageBox("CREATE  SERVIVR FAILED") ;
    }

    GetDlgItem(IDB_CREATE)->EnableWindow(FALSE); // 将“CreateServer”按扭失效
    GetDlgItem(IDB_DEL)->EnableWindow(TRUE);     // 将“DeleteServer”按扭生效
    GetDlgItem(IDB_STR)->EnableWindow(TRUE); 

    CloseServiceHandle(m_svc);
    CloseServiceHandle(m_scm);
    }//end of if
    }void CServerCallDlg::DeleteBtnClick()
    {
     m_scm=OpenSCManager (
                NULL,
            NULL,
            SC_MANAGER_CONNECT//允许连接到service control manager database 
                ); if (m_scm!=NULL)// 1st if
        {
      m_svc = OpenService (
           m_scm,
           "AlarmService",
           SERVICE_ALL_ACCESS
           ); if (m_svc!=NULL)//2st if
    {
    //查询servers数据库的状态
    QueryServiceStatus(m_svc,&m_ServiceStatus); //删除前,先停止此Service.
    if (m_ServiceStatus.dwCurrentState == SERVICE_RUNNING)
    {
    ControlService(m_svc,SERVICE_CONTROL_STOP,&m_ServiceStatus);

    DeleteService(m_svc); CloseServiceHandle(m_svc); //删除Service后,最好再调用CloseServiceHandle,以便立即从数据库中移走此条目。

    CloseServiceHandle(m_scm);
        }    GetDlgItem(IDB_DEL)->EnableWindow(FALSE);       // 将“DeleteServer”按扭失效
    GetDlgItem(IDB_CREATE)->EnableWindow(TRUE); // 将“CreateServer”按扭失效
    GetDlgItem(IDB_STR)->EnableWindow(FALSE);  
    GetDlgItem(IDB_STOP)->EnableWindow(FALSE);  

    MessageBox("DELETE SERVICE SUCCEEDS !");
    }void CServerCallDlg::StartBtnClick()
    {
    m_scm=OpenSCManager(
      NULL,
      NULL,
      SC_MANAGER_CONNECT//允许连接到service control manager database 
      );
    if (m_scm!=NULL)
    {
    m_svc=OpenService(
     m_scm,
     "AlarmService",
     SERVICE_START //Enables calling of the StartService function to start the service.          
     );
    if (m_svc!=NULL)
    {
    //开始Service
    StartService (  m_svc,   //为指向Service的句柄,由OpenService返回
                0,       //为启动服务所需的参数的个数
                NULL     //为 启 动 服务所需的参数
             );
        CloseServiceHandle(m_svc);
        CloseServiceHandle(m_scm);
    GetDlgItem(IDB_STR)->EnableWindow(FALSE);  
    GetDlgItem(IDB_STOP)->EnableWindow(TRUE);  
    MessageBox("START SERVICE SUCCEEDS !");

    }
    else
    {
    DWORD  error = GetLastError();
    CString errcode ;
    errcode.Format("启动服务错误,错误的类型识:%d",(int)error);
    AfxMessageBox(errcode);
    }
    }
    }void CServerCallDlg::StopBtnClick()
    {
        //LPSERVICE_STATUS ServiceStatus ;
    m_scm=OpenSCManager(
    NULL,
    NULL,
    SC_MANAGER_ALL_ACCESS//取得所有的权限
    ); if (m_scm!=NULL) //1st if
    {
    m_svc=OpenService(
    m_scm,
    "AlarmService",
    //Enables calling of the ControlService function to stop the service
    //Enables calling of the QueryServiceStatus function to query the status of the service.
    SERVICE_STOP|SERVICE_QUERY_STATUS
    );
    if (m_svc!=NULL)//2st if
    {
    QueryServiceStatus(m_svc,&m_ServiceStatus);//查询server的状态
    if (m_ServiceStatus.dwCurrentState==SERVICE_RUNNING)//3st if
    {
                    ControlService(m_svc,SERVICE_CONTROL_STOP,&m_ServiceStatus);
                  MessageBox("STOP SERVVICE SUCCEEDS !"); }//end  3st if
    CloseServiceHandle(m_svc);
    }//end of 2st if
    CloseServiceHandle(m_scm);
    }//end  1st if
        GetDlgItem(IDB_STR)->EnableWindow(TRUE);  
    GetDlgItem(IDB_STOP)->EnableWindow(FALSE);  
    }
      

  4.   

    to 楼上:
    看你的代码关键似乎是这句:
    CloseServiceHandle(m_svc); //删除Service后,最好再调用CloseServiceHandle,以便立即从数据库中移走此条目。但是我的代码里面也确实关闭了SC_HANDLE,但是注册表还是存在,再建服务就会返回服务已经被标记为删除的错误void SUnInstall(SC_HANDLE hSCDB)
    {
    try
    {
    SC_HANDLE h1=OpenService(hSCDB,SERVICE_NAME,SERVICE_ALL_ACCESS); 
    if(!h1)
    {
    throw "打开服务失败。";
    }
    SERVICE_STATUS_PROCESS stStatus;
    if(QueryServiceStatusEx(h1,SC_STATUS_PROCESS_INFO,(BYTE*)&stStatus,sizeof(stStatus),NULL))
    {
    SERVICE_STATUS stStatus2;
    ControlService(h1,SERVICE_CONTROL_STOP,&stStatus2);
    }
    else
    {
    SERVICE_STATUS stStatus2;
    ControlService(h1,SERVICE_CONTROL_STOP,&stStatus2);
    }
    if(!DeleteService(h1))
    {
    CloseServiceHandle(h1);
    throw "删除服务失败";
    }
    CloseServiceHandle(h1);
    }
    catch (const char* e1)
    {
    MessageBox(NULL,e1,"错误",MB_OK);
    }
    catch (...) 
    {
    }
    }
    hscDB在函数外面打开、关闭
      

  5.   

    搞清楚了,原来是windows的服务窗口开着,所以暂时作了一个删除标志