头文件
Code
#if !defined(AFX_MYSERVICESTATUS_H__B2E287EF_2595_4A6A_98A8_DEEA5926E037__INCLUDED_)
#define AFX_MYSERVICESTATUS_H__B2E287EF_2595_4A6A_98A8_DEEA5926E037__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CMyServiceStatus
{
public:
CMyServiceStatus(LPTSTR szServiceName);
virtual ~CMyServiceStatus();
public:
BOOL UnInstall(LPCTSTR szServiceName);
BOOL Install(LPCTSTR szServiceName,LPCTSTR szFilePath);
void MyStopService();
void MyStartService();
void Stop();
void MyOpenService();
static unsigned int __stdcall GetServiceStatus(LPVOID lParam);
BOOL Run();
BOOL IsServiceInstalled();
BOOL IsServiceInstalled(LPCTSTR szServiceName);
LPTSTR m_szServiceName;
DWORD m_dwServiceStatus;
private:
SC_HANDLE hSCM;
BOOL m_bNeedExit;
BOOL m_bIsServiceInstalled;
SC_HANDLE hService;
HANDLE m_hThreadOverEvent;
};
#endif // !defined(AFX_MYSERVICESTATUS_H__B2E287EF_2595_4A6A_98A8_DEEA5926E037__INCLUDED_)
CPP实现文件:
Code
// MyServiceStatus.cpp: implementation of the CMyServiceStatus class.
//
/**///////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <process.h>
#include "MyServiceStatus.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/**///////////////////////////////////////////////////////////////////////
// Construction/Destruction
/**///////////////////////////////////////////////////////////////////////
CMyServiceStatus::CMyServiceStatus(LPTSTR szServiceName)
{
m_szServiceName = szServiceName;
m_bIsServiceInstalled = FALSE;
m_bNeedExit = FALSE;
m_dwServiceStatus = 0xFFFFFFFF;
hSCM = NULL;
hService = NULL;
m_hThreadOverEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//初始化线程结束信号,并指定手动复位
if(hSCM == NULL)
hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
}
CMyServiceStatus::~CMyServiceStatus()
{
if(hService)
CloseServiceHandle(hService);
if(hSCM !=NULL)
CloseServiceHandle(hSCM);
}
BOOL CMyServiceStatus::IsServiceInstalled()
{
return m_bIsServiceInstalled;
}
//重载
BOOL CMyServiceStatus::IsServiceInstalled(LPCTSTR szServiceName)
{
BOOL bResult = FALSE;
SC_HANDLE mHService;
if (hSCM != NULL)
{
mHService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);
if (mHService != NULL)
{
bResult = TRUE;
::CloseServiceHandle(mHService);
}
}
return bResult;
}
BOOL CMyServiceStatus::Run()
{
UINT dwThreadId;
HANDLE hThread;
m_bNeedExit = FALSE;
hThread =(HANDLE) _beginthreadex(NULL,0,GetServiceStatus,(void*)this,0,&dwThreadId);
if(hThread != NULL)
{
CloseHandle(hThread);
return TRUE;
}
return FALSE;
}
unsigned int __stdcall CMyServiceStatus::GetServiceStatus(LPVOID lParam)
{
CMyServiceStatus* pThis = reinterpret_cast<CMyServiceStatus*>(lParam);
DWORD dwState = 0xFFFFFFFF;
DWORD dwErr = 0xFFFFFFFF;
while(!pThis->m_bNeedExit)
{
DWORD dResult = WaitForSingleObject(pThis->m_hThreadOverEvent,100);
if(dResult == WAIT_OBJECT_0)
break;
if (pThis->hService) {
// Get the current status
SERVICE_STATUS ss;
memset(&ss, 0, sizeof(ss));
BOOL b = QueryServiceStatus(pThis->hService,
&ss);
if(!b) {
DWORD dwErr = GetLastError();
ASSERT(0);
} else {
dwErr = ss.dwWin32ExitCode;
dwState = ss.dwCurrentState;
// If the service is running, send a control request
// to get its current status
if (dwState == SERVICE_RUNNING) {
b = ::ControlService(pThis->hService,
SERVICE_CONTROL_INTERROGATE,
//Notifies a service that
//it should report its current
//status information to the
//service control manager.
&ss);
if (b) {
dwErr = ss.dwWin32ExitCode;
dwState = ss.dwCurrentState;
}
}
}//end else
pThis->m_dwServiceStatus = dwState;
}//end if
else
{
pThis->MyOpenService();
}
}
}
void CMyServiceStatus::MyOpenService()
{
m_bIsServiceInstalled = FALSE;
m_dwServiceStatus = 0xFFFFFFFF;
if(_tcslen(m_szServiceName)<1)
return;
HKEY hkey;
char szKey[1024];
strcpy(szKey, "SYSTEM\\CurrentControlSet\\Services\\");
strcat(szKey, m_szServiceName);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
szKey,
0,
KEY_QUERY_VALUE,
&hkey) == ERROR_SUCCESS) {
// Yes we are installed
m_bIsServiceInstalled = TRUE;
int m_iStartParam;
int m_iIncParam;
DWORD dwType = 0;
DWORD dwSize = sizeof(m_iStartParam);
RegQueryValueEx(hkey,
"Start",
NULL,
&dwType,
(BYTE*)&m_iStartParam,
&dwSize);
dwSize = sizeof(m_iIncParam);
RegQueryValueEx(hkey,
"Inc",
NULL,
&dwType,
(BYTE*)&m_iIncParam,
&dwSize);
RegCloseKey(hkey);
}
else
return;
if(hSCM != NULL)
{
// open the service
hService = OpenService(hSCM, m_szServiceName, SERVICE_ALL_ACCESS);
}
}
void CMyServiceStatus::Stop()
{
m_bNeedExit = TRUE;
SetEvent(m_hThreadOverEvent);
}
void CMyServiceStatus::MyStartService()
{
if(hService && m_dwServiceStatus == SERVICE_STOPPED)
{
StartService(hService, 0, NULL);
}
}
void CMyServiceStatus::MyStopService()
{
if(hService && m_dwServiceStatus == SERVICE_RUNNING)
{
SERVICE_STATUS ss;
BOOL b = ControlService(hService,
SERVICE_CONTROL_STOP,
&ss);
}
}
BOOL CMyServiceStatus::Install(LPCTSTR szServiceName,LPCTSTR szFilePath)
{
BOOL bResult = FALSE;
if(IsServiceInstalled(szServiceName))
return TRUE;
SC_HANDLE mHService;
if (hSCM != NULL)
{
mHService = ::CreateService(
hSCM, szServiceName, szServiceName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, _T("RPCSS\0"), NULL, NULL);
if(mHService != NULL)
{
bResult = TRUE;
::CloseServiceHandle(mHService);
}
}
return bResult;
}
BOOL CMyServiceStatus::UnInstall(LPCTSTR szServiceName)
{
BOOL bResult = FALSE;
if(!IsServiceInstalled(szServiceName))
return TRUE;
SC_HANDLE mHService;
if (hSCM != NULL)
{
mHService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);
if(mHService != NULL)
{
SERVICE_STATUS status;
::ControlService(mHService, SERVICE_CONTROL_STOP, &status);
bResult = ::DeleteService(hService);
}
}
return bResult;
}
使用示例:
...
#include "MyServiceStatus.h"
class CNTServCtrlDlg : public CDialog
{
...
private:
CMyServiceStatus m_MyServiceStatus;
}
////////////////////////////////////////////////////////////
CNTServCtrlDlg::CNTServCtrlDlg(CWnd* pParent /*=NULL*/)
: CDialog(CNTServCtrlDlg::IDD, pParent),m_MyServiceStatus("FileSync")
{
//{{AFX_DATA_INIT(CNTServCtrlDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_uiTimer = 0;
}
BOOL CNTServCtrlDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CenterWindow();
m_MyServiceStatus.Run();//启动查询状态线程
return TRUE; // return TRUE unless you set the focus to a control
}
void CNTServCtrlDlg::OnTimer(UINT nIDEvent)
{
// Update the status
ShowState();
}
void CNTServCtrlDlg::ShowState()
{
DWORD dwState = 0xFFFFFFFF;
char buf[64];
dwState = m_MyServiceStatus.m_dwServiceStatus;
switch (dwState) {
case SERVICE_STOPPED:
strcpy(buf, "Stopped");
break;
case SERVICE_START_PENDING:
strcpy(buf, "Start pending");
break;
case SERVICE_STOP_PENDING:
strcpy(buf, "Stop pending");
break;
case SERVICE_RUNNING:
strcpy(buf, "Running");
break;
case SERVICE_CONTINUE_PENDING:
strcpy(buf, "Continue pending");
break;
case SERVICE_PAUSE_PENDING:
strcpy(buf, "Pause pending");
break;
case SERVICE_PAUSED:
strcpy(buf, "Paused");
break;
default:
if(!m_MyServiceStatus.IsServiceInstalled())
strcpy(buf,"Service Not Installed");
else
strcpy(buf, "<Unknown>");
break;
}
SetDlgItemText(IDC_STATE, buf);
}
void CNTServCtrlDlg::OnDestroy()
{
m_MyServiceStatus.Stop();//结束CMyServiceStatus中的查询状态线程
CDialog::OnDestroy();
if (m_uiTimer != 0) {
KillTimer(1);
}
}