Delaying Shutdown through windows service and executing scripts ?
-
Any luck with the code? Regards, Kushagra
What OS to you use? Cause on Vista I do not find any way to block the shutdown (ShutdownBlockReasonCreate needs a window...). But the service itself works fine. Here some eventlog-output: SetServiceStatus Succeed Service started SetServiceStatus Succeed SERVICE_CONTROL_SHUTDOWN (<- shutdown event caught) AbortSystemShutdown failed! Error=1115 (<- means shutdown already in progress, very funny errorcode :) ) The only thing left is to stop the shutdown. On WinXP your code should work. How do you test your service? You can just catch this event if your app really runs as service in debug mode you will never see this event. Here some code-changes I made (but nothing very special): 1. The "problem" that your SetServiceStatus always "fails":
void ...SetServiceStatus(DWORD dwState)
{
if (::SetServiceStatus(m_hServiceStatus, &m_status) == TRUE)
{
// ...
LogEvent(TEXT("SetServiceStatus Failed"));
}
else
{
// ...
LogEvent(TEXT("SetServiceStatus Failed"));
}
}---> copy & paste is not always your friend. :laugh: 2. In "...::Handler(...)" I made some changes to get more eventlog entries:
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
LogEvent(_T("SERVICE_CONTROL_STOP"));
//...
break;
case SERVICE_CONTROL_PAUSE:
LogEvent(_T("SERVICE_CONTROL_PAUSE"));
break;
case SERVICE_CONTROL_CONTINUE:
LogEvent(_T("SERVICE_CONTROL_CONTINUE"));
break;
case SERVICE_CONTROL_INTERROGATE:
LogEvent(_T("SERVICE_CONTROL_INTERROGATE"));
break;
case SERVICE_CONTROL_SHUTDOWN:
LogEvent(_T("SERVICE_CONTROL_SHUTDOWN"));AbortShutdown(chComputerName); break; //...
}
3. AbortShutdown changes: (AbortShutdown is now part of your Module class, just for LogEvent)
BOOL ...::AbortShutdown(LPTSTR lpMachineName)
{
HANDLE hToken; // handle to process token
TOKEN_PRIVILEGES tkp; // pointer to token structureBOOL fResult; // system shutdown flag
// Get the current process token handle so we can get shutdown
// privilege.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
// TRACE("OpenProcessToken failed.\n");
LogEvent(TEXT("OpenProcessToken failed"));return false; } // Get the LUID for shutdown privilege.
-
What OS to you use? Cause on Vista I do not find any way to block the shutdown (ShutdownBlockReasonCreate needs a window...). But the service itself works fine. Here some eventlog-output: SetServiceStatus Succeed Service started SetServiceStatus Succeed SERVICE_CONTROL_SHUTDOWN (<- shutdown event caught) AbortSystemShutdown failed! Error=1115 (<- means shutdown already in progress, very funny errorcode :) ) The only thing left is to stop the shutdown. On WinXP your code should work. How do you test your service? You can just catch this event if your app really runs as service in debug mode you will never see this event. Here some code-changes I made (but nothing very special): 1. The "problem" that your SetServiceStatus always "fails":
void ...SetServiceStatus(DWORD dwState)
{
if (::SetServiceStatus(m_hServiceStatus, &m_status) == TRUE)
{
// ...
LogEvent(TEXT("SetServiceStatus Failed"));
}
else
{
// ...
LogEvent(TEXT("SetServiceStatus Failed"));
}
}---> copy & paste is not always your friend. :laugh: 2. In "...::Handler(...)" I made some changes to get more eventlog entries:
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
LogEvent(_T("SERVICE_CONTROL_STOP"));
//...
break;
case SERVICE_CONTROL_PAUSE:
LogEvent(_T("SERVICE_CONTROL_PAUSE"));
break;
case SERVICE_CONTROL_CONTINUE:
LogEvent(_T("SERVICE_CONTROL_CONTINUE"));
break;
case SERVICE_CONTROL_INTERROGATE:
LogEvent(_T("SERVICE_CONTROL_INTERROGATE"));
break;
case SERVICE_CONTROL_SHUTDOWN:
LogEvent(_T("SERVICE_CONTROL_SHUTDOWN"));AbortShutdown(chComputerName); break; //...
}
3. AbortShutdown changes: (AbortShutdown is now part of your Module class, just for LogEvent)
BOOL ...::AbortShutdown(LPTSTR lpMachineName)
{
HANDLE hToken; // handle to process token
TOKEN_PRIVILEGES tkp; // pointer to token structureBOOL fResult; // system shutdown flag
// Get the current process token handle so we can get shutdown
// privilege.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
// TRACE("OpenProcessToken failed.\n");
LogEvent(TEXT("OpenProcessToken failed"));return false; } // Get the LUID for shutdown privilege.
Yup you are right ...some time a minute error can take the hell out of ..hehehe :laugh: I am working on the code presently will let you know on the progress . Cheers, Kushagra :thumbsup:
-
What OS to you use? Cause on Vista I do not find any way to block the shutdown (ShutdownBlockReasonCreate needs a window...). But the service itself works fine. Here some eventlog-output: SetServiceStatus Succeed Service started SetServiceStatus Succeed SERVICE_CONTROL_SHUTDOWN (<- shutdown event caught) AbortSystemShutdown failed! Error=1115 (<- means shutdown already in progress, very funny errorcode :) ) The only thing left is to stop the shutdown. On WinXP your code should work. How do you test your service? You can just catch this event if your app really runs as service in debug mode you will never see this event. Here some code-changes I made (but nothing very special): 1. The "problem" that your SetServiceStatus always "fails":
void ...SetServiceStatus(DWORD dwState)
{
if (::SetServiceStatus(m_hServiceStatus, &m_status) == TRUE)
{
// ...
LogEvent(TEXT("SetServiceStatus Failed"));
}
else
{
// ...
LogEvent(TEXT("SetServiceStatus Failed"));
}
}---> copy & paste is not always your friend. :laugh: 2. In "...::Handler(...)" I made some changes to get more eventlog entries:
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
LogEvent(_T("SERVICE_CONTROL_STOP"));
//...
break;
case SERVICE_CONTROL_PAUSE:
LogEvent(_T("SERVICE_CONTROL_PAUSE"));
break;
case SERVICE_CONTROL_CONTINUE:
LogEvent(_T("SERVICE_CONTROL_CONTINUE"));
break;
case SERVICE_CONTROL_INTERROGATE:
LogEvent(_T("SERVICE_CONTROL_INTERROGATE"));
break;
case SERVICE_CONTROL_SHUTDOWN:
LogEvent(_T("SERVICE_CONTROL_SHUTDOWN"));AbortShutdown(chComputerName); break; //...
}
3. AbortShutdown changes: (AbortShutdown is now part of your Module class, just for LogEvent)
BOOL ...::AbortShutdown(LPTSTR lpMachineName)
{
HANDLE hToken; // handle to process token
TOKEN_PRIVILEGES tkp; // pointer to token structureBOOL fResult; // system shutdown flag
// Get the current process token handle so we can get shutdown
// privilege.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
// TRACE("OpenProcessToken failed.\n");
LogEvent(TEXT("OpenProcessToken failed"));return false; } // Get the LUID for shutdown privilege.
I was able to abort shutdown and execute my scripts when the user was logged on to the system by making the service as an interactive service but in case when user was logged off and the shutdown was scheduled , the shutdown was aborted but no scripts were executed.Please suggest what to do in this case when no user is logged on to the system and shutdown was made a scheduled task. Regards, Kushagra
-
I was able to abort shutdown and execute my scripts when the user was logged on to the system by making the service as an interactive service but in case when user was logged off and the shutdown was scheduled , the shutdown was aborted but no scripts were executed.Please suggest what to do in this case when no user is logged on to the system and shutdown was made a scheduled task. Regards, Kushagra
-
Sorry but after I read some information on this, I don't believe, that you will be able to abort this kind of shutdown. But maybe someone else has an idea.
Even I couldn't find any way to do the same . Windows can be harsh to us some times :( . Still I am looking for some tweaks to achieve it . Will let you know if I found some . Regards, Kushagra