Delaying Shutdown through windows service and executing scripts ?
-
Hello All, I am working on a project where I need to catch the windows shutdown event through a windows service running in system account, delay shutdown and execute some shutdown scripts and then once the scripts have been completed the shutdown continues.Kindly suggest me some ways to do this via a windows service developed by me in C++. Regards, Kushagra I hate coding but I luv to develop :)
-
Hello All, I am working on a project where I need to catch the windows shutdown event through a windows service running in system account, delay shutdown and execute some shutdown scripts and then once the scripts have been completed the shutdown continues.Kindly suggest me some ways to do this via a windows service developed by me in C++. Regards, Kushagra I hate coding but I luv to develop :)
Have you tried creating a hidden window and handling the
WM_QUERYENDSESSION
message? You may need to turn on the "Allow Service to Interact With Desktop" option."Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
-
Hello All, I am working on a project where I need to catch the windows shutdown event through a windows service running in system account, delay shutdown and execute some shutdown scripts and then once the scripts have been completed the shutdown continues.Kindly suggest me some ways to do this via a windows service developed by me in C++. Regards, Kushagra I hate coding but I luv to develop :)
-
Did you try my suggestions from when you asked this question in September 2009[^]? Best Wishes, -David Delaune
Hello David, I definitely had tried the the function but some how it doesnt seem to work for me.Can you detail me exactly what steps have to be followed in achieving the same. Regards, Kushagra
-
Hello David, I definitely had tried the the function but some how it doesnt seem to work for me.Can you detail me exactly what steps have to be followed in achieving the same. Regards, Kushagra
-
Kushagra Tiwari wrote:
Can you detail me exactly what steps have to be followed in achieving the same.
First can you tell me what operating system will be hosting the Windows service? Best Wishes, -David Delaune
I have to run this in all operating systems namely Windows XP, Windows Server 2003& 2008, Windows Vista,Windows 7. I tried it presently on XP , but the application is meant to be supporting all flavours of Windows after NT Regards, Kushagra
-
Hello All, I am working on a project where I need to catch the windows shutdown event through a windows service running in system account, delay shutdown and execute some shutdown scripts and then once the scripts have been completed the shutdown continues.Kindly suggest me some ways to do this via a windows service developed by me in C++. Regards, Kushagra I hate coding but I luv to develop :)
To catch the Shutdown-Event you have to handle SERVICE_CONTROL_SHUTDOWN or SERVICE_CONTROL_PRESHUTDOWN event in your HandlerEx callback function you registered with RegisterServiceCtrlHandlerEx. (To use this, you need to say the system that your service supports shutdown events. An other possibility is to use the SetConsoleCtrlHandler function where you handle the CTRL_SHUTDOWN_EVENT event in your HandlerRoutine. After you catched the shutdown-event you have to use the function AbortSystemShutdown or just delay your service-shutdown for example with the status SERVICE_STOP_PENDING.
-
Kushagra Tiwari wrote:
Can you detail me exactly what steps have to be followed in achieving the same.
First can you tell me what operating system will be hosting the Windows service? Best Wishes, -David Delaune
Also to call Abort shutdown Method my service first needs to know that a shutdown signal was received. So kindly tell me how my service will come to know about that a shutdown signal was received and where should I place a call to abortshutdown ? Regards, Kushagra
-
To catch the Shutdown-Event you have to handle SERVICE_CONTROL_SHUTDOWN or SERVICE_CONTROL_PRESHUTDOWN event in your HandlerEx callback function you registered with RegisterServiceCtrlHandlerEx. (To use this, you need to say the system that your service supports shutdown events. An other possibility is to use the SetConsoleCtrlHandler function where you handle the CTRL_SHUTDOWN_EVENT event in your HandlerRoutine. After you catched the shutdown-event you have to use the function AbortSystemShutdown or just delay your service-shutdown for example with the status SERVICE_STOP_PENDING.
Thanks Covean, I will try todo this and will let u know as I think this should actually work out Regards, Kushagra
-
I have to run this in all operating systems namely Windows XP, Windows Server 2003& 2008, Windows Vista,Windows 7. I tried it presently on XP , but the application is meant to be supporting all flavours of Windows after NT Regards, Kushagra
Hi Kushagra, This means that you will need to conditionally delay the shutdown based on what operating system the service is running on. There have been some changes in how a shutdown works in Vista and above. These changes are documented here: Application Shutdown Changes in Windows Vista[^] I would suggest creating a hidden window in each interactive logon session and returning FALSE when the window recieves a WM_QUERYENDSESSION message. On Vista and above you will need to call ShutdownBlockReasonCreate before returning FALSE to the WM_QUERYENDSESSION message. Best Wishes, -David Delaune
-
To catch the Shutdown-Event you have to handle SERVICE_CONTROL_SHUTDOWN or SERVICE_CONTROL_PRESHUTDOWN event in your HandlerEx callback function you registered with RegisterServiceCtrlHandlerEx. (To use this, you need to say the system that your service supports shutdown events. An other possibility is to use the SetConsoleCtrlHandler function where you handle the CTRL_SHUTDOWN_EVENT event in your HandlerRoutine. After you catched the shutdown-event you have to use the function AbortSystemShutdown or just delay your service-shutdown for example with the status SERVICE_STOP_PENDING.
Covean wrote:
An other possibility is to use the SetConsoleCtrlHandler function...
Isn't this for console applications?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
-
Covean wrote:
An other possibility is to use the SetConsoleCtrlHandler function...
Isn't this for console applications?
"Old age is like a bank account. You withdraw later in life what you have deposited along the way." - Unknown
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
See http://msdn.microsoft.com/en-us/library/ms683240(VS.85).aspx Its also a good reference about service shutdown. "Services can also use the SetConsoleCtrlHandler function to receive shutdown notification. This notification is received when the running applications are shutting down, which occurs before services are shut down."
-
To catch the Shutdown-Event you have to handle SERVICE_CONTROL_SHUTDOWN or SERVICE_CONTROL_PRESHUTDOWN event in your HandlerEx callback function you registered with RegisterServiceCtrlHandlerEx. (To use this, you need to say the system that your service supports shutdown events. An other possibility is to use the SetConsoleCtrlHandler function where you handle the CTRL_SHUTDOWN_EVENT event in your HandlerRoutine. After you catched the shutdown-event you have to use the function AbortSystemShutdown or just delay your service-shutdown for example with the status SERVICE_STOP_PENDING.
Hello Covean, As per your suggesstion I did the folowing things: In ServiceMain of my service I did the following code : m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler); if (m_hServiceStatus == NULL) { LogEvent(_T("Handler not installed")); return; } and here is the code for _Handler function : void WINAPI CServiceModule::_Handler(DWORD dwOpcode) { char chComputerName[512]; DWORD dwBuff = 512; GetComputerName(chComputerName,&dwBuff); if (dwOpcode == SERVICE_CONTROL_SHUTDOWN) { AbortShutdown(chComputerName); } _Module.Handler(dwOpcode); } and abortshutdown does the following functionality BOOL AbortShutdown(LPTSTR lpMachineName) { HANDLE hToken; // handle to process token TOKEN_PRIVILEGES tkp; // pointer to token structure BOOL 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"); return false; } // Get the LUID for shutdown privilege. LookupPrivilegeValue(lpMachineName, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; // one privilege to set tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get shutdown privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); // Cannot test the return value of AdjustTokenPrivileges. if (GetLastError() != ERROR_SUCCESS) { //TRACE("AdjustTokenPrivileges(setting) enable failed.\n"); return false; } // Prevent the system from shutting down. fResult = AbortSystemShutdown(lpMachineName); if (!fResult) { //TRACE("AbortSystemShutdown failed.\n"); return false; } else { Cxcutter objexe; } //m_bIsShuttingDown = false; // Reset shut down flag // Disable shutdown privilege. tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); if (GetLastError() != ERROR_SUCCESS) { // TRACE("AdjustTokenPrivileges(re-setting) disable failed.\n"); return false; } return true; } But some how the when shutdown is done then the
-
Hello Covean, As per your suggesstion I did the folowing things: In ServiceMain of my service I did the following code : m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler); if (m_hServiceStatus == NULL) { LogEvent(_T("Handler not installed")); return; } and here is the code for _Handler function : void WINAPI CServiceModule::_Handler(DWORD dwOpcode) { char chComputerName[512]; DWORD dwBuff = 512; GetComputerName(chComputerName,&dwBuff); if (dwOpcode == SERVICE_CONTROL_SHUTDOWN) { AbortShutdown(chComputerName); } _Module.Handler(dwOpcode); } and abortshutdown does the following functionality BOOL AbortShutdown(LPTSTR lpMachineName) { HANDLE hToken; // handle to process token TOKEN_PRIVILEGES tkp; // pointer to token structure BOOL 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"); return false; } // Get the LUID for shutdown privilege. LookupPrivilegeValue(lpMachineName, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; // one privilege to set tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get shutdown privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); // Cannot test the return value of AdjustTokenPrivileges. if (GetLastError() != ERROR_SUCCESS) { //TRACE("AdjustTokenPrivileges(setting) enable failed.\n"); return false; } // Prevent the system from shutting down. fResult = AbortSystemShutdown(lpMachineName); if (!fResult) { //TRACE("AbortSystemShutdown failed.\n"); return false; } else { Cxcutter objexe; } //m_bIsShuttingDown = false; // Reset shut down flag // Disable shutdown privilege. tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); if (GetLastError() != ERROR_SUCCESS) { // TRACE("AdjustTokenPrivileges(re-setting) disable failed.\n"); return false; } return true; } But some how the when shutdown is done then the
Does your service get the shutdown notification SERVICE_CONTROL_SHUTDOWN or does AbortSystemShutdown not abort the shutdown? I would say its easier to test the version with SetConsoleCtrl..., after that you should try th service version. Edit: In my first answer I said, that you have to say the system that your service supports SHUTDOWN events. Now I found what i meant. You have to use SetServiceStatus with a SERVICE_STATUS where dwControlsAccepted is a least SERVICE_ACCEPT_SHUTDOWN.
modified on Thursday, October 22, 2009 12:02 PM
-
Does your service get the shutdown notification SERVICE_CONTROL_SHUTDOWN or does AbortSystemShutdown not abort the shutdown? I would say its easier to test the version with SetConsoleCtrl..., after that you should try th service version. Edit: In my first answer I said, that you have to say the system that your service supports SHUTDOWN events. Now I found what i meant. You have to use SetServiceStatus with a SERVICE_STATUS where dwControlsAccepted is a least SERVICE_ACCEPT_SHUTDOWN.
modified on Thursday, October 22, 2009 12:02 PM
Ok , I will try with this and attempt achieve the same
-
Does your service get the shutdown notification SERVICE_CONTROL_SHUTDOWN or does AbortSystemShutdown not abort the shutdown? I would say its easier to test the version with SetConsoleCtrl..., after that you should try th service version. Edit: In my first answer I said, that you have to say the system that your service supports SHUTDOWN events. Now I found what i meant. You have to use SetServiceStatus with a SERVICE_STATUS where dwControlsAccepted is a least SERVICE_ACCEPT_SHUTDOWN.
modified on Thursday, October 22, 2009 12:02 PM
Covean wrote:
. You have to use SetServiceStatus with a SERVICE_STATUS where dwControlsAccepted is a least SERVICE_ACCEPT_SHUTDOWN.
As per ur suggestion I tried to do the same but seems the control never reaches my code , I am quite confused actually as I think I am doing every thing which I think is right .Here is what I am doing after calling RegisterserverEx: ::SetServiceStatus(m_hServiceStatus, &m_status); Where m_status is of SERVICE_STATUS type and initialized by : m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS; m_status.dwCurrentState = SERVICE_STOPPED; m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN; m_status.dwWin32ExitCode = 0; m_status.dwServiceSpecificExitCode = 0; m_status.dwCheckPoint = 0; m_status.dwWaitHint = 0; and in Handler function of my Service handle SERVICE_CONTROL_SHUTDOWN which has following code char chComputerName[512]; DWORD dwBuff = 512; GetComputerName(chComputerName,&dwBuff); switch (dwOpcode) { case SERVICE_CONTROL_STOP: SetServiceStatus(SERVICE_STOP_PENDING); Alive = true; iscmcontrol = 3; PostThreadMessage(dwThreadID, WM_QUIT, 0, 0); break; case SERVICE_CONTROL_PAUSE: Alive = false; iscmcontrol = 1; break; case SERVICE_CONTROL_CONTINUE: Alive = false; iscmcontrol = 0; break; case SERVICE_CONTROL_INTERROGATE: break; case SERVICE_CONTROL_SHUTDOWN: CoInitialize( NULL ); AbortShutdown(chComputerName); CoUninitialize(); Alive = true; iscmcontrol = 2; break; default: LogEvent(_T("Bad service request")); } If you want the sample code and personally see what is the problem please let me know your email address I will send it to you . Regards, Kushagra
-
Does your service get the shutdown notification SERVICE_CONTROL_SHUTDOWN or does AbortSystemShutdown not abort the shutdown? I would say its easier to test the version with SetConsoleCtrl..., after that you should try th service version. Edit: In my first answer I said, that you have to say the system that your service supports SHUTDOWN events. Now I found what i meant. You have to use SetServiceStatus with a SERVICE_STATUS where dwControlsAccepted is a least SERVICE_ACCEPT_SHUTDOWN.
modified on Thursday, October 22, 2009 12:02 PM
Hello Covean, Did you recieve my mail having the sample code?? Kushagra
-
Hello Covean, Did you recieve my mail having the sample code?? Kushagra
-
Yes I received your code and after some changes (for VS2008 and Vista) I has installed it. Now I'm try to get it to work.
Ok . I hope it works :) Kushagra
-
Yes I received your code and after some changes (for VS2008 and Vista) I has installed it. Now I'm try to get it to work.
Any luck with the code? Regards, Kushagra