Good catch.
I'll add some code that uses the current running program title and test with Vista while at it.
Announcement
Collapse
No announcement yet.
Is there a way to stop a reboot/shutdown?
Collapse
X
-
Glad you have what you need Mike but FYI your code didn't prevent my PC (WinXP Home) from rebooting.
I don't have a window with "END PROGRAM" in the title though..
Leave a comment:
-
Mike,
I fixed the sample code http://www.powerbasic.com/support/pb...ION#post300982 so that it doesn't close the message box after 3seconds.
If you add these three functions to your TCP program and insert the Case statements into it's DialogProc that might be all you need?
Code:%SHTDN_REASON_FLAG_USER_DEFINED = &H40000000 FUNCTION IsNt () AS LONG LOCAL tOsVersion AS OSVERSIONINFO tOsVersion.dwOSVersionInfoSize = SIZEOF(tOsVersion) IF GetVersionEx(tOsVersion) THEN FUNCTION = (tOsVersion.dwPlatformId = %VER_PLATFORM_WIN32_NT) END IF END FUNCTION '------------------/IsNt FUNCTION AdjustToken () AS LONG LOCAL hToken AS DWORD LOCAL tokenProcess AS TOKEN_PRIVILEGES ' Get the privilege token for this process. - keep in hToken IF ISFALSE OpenProcessToken(GetCurrentProcess(), %TOKEN_ADJUST_PRIVILEGES OR %TOKEN_QUERY, hToken) THEN EXIT FUNCTION END IF ' Get the value of the shutdown privilege. IF LookupPrivilegeValue(BYVAL %NULL, "SeShutdownPrivilege", tokenProcess.Privileges(0).pLuid) THEN ' Enable the shutdown privilege for this process. tokenProcess.PrivilegeCount = 1 tokenProcess.Privileges(0).Attributes = %SE_PRIVILEGE_ENABLED FUNCTION = AdjustTokenPrivileges(hToken, %FALSE, tokenProcess, 0, BYVAL %NULL, BYVAL %NULL) END IF CloseHandle hToken END FUNCTION '------------------/AdjustTken FUNCTION ResumeShutDown(BYVAL LogOff AS LONG) AS LONG IF IsNT() THEN IF ISFALSE AdjustToken() THEN MSGBOX "Could not obtain shutdown privilege." EXIT FUNCTION END IF END IF ' If you're using Windows XP or later, you may want to provide a shutdown ' reason code in the second parameter. See the Reason.inc file for codes. ' The major reason code should be ORed with the minor reason code. ' eg %SHTDN_REASON_FLAG_USER_DEFINED = &H40000000 IF LogOff = 0 THEN IF ISFALSE ExitWindowsEx(%EWX_SHUTDOWN OR %EWX_FORCEIFHUNG, %SHTDN_REASON_FLAG_USER_DEFINED) THEN MSGBOX "Shutdown failed." END IF ELSE IF ISFALSE ExitWindowsEx(%EWX_LOGOFF, 0) THEN MSGBOX "Shutdown failed." END IF END IF END FUNCTION '------------------/ResumeShutDown CALLBACK FUNCTION DlgProc DIM Res AS LONG STATIC ThisProc, LogOff AS Long '.. SELECT CASE AS LONG CbMsg '.. CASE %WM_QUERYENDSESSION IF ThisProc = 0 THEN ThisProc = %TRUE ' Test for resume shutdown LogOff = IIF(CblParam AND %ENDSESSION_LOGOFF = %ENDSESSION_LOGOFF, 1, 0) PostMessage CbHndl, %WM_USER + 1000, 0, 0 FUNCTION = 0 ' Stop the shutdown process EXIT FUNCTION END IF CASE %WM_USER + 1000 MSGBOX TIME$ & ": Prevented ShutDown." ' Here you could wait for your TCP thread to end... Res = MSGBOX ("Resume Shutdown / LogOff?", %MB_YESNO OR %MB_SYSTEMMODAL _ ' / logoff OR %MB_ICONWARNING OR %MB_DEFBUTTON2, "Ready to quit?") IF Res = %IDYES THEN ResumeShutDown (LogOff) ELSE ThisProc = 0 LogOff = 0 END SELECT END FUNCTION '------------------/DlgProc
Leave a comment:
-
I posted code tested with DDT. PB 9 and XP SP3.
What did you test with?
Just exiting that way does not stop shutdown.
Leave a comment:
-
>This code is to prevent reboot if say a file download is in progress.
Now I am really confused.
If the file download is in your program and you have a global variable indicating a download is in progress, then all you should have to do on WM_QUERYENDSESSION is check that variable and exit with %TRUE or %FALSE as appropriate.
If some other program is NOT checking WM_QUERYENDSESSION during its file downloads, I'd get a new download program.
MCM
Leave a comment:
-
Stop reboot - also closes End Program window
*** SOLVED PROBLEM This code works correctly. Thread may be closed. Thank you. ***
This code is to prevent reboot if say a file download is in progress.
This sniplet shows a global is set so reboot should not be allowed.
Code:CASE %WM_QUERYENDSESSION IF gBusy THEN SLEEP 8000 'normally between 5 and 6 seconds DIALOG DOEVENTS result = EnumWindows(CODEPTR(EnumWindowsProc), 0) END IF EnumWindows uses this logic: IF UCASE$(LEFT$(zTitle,11)) = "END PROGRAM" THEN PostMessage(lHandle, %WM_CLOSE,0,0) 'WM_QUIT doesn't work
Code:#PBFORMS CREATED V1.52 #COMPILE EXE #DIM ALL #PBFORMS BEGIN INCLUDES #IF NOT %DEF(%WINAPI) #INCLUDE "WIN32API.INC" #ENDIF #PBFORMS END INCLUDES #PBFORMS BEGIN CONSTANTS %IDD_DIALOG1 = 101 #PBFORMS END CONSTANTS DECLARE CALLBACK FUNCTION ShowDIALOG1Proc() DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG #PBFORMS DECLARATIONS FUNCTION PBMAIN() ShowDIALOG1 %HWND_DESKTOP END FUNCTION CALLBACK FUNCTION ShowDIALOG1Proc() SELECT CASE AS LONG CBMSG CASE %WM_QUERYENDSESSION SLEEP 8000 'normally between 5 and 6 seconds EnumWindows CODEPTR(EnumWindowsProc), 0 CASE %WM_INITDIALOG ' Initialization handler CASE %WM_NCACTIVATE STATIC hWndSaveFocus AS DWORD IF ISFALSE CBWPARAM THEN ' Save control focus hWndSaveFocus = GetFocus() ELSEIF hWndSaveFocus THEN ' Restore control focus SetFocus(hWndSaveFocus) hWndSaveFocus = 0 END IF CASE %WM_COMMAND ' Process control notifications SELECT CASE AS LONG CBCTL END SELECT END SELECT END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Dialogs ** '------------------------------------------------------------------------------ FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG #PBFORMS BEGIN DIALOG %IDD_DIALOG1->-> LOCAL hDlg AS DWORD DIALOG NEW hParent, "%WM_QUERYENDSESSION NOT ALLOWING REBOOT", 206, 164, 201, 121, %WS_POPUP OR _ %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _ %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg #PBFORMS END DIALOG DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt #PBFORMS BEGIN CLEANUP %IDD_DIALOG1 #PBFORMS END CLEANUP FUNCTION = lRslt END FUNCTION '------------------------------------------------------------------------------ FUNCTION EnumWindowsProc(BYVAL lHandle AS LONG, BYVAL lNotUsed AS LONG) AS LONG LOCAL result AS LONG LOCAL zTitle AS ASCIIZ * 256 GetWindowText lHandle, zTitle, 256 zTitle = EXTRACT$(zTitle,$NUL) IF UCASE$(LEFT$(zTitle,11)) = "END PROGRAM" THEN PostMessage(lHandle, %WM_CLOSE,0,0) 'WM_QUIT doesn't work with End Program shutdown SLEEP 10 'required DIALOG DOEVENTS FUNCTION = 0 EXIT FUNCTION END IF FUNCTION = 1 'keep looking or signals done END FUNCTION
Last edited by Mike Doty; 24 Nov 2008, 09:21 AM.
Leave a comment:
-
>I'm getting the handle to the End Program dialog and sending...
???
The shutdown sequence is ended...
The WM_QUERYENDSESSION message is sent when the user chooses to end the session or when an application calls the ExitWindows function. If any application returns zero, the session is not ended. The system stops sending WM_QUERYENDSESSION messages as soon as one application returns zero.
If other applications choose to use another mechanism...
Code:CASE %WM_QUERYENDSESSION bQuit = ISTRUE (MSGBOX (question) = %IDYES ) FUNCTION = ISTRUE (bQuit) EXIT FUNCTION
Only thing I can think of which might be interfering with this would be, maybe your process needs certain permissions to "terminate the Windows' shutdown sequence"
Leave a comment:
-
Can End Program dialog be closed with PostMessage?
I'm getting the handle to the End Program dialog and sending
x = PostMessage(gShutDownHandle, %WM_QUIT,0,0) 'returns 1
'This doesn't close the End Program dialog. How would it be done?
'Is %WM_QUIT the correct message to send
'Is this the correct windows handle?
Tried modifying the code to shutdown NOTEPAD and it does shut NOTEPAD so
the code might be close to ending the shutdown dialog?
Tried SendMessage without luck, too.
I'll try sending ALT+F4 next.
Code:CALLBACK FUNCTION MyCallBack() LOCAL x AS LONG SELECT CASE AS LONG CBMSG CASE %WM_QUERYENDSESSION SLEEP 10000 'wait for end program dialog EnumWindows CODEPTR(EnumWindowsProc), 0 IF gShutDownHandle THEN x = PostMessage(gShutDownHandle, %WM_QUIT,0,0) ? "Result was" + STR$(x) 'returns 1 END IF ? "Here as a safeguard" FUNCTION EnumWindowsProc(BYVAL lHandle AS LONG, BYVAL lNotUsed AS LONG) AS LONG LOCAL result AS LONG gsTitle = STRING$(256,0) GetWindowText lHandle, BYVAL STRPTR(gsTitle), 256 gsTitle = EXTRACT$(gsTitle,CHR$(0)) IF UCASE$(LEFT$(gsTitle,11)) = "END PROGRAM" THEN gShutDownHandle = lHandle result = PostMessage(lHandle, %WM_QUIT,0,0) 'returns 1 EXIT FUNCTION END IF FUNCTION = 1 'keep looking while 1 END FUNCTION
Last edited by Mike Doty; 24 Nov 2008, 06:23 AM.
Leave a comment:
-
Dave,
Your code works. It displays the first message box for 3-seconds which is better than my unpredictable results. It then allows not allowing
the reboot. I will try the same method and get back. I'm not sure that
my TCP session will be trashed in the process, but at least I can notify
the user it wasn't completed.
Michael DDT 9 modal.
Leave a comment:
-
Code:CASE %WM_QUERYENDSESSION PostQuitMessage 0
"Normally " you'd post WM_QUIT on WM_DESTROY. That might be causing you some issues.
For that matter if this is the callback for a MODAL dialog (code not shown) then PostQuitmessage is not required at all.
Leave a comment:
-
-
Is there a way to stop a reboot/shutdown?
This code might slow down a reboot, but won't prevent it.
Using DDT with PB 9 on XP SP3. If TCP transfer is in progress
it is halted (which is what I'm trying to complete.)
Code:CALLBACK FUNCTION MyCallBack() SELECT CASE AS LONG CBMSG CASE %WM_QUERYENDSESSION PostQuitMessage 0 FUNCTION = %TRUE ' don't allow default action 'BEEP 'PostQuitMessage 0 'PostMessage CBHNDL, %WM_USER + 2049, 0, 0 'DoNotEnd
Tags: None
Leave a comment: