Namestitev sem dopolnil še z možnostjo zagona/zaustavitve poljubnega sistemskega servisa (v tej fazi brez odvisnih servisov).
This commit is contained in:
parent
93ed14df64
commit
32ef7ddcb2
50
MSICALib.h
50
MSICALib.h
@ -476,14 +476,33 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// COpSvcControl
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class COpSvcControl : public COpTypeSingleString
|
||||
{
|
||||
public:
|
||||
COpSvcControl(LPCWSTR pszService = L"", BOOL bWait = FALSE, int iTicks = 0);
|
||||
|
||||
static DWORD WaitForState(CSession *pSession, SC_HANDLE hService, DWORD dwPendingState, DWORD dwFinalState);
|
||||
|
||||
friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpSvcControl &op);
|
||||
friend inline HRESULT operator >>(ATL::CAtlFile &f, COpSvcControl &op);
|
||||
|
||||
protected:
|
||||
BOOL m_bWait;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// COpSvcStart
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class COpSvcStart : public COpTypeSingleString
|
||||
class COpSvcStart : public COpSvcControl
|
||||
{
|
||||
public:
|
||||
COpSvcStart(LPCWSTR pszService = L"", int iTicks = 0);
|
||||
COpSvcStart(LPCWSTR pszService = L"", BOOL bWait = FALSE, int iTicks = 0);
|
||||
virtual HRESULT Execute(CSession *pSession);
|
||||
};
|
||||
|
||||
@ -492,10 +511,10 @@ public:
|
||||
// COpSvcStop
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class COpSvcStop : public COpTypeSingleString
|
||||
class COpSvcStop : public COpSvcControl
|
||||
{
|
||||
public:
|
||||
COpSvcStop(LPCWSTR pszService = L"", int iTicks = 0);
|
||||
COpSvcStop(LPCWSTR pszService = L"", BOOL bWait = FALSE, int iTicks = 0);
|
||||
virtual HRESULT Execute(CSession *pSession);
|
||||
};
|
||||
|
||||
@ -1438,6 +1457,29 @@ inline HRESULT operator >>(ATL::CAtlFile &f, COpSvcSetStart &op)
|
||||
}
|
||||
|
||||
|
||||
inline HRESULT operator <<(ATL::CAtlFile &f, const COpSvcControl &op)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = f << (const COpTypeSingleString&)op; if (FAILED(hr)) return hr;
|
||||
hr = f << (int)(op.m_bWait); if (FAILED(hr)) return hr;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
inline HRESULT operator >>(ATL::CAtlFile &f, COpSvcControl &op)
|
||||
{
|
||||
HRESULT hr;
|
||||
int iValue;
|
||||
|
||||
hr = f >> (COpTypeSingleString&)op; if (FAILED(hr)) return hr;
|
||||
hr = f >> iValue; if (FAILED(hr)) return hr; op.m_bWait = iValue ? TRUE : FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
inline HRESULT operator <<(ATL::CAtlFile &f, const COpList &list)
|
||||
{
|
||||
POSITION pos;
|
||||
|
65
OpSvc.cpp
65
OpSvc.cpp
@ -76,11 +76,60 @@ HRESULT COpSvcSetStart::Execute(CSession *pSession)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// COpSvcControl
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
COpSvcControl::COpSvcControl(LPCWSTR pszService, BOOL bWait, int iTicks) :
|
||||
COpTypeSingleString(pszService, iTicks),
|
||||
m_bWait(bWait)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DWORD COpSvcControl::WaitForState(CSession *pSession, SC_HANDLE hService, DWORD dwPendingState, DWORD dwFinalState)
|
||||
{
|
||||
PMSIHANDLE hRecordProg = ::MsiCreateRecord(3);
|
||||
|
||||
// Prepare hRecordProg for progress messages.
|
||||
::MsiRecordSetInteger(hRecordProg, 1, 2);
|
||||
::MsiRecordSetInteger(hRecordProg, 3, 0);
|
||||
|
||||
// Wait for the service to start.
|
||||
for (;;) {
|
||||
SERVICE_STATUS_PROCESS ssp;
|
||||
DWORD dwSize;
|
||||
|
||||
// Check service status.
|
||||
if (::QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwSize)) {
|
||||
if (ssp.dwCurrentState == dwPendingState) {
|
||||
// Service is pending. Wait some more ...
|
||||
::Sleep(ssp.dwWaitHint < 1000 ? ssp.dwWaitHint : 1000);
|
||||
} else if (ssp.dwCurrentState == dwFinalState) {
|
||||
// Service is in expected state.
|
||||
return NO_ERROR;
|
||||
} else {
|
||||
// Service is in unexpected state.
|
||||
return ERROR_ASSERTION_FAILURE;
|
||||
}
|
||||
} else {
|
||||
// Service query failed.
|
||||
return ::GetLastError();
|
||||
}
|
||||
|
||||
// Check if user cancelled installation.
|
||||
::MsiRecordSetInteger(hRecordProg, 2, 0);
|
||||
if (::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL)
|
||||
return ERROR_INSTALL_USEREXIT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// COpSvcStart
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
COpSvcStart::COpSvcStart(LPCWSTR pszService, int iTicks) : COpTypeSingleString(pszService, iTicks)
|
||||
COpSvcStart::COpSvcStart(LPCWSTR pszService, BOOL bWait, int iTicks) : COpSvcControl(pszService, bWait, iTicks)
|
||||
{
|
||||
}
|
||||
|
||||
@ -96,15 +145,15 @@ HRESULT COpSvcStart::Execute(CSession *pSession)
|
||||
SC_HANDLE hService;
|
||||
|
||||
// Open the specified service.
|
||||
hService = ::OpenServiceW(hSCM, m_sValue, SERVICE_START);
|
||||
hService = ::OpenServiceW(hSCM, m_sValue, SERVICE_START | (m_bWait ? SERVICE_QUERY_STATUS : 0));
|
||||
if (hService) {
|
||||
// Start the service.
|
||||
if (::StartService(hService, 0, NULL)) {
|
||||
if (pSession->m_bRollbackEnabled) {
|
||||
dwError = m_bWait ? WaitForState(pSession, hService, SERVICE_START_PENDING, SERVICE_RUNNING) : NO_ERROR;
|
||||
if (dwError == NO_ERROR && pSession->m_bRollbackEnabled) {
|
||||
// Order rollback action to stop the service.
|
||||
pSession->m_olRollback.AddHead(new COpSvcStop(m_sValue));
|
||||
}
|
||||
dwError = NO_ERROR;
|
||||
} else {
|
||||
dwError = ::GetLastError();
|
||||
if (dwError == ERROR_SERVICE_ALREADY_RUNNING) {
|
||||
@ -134,7 +183,7 @@ HRESULT COpSvcStart::Execute(CSession *pSession)
|
||||
// COpSvcStop
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
COpSvcStop::COpSvcStop(LPCWSTR pszService, int iTicks) : COpTypeSingleString(pszService, iTicks)
|
||||
COpSvcStop::COpSvcStop(LPCWSTR pszService, BOOL bWait, int iTicks) : COpSvcControl(pszService, bWait, iTicks)
|
||||
{
|
||||
}
|
||||
|
||||
@ -150,16 +199,16 @@ HRESULT COpSvcStop::Execute(CSession *pSession)
|
||||
SC_HANDLE hService;
|
||||
|
||||
// Open the specified service.
|
||||
hService = ::OpenServiceW(hSCM, m_sValue, SERVICE_STOP);
|
||||
hService = ::OpenServiceW(hSCM, m_sValue, SERVICE_STOP | (m_bWait ? SERVICE_QUERY_STATUS : 0));
|
||||
if (hService) {
|
||||
SERVICE_STATUS ss;
|
||||
// Stop the service.
|
||||
if (::ControlService(hService, SERVICE_CONTROL_STOP, &ss)) {
|
||||
if (pSession->m_bRollbackEnabled) {
|
||||
dwError = m_bWait ? WaitForState(pSession, hService, SERVICE_STOP_PENDING, SERVICE_STOPPED) : NO_ERROR;
|
||||
if (dwError == NO_ERROR && pSession->m_bRollbackEnabled) {
|
||||
// Order rollback action to start the service.
|
||||
pSession->m_olRollback.AddHead(new COpSvcStart(m_sValue));
|
||||
}
|
||||
dwError = NO_ERROR;
|
||||
} else {
|
||||
dwError = ::GetLastError();
|
||||
if (dwError == ERROR_SERVICE_NOT_ACTIVE) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user