用DeleteService之后服务只是作了一个删除标志,再创建服务就会失败,返回ERROR_SERVICE_MARKED_FOR_DELETE。如果直接删除注册表,windows的服务管理器还是会显示那个服务(还存在哪里了?),只是属性都没有所以我现在是先DeleteService,然后删除注册表不知道windows是否提供了API彻底的删除服务?ps,关于CreateService返回ERROR_SERVICE_MARKED_FOR_DELETE的这个问题,我看网上的例子似乎都没有说明这个问题,真是没这个问题码?
或者导放 a.exe的输出节调用
楼上高,这个话我都没看懂,呵呵
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);
}
看你的代码关键似乎是这句:
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在函数外面打开、关闭