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
|
// COpSvcStart
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class COpSvcStart : public COpTypeSingleString
|
class COpSvcStart : public COpSvcControl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
COpSvcStart(LPCWSTR pszService = L"", int iTicks = 0);
|
COpSvcStart(LPCWSTR pszService = L"", BOOL bWait = FALSE, int iTicks = 0);
|
||||||
virtual HRESULT Execute(CSession *pSession);
|
virtual HRESULT Execute(CSession *pSession);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -492,10 +511,10 @@ public:
|
|||||||
// COpSvcStop
|
// COpSvcStop
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class COpSvcStop : public COpTypeSingleString
|
class COpSvcStop : public COpSvcControl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
COpSvcStop(LPCWSTR pszService = L"", int iTicks = 0);
|
COpSvcStop(LPCWSTR pszService = L"", BOOL bWait = FALSE, int iTicks = 0);
|
||||||
virtual HRESULT Execute(CSession *pSession);
|
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)
|
inline HRESULT operator <<(ATL::CAtlFile &f, const COpList &list)
|
||||||
{
|
{
|
||||||
POSITION pos;
|
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::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;
|
SC_HANDLE hService;
|
||||||
|
|
||||||
// Open the specified service.
|
// 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) {
|
if (hService) {
|
||||||
// Start the service.
|
// Start the service.
|
||||||
if (::StartService(hService, 0, NULL)) {
|
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.
|
// Order rollback action to stop the service.
|
||||||
pSession->m_olRollback.AddHead(new COpSvcStop(m_sValue));
|
pSession->m_olRollback.AddHead(new COpSvcStop(m_sValue));
|
||||||
}
|
}
|
||||||
dwError = NO_ERROR;
|
|
||||||
} else {
|
} else {
|
||||||
dwError = ::GetLastError();
|
dwError = ::GetLastError();
|
||||||
if (dwError == ERROR_SERVICE_ALREADY_RUNNING) {
|
if (dwError == ERROR_SERVICE_ALREADY_RUNNING) {
|
||||||
@ -134,7 +183,7 @@ HRESULT COpSvcStart::Execute(CSession *pSession)
|
|||||||
// COpSvcStop
|
// 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;
|
SC_HANDLE hService;
|
||||||
|
|
||||||
// Open the specified service.
|
// 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) {
|
if (hService) {
|
||||||
SERVICE_STATUS ss;
|
SERVICE_STATUS ss;
|
||||||
// Stop the service.
|
// Stop the service.
|
||||||
if (::ControlService(hService, SERVICE_CONTROL_STOP, &ss)) {
|
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.
|
// Order rollback action to start the service.
|
||||||
pSession->m_olRollback.AddHead(new COpSvcStart(m_sValue));
|
pSession->m_olRollback.AddHead(new COpSvcStart(m_sValue));
|
||||||
}
|
}
|
||||||
dwError = NO_ERROR;
|
|
||||||
} else {
|
} else {
|
||||||
dwError = ::GetLastError();
|
dwError = ::GetLastError();
|
||||||
if (dwError == ERROR_SERVICE_NOT_ACTIVE) {
|
if (dwError == ERROR_SERVICE_NOT_ACTIVE) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user