Windows 7 prevent shutdown - windows

I want to be able to prevent regular shutdown on windows 7. I found this AutoIt script but its not clicking the CANCEL button on force shutdown dialog really.
Someone can test it and tell me whats wrong exactly?
$WM_QUERYENDSESSION = 0x11
GUIRegisterMsg($WM_QUERYENDSESSION, "Cancel_Shutdown")
$Hwnd = GUICreate("PreventShutdownGUI")
;~ GUISetSTate(#SW_SHOW)
_ShutdownBlockReasonCreate($hwnd, "Sorry, AutoIt > Windows")
TrayTip("Shutdown Blocker - Started", "Denies shutdowns from now on.", 20)
While Sleep(100)
WEnd
_ShutdownBlockReasonDestroy($hwnd)
Func _ShutdownBlockReasonCreate($Hwnd, $wStr)
; http://msdn.microsoft.com/en-us/library/ms...28VS.85%29.aspx
; Prog#ndy
Local $aResult = DllCall("User32.dll", "int", "ShutdownBlockReasonCreate", "hwnd", $Hwnd, "wstr", $wStr)
If #error Then Return SetError(1,0,0)
Return $aResult[0]
EndFunc
Func _ShutdownBlockReasonDestroy($Hwnd)
Local $aResult = DllCall("User32.dll", "int", "ShutdownBlockReasonDestroy", "hwnd", $Hwnd)
If #error Then Return SetError(1,0,0)
Return $aResult[0]
EndFunc
Func Cancel_Shutdown($hWndGUI, $MsgID, $WParam, $LParam)
; This HAS to be here to capture the endsession...
AdlibRegister("Cancel_ShutdownResolver",50)
Return False
EndFunc
Func Cancel_ShutdownResolver()
Local $iOpt = Opt("WinTitleMatchMode",4),$hwnd = WinGetHandle("[CLASS:BlockedShutdownResolver]")
Opt("WinTitleMatchMode",$iOpt)
If $hwnd Then
If #OSVersion = "WIN_7" Then ControlClick($hwnd,"","[CLASS:Button; INSTANCE:1]")
If #OSVersion <> "WIN_7" Then ControlClick($hwnd,"","[CLASS:Button; INSTANCE:2]")
AdlibUnRegister("Cancel_ShutdownResolver")
TrayTip("Shutdown Blocker - Shutdown denied", "Denied shutdown successfull!", 5)
_DeineFunktion() ; <================ Hier musst du deine Funktion einfügen
EndIf
EndFunc
Func _DeineFunktion()
MsgBox(0,"","Das hier ist deine Funktion ;) - Danach musst du erneut _ShutdownBlockReasonDestroy($hwnd) aufrufen, und einen neuen Shutdown machen.")
EndFunc

Looks to me like this is a way of preventing an autoit function getting killed..
_deineFunction() (German for your function) is the function you don't want killed.

Related

Optimizing Tab Control With AutoIT

So I wrote this to simulate a program that would have a start and stop feature, and has a tab design. Right now there is a tab that has a RichEdit object intended to be a running log.
As you can see, after we "start" the program I put just some milliseconds of sleep to simulate running instructions. I created a function to check for requests that would be called on a larger scale randomly throughout code to ping the GUI per say.
#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>
Global Const $h_numOfTabs = 2
Global Enum $H_TAB_1, $H_TAB_2, $H_TAB_END
Global $hGui, $h_logRichEdit, $iMsg, $h_tabs, $h_startButton, $h_stopButton
Example()
Func Example()
$hGui = GUICreate("Example (" & StringTrimRight(#ScriptName, StringLen(".exe")) & ")", 400, 550, -1, -1)
; ADD START AND STOP BUTTONS
$h_startButton = GUICtrlCreateButton( "Start", 50, 450 )
$h_stopButton = GUICtrlCreateButton( "Stop", 150, 450 )
$h_tabs = GUICtrlCreateTab( 5, 5, 390,375 )
; LOG TAB
GUICtrlCreateTabItem( "Log" )
$h_logRichEdit = _GUICtrlRichEdit_Create ( $hGui, "", 8, 30, 384, 347, BitOR( $ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL, $ES_READONLY ) )
; STATS TAB
GUICtrlCreateTabItem( "Stats" )
; Close TABS
GUICtrlCreateTabItem( "" )
GUISetState( #SW_SHOW ) ; initialize the gui
While True
CheckRequests()
WEnd
EndFunc ;==>Example
Func Start()
while true
Sleep(100)
CheckRequests()
WEnd
EndFunc
Func Stop()
EndFunc
Func CheckRequests()
$iMsg = GUIGetMsg()
while $iMsg <> 0
Select
Case $iMsg = $GUI_EVENT_CLOSE
_GUICtrlRichEdit_Destroy($h_logRichEdit) ; needed unless script crashes
; GUIDelete() ; is OK too
Exit
Case $iMsg = $h_tabs
Switch GUICtrlRead( $h_tabs )
Case $H_TAB_1
ControlShow( $hGui, "", $h_logRichEdit )
Case Else
ControlHide( $hGui, "", $h_logRichEdit )
EndSwitch
Case $iMsg = $h_startButton
Start()
Case $iMsg = $h_stopButton
Stop()
EndSelect
$iMsg = GUIGetMsg()
WEnd
EndFunc
At about 500ms sleep, the lag when switching tabs is visible.
My question: On a larger scale, is this how we would handle/update things that are specific to a tab while running a larger program? If not, what would be a more efficient way of updating tab specific properties while running a larger overall program.
I have also seen a design recently where all the tabs and related components were their own GUI's but I am not sure the relevance of everything being its own GUI and if it pertains to this question.
Any help or clarification is greatly appreciated, I am new to AutoIT and trying to figure out some do's and dont's as well as efficiency.
#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>
Global Const $h_numOfTabs = 2
Global Enum $H_TAB_1, $H_TAB_2, $H_TAB_END
Global $hGui, $h_logRichEdit, $iMsg, $h_tabs, $h_startButton, $h_stopButton
Example()
Func Example()
$hGui = GUICreate("Example (" & StringTrimRight(#ScriptName, StringLen(".exe")) & ")", 400, 550, -1, -1)
; ADD START AND STOP BUTTONS
$h_startButton = GUICtrlCreateButton( "Start", 50, 450 )
$h_stopButton = GUICtrlCreateButton( "Stop", 150, 450 )
$h_tabs = GUICtrlCreateTab( 5, 5, 390,375 )
; LOG TAB
GUICtrlCreateTabItem( "Log" )
$h_logRichEdit = _GUICtrlRichEdit_Create ( $hGui, "", 8, 30, 384, 347, BitOR( $ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL, $ES_READONLY ) )
_GUICtrlRichEdit_AppendText($h_logRichEdit, "{\rtf {Showing \b1 Rich Text \b0}")
; STATS TAB
GUICtrlCreateTabItem( "Stats" )
; Close TABS
GUICtrlCreateTabItem( "" )
; Register Windows message.
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUISetState( #SW_SHOW ) ; initialize the gui
GuiMessageLoop()
EndFunc
Func GuiMessageLoop()
While 1
$iMsg = GUIGetMsg()
Switch $iMsg
Case $GUI_EVENT_CLOSE
_GUICtrlRichEdit_Destroy($h_logRichEdit) ; needed unless script crashes
; GUIDelete() ; is OK too
Exit
Case $h_startButton
Start()
Case $h_stopButton
Stop()
EndSwitch
WEnd
EndFunc
Func Start()
ConsoleWrite('# Sleep' & #CRLF)
Sleep(5000)
ConsoleWrite('# Awake' & #CRLF)
EndFunc
Func Stop()
EndFunc
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
Local $iLoWord = _WinAPI_LoWord($lParam)
Local $iHiWord = _WinAPI_HiWord($lParam)
ConsoleWrite('- WM_NOTIFY' & ' ' & $iLoWord & ' ' & $iHiWord & #CRLF)
Switch GUICtrlRead( $h_tabs )
Case $H_TAB_1
ControlShow( $hGui, "", $h_logRichEdit )
Case Else
ControlHide( $hGui, "", $h_logRichEdit )
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Try this example. It uses GuiRegisterMessage to capture
WM_NOTIFY Windows messages. WM_NOTIFY is not an ideal
message code for this, though have not found something
more suitable for only changing Tabs.
The code to hide and show the Rich Edit control has been
moved into the WM_NOTIFY function so that each time a
message is received, the Tab hide and show code executes.
ConsoleWrite is used to show what the events of interest
are doing during testing. If your editor has a output
console pane, then you may be able to view the writes to
the console pane.
If an event such as function Start takes a long time,
then multi-processing may help to allow the Gui to
remain responsive with the message loop.
Want a do don't, avoid (cyclic) recursive function
calls and avoid getting trapped in loops.
Additional References:
Windows Message Codes
AutoIt Wiki about Tabs

Why does my script cause the Ctrl key to be permanently active?

My AutoIt script pastes strings when I press Ctrl + 1, Ctrl + 2, etc.
Func copyPasta1()
Send($texts[1], 1)
EndFunc
Func copyPasta2()
Send($texts[2], 1)
EndFunc
...
HotKeySet("^" & $keys_arr[2], "copyPasta" & ($i - 1))
Sometimes the Ctrl key gets locked so the whole system behaves as if I had Ctrl pressed continuously. Pressing Ctrl resolves it.
I tried using Shift instead, but then Shift gets locked. Anybody has a solution for this ? My script:
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <FileConstants.au3>
#include <Array.au3>
#include <Math.au3>
HotKeySet("^q", "end")
Func end()
SplashTextOn("", "Programm wird beendet", 200, 40, -1, -1, 1, "", 10, 600)
Sleep(1000)
SplashOff()
Exit
EndFunc
Func copyPasta1()
Send($texts[1], 1)
EndFunc
Func copyPasta2()
Send($texts[2], 1)
EndFunc
Func copyPasta3()
Send($texts[3], 1)
EndFunc
Func copyPasta4()
Send($texts[4], 1)
EndFunc
Func copyPasta5()
Send($texts[5], 1)
EndFunc
Func copyPasta6()
Send($texts[6], 1)
EndFunc
Func copyPasta7()
Send($texts[7], 1)
EndFunc
Func copyPasta8()
Send($texts[8], 1)
EndFunc
Func copyPasta9()
Send($texts[9], 1)
EndFunc
; read config File
Local $hFileOpen = FileOpen(#WorkingDir & "\config.cfg", $FO_READ)
If $hFileOpen = -1 Then
MsgBox(1, "", "Keine config Datei gefunden.")
Exit
EndIf
Global $texts[12]
$sFileRead = FileRead($hFileOpen)
FileClose($hFileOpen)
$arr1 = StringSplit($sFileRead, "#TASTE:", 1)
For $i = 2 To _Min($arr1[0], 10)
$arr2 = StringSplit($arr1[$i], "#SATZ:", 1)
If $arr2[0] == 2 Then
$keys_arr = StringSplit($arr2[1], '"', 1)
$texts_arr = StringSplit($arr2[2], '"', 1)
If $keys_arr[0] == 3 And $texts_arr[0] == 3 Then
HotKeySet("^" & $keys_arr[2], "copyPasta" & ($i - 1))
$texts[$i - 1] = $texts_arr[2]
EndIf
EndIf
Next
SplashTextOn("", "Programm gestartet", 200, 40, -1, -1, 1, "", 10, 600)
Sleep(1000)
SplashOff()
While 1
Sleep(1000)
WEnd
Exit
Here is the solution; you just have to add this function, which is from http://www.autoitscript.fr/wiki/FAQ#Pourquoi_la_touche_Ctrl_reste_enfonc.C3.A9e.2C_apr.C3.A8s_que_j.27ai_lanc.C3.A9_mon_script_.3F
#include < Misc.au3 >
;Envoi la chaîne $ss après que les touches Shift Alt et Ctrl sont relachées. Optionnellement, donne une erreur après 1 sec si aucune de ces touches reste enfoncée.
;Nécessite d'inclure misc.au3 dans le script pour la fonction _IsPressed.
Func _SendEx($ss, $warn = "")
Local $iT = TimerInit()
While _IsPressed("10") Or _IsPressed("11") Or _IsPressed("12")
If $warn <> "" And TimerDiff($iT) > 1000 Then
MsgBox(262144, "Avertissement", $warn)
EndIf
Sleep(50)
WEnd
Send($ss)
EndFunc ;==>_SendEx
The comments above can be translated:
Send the $ss string after Shift, Alt and Ctrl keys are released. Optionally return error after 1 second if none of these keys remain pressed.
Requires Misc.au3 for _IsPressed().
And use _SendEx("Your text") instead of Send("Your text").

Detecting system shutdown or logoff

How can I detect when a system is shutting down or logging off with AutoIt?
I need to run a function if the computer is shutdown or logged off while my script is still running.
You need to handle the Message WM_QUERYENDSESSION
Sample Code:
; Define Windows Message Codes
$WM_QUERYENDSESSION = 0x11
; Define Callback Parameter Codes
$ENDSESSION_CLOSEAPP = 0x00000001
$ENDSESSION_CRITICAL = 0x40000000
$ENDSESSION_LOGOFF = 0x80000000
; Register a Callback on the Message to the Function "onShutDown"
GUIRegisterMsg($WM_QUERYENDSESSION, "onShutDown")
; #FUNCTION# ========================================================
; Name...........: onShutDown Example Function
; Description ...: Application receives the WM_QUERYENDSESSION message
;
; Parameters ....:
; $hWndGUI - A handle to the window
; $MsgID - The WM_QUERYENDSESSION identifier
; $wParam - This parameter is reserved for future use
; $lParam - This parameter can be one or more of the following values.
; |0 - The system is shutting down or restarting
; (it is not possible to determine which event is occurring)
; |$ENDSESSION_CLOSEAPP - Application is using a ressource or file that needs to be freed
; |$ENDSESSION_CRITICAL - Application is forced to shut down
; |$ENDSESSION_LOGOFF - The user is logging off
;
; Return values .:
; |True - Allow to Shutdown
; |False - Prevent Shutdown
; Remarks .......: Applications should respect the user's intentions and return TRUE. By default any application returns **TRUE** for this message.
; If shutting down would corrupt the system or media that is being burned, the application can return **FALSE**.
; However, it is good practice to respect the user's actions.
;
Func onShutDown($hWndGUI, $MsgID, $wParam, $lParam)
Return True ; allow Shutdown ( or return "False" to prevent Shutdown )
EndFunc
Also See : List of Windows Message Codes
You can implement OnAutoItExitRegister() in such a way that you can assume the PC is shutting down.
OnAutoItExitRegister("DetectShutdown")
GUICreate("My GUI") ; will create a dialog box that when displayed is centered
GUISetState(#SW_SHOW) ; will display an empty dialog box
; Run the GUI until the dialog is closed
While True
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE Then
OnAutoItExitUnRegister("DetectShutdown")
Exit
EndIf
WEnd
Func DetectShutdown()
MsgBox(0, "", "Shutdown Detected!")
EndFunc
How can I detect when a system is shutting down or logging off with AutoIt?
As per Documentation - Function Reference - OnAutoItExitRegister() :
The mode of exit can be retrieved with #exitMethod.
Also detects user logoff and Windows shutdown.
I need to run a function if the computer is shutdown or logged off while my script is still running.
Example (determination of-, and reaction to exit methods):
#include <AutoItConstants.au3>; #exitMethod constants.
Global Enum $EXIT_OK, _
$EXIT_ONAUTOITEXITREGISTER, _
$EXIT_HOTKEYSET
Global Const $g_iDelayMain = 250
Global Const $g_iDelayExit = 1000 * 5
Global Const $g_sKeyExit = '{ESC}'
Global Const $g_sConsole = '%s-%s-%s %s:%s:%s.%s - #exitCode = %i (%s) #exitMethod = %i (%s)\n'
Global Const $g_aExit = [ _
'OK', _
'OnAutoItExitRegister() failed', _
'HotKeySet() failed' _
]
Global Const $g_aMethod = [ _
'end of script reached', _
'Exit function executed', _
'systray exit function activated', _
'Windows logoff', _
'Windows shutdown' _
]
Global $g_bStateExit = False
Main()
Func Main()
If Not OnAutoItExitRegister('_ReportExit') Then Exit $EXIT_ONAUTOITEXITREGISTER
If Not HotKeySet($g_sKeyExit, 'SetStateExit') Then Exit $EXIT_HOTKEYSET
While Not $g_bStateExit
Sleep($g_iDelayMain)
WEnd
Exit $EXIT_OK
EndFunc
Func _ReportExit()
Local Const $sLine = StringFormat($g_sConsole, _
#YEAR, #MON, #MDAY, #HOUR, #MIN, #SEC, #MSEC, _
#exitCode, $g_aExit[#exitCode], _
#exitMethod, $g_aMethod[#exitMethod] _
)
ConsoleWrite($sLine)
Sleep($g_iDelayExit)
Switch #exitMethod
; Case $EXITCLOSE_NORMAL
; Your code here.
; Case $EXITCLOSE_BYEXIT
; Your code here.
; Case $EXITCLOSE_BYCLICK
; Your code here.
Case $EXITCLOSE_BYLOGOFF
; Your code here.
Case $EXITCLOSE_BYSHUTDOWN
; Your code here.
EndSwitch
EndFunc
Func SetStateExit()
$g_bStateExit = True
EndFunc

Why is HotkeySet() not working with clipboard data?

My clipboard controller could have several items copied to the clipboard when using a hotkey (CTRL + SHIFT + Q), instead of only one item, and pastes all at once (CTRL + SHIFT + W), or paste any of the first 10 items directly (CTRL + SHIFT + 1 … 9). Another option is to clear the clipboard (CTRL + SHIFT + -).
It works just for several copy and pastes, but then trying to make a copy operation nothing is added to the buffer. I couldn't find a reason for this.
Code (problem should be in the addToClipboard() or getAll()) :
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
Global $clipBoard[50]=[""]
Global $counter = 0
HotKeySet("^+q","addToClipboard")
HotKeySet("^+-","emptyAll")
HotKeySet("^+w","getAll")
HotKeySet("^+1","get1")
HotKeySet("^+2","get2")
HotKeySet("^+3","get3")
HotKeySet("^+4","get4")
HotKeySet("^+5","get5")
HotKeySet("^+6","get6")
HotKeySet("^+7","get7")
HotKeySet("^+8","get8")
HotKeySet("^+9","get9")
$hGUI = GuiCreate("Clipboard Controller", 100, 100,Default,Default,$WS_SIZEBOX)
GUISetState()
Func addToClipboard()
Send ("^c")
$copied = ClipGet()
$clipBoard[Mod($counter,50)] = $copied
$counter +=1
EndFunc
Func getByIndex($i)
$statement = $clipBoard[$i]
ClipPut($statement)
Send("^v")
EndFunc
Func getAll()
$statement =""
For $i In $clipBoard
If $i <> "" Then
$statement &= $i & #CRLF
EndIf
Next
ClipPut($statement)
Send("^v")
EndFunc
Func emptyAll()
For $i=0 To 49
$clipBoard[$i]=""
Next
ClipPut("")
EndFunc
Func get1()
getByIndex(0)
EndFunc
Func get2()
getByIndex(1)
EndFunc
Func get3()
getByIndex(2)
EndFunc
Func get4()
getByIndex(3)
EndFunc
Func get5()
getByIndex(4)
EndFunc
Func get6()
getByIndex(5)
EndFunc
Func get7()
getByIndex(6)
EndFunc
Func get8()
getByIndex(7)
EndFunc
Func get9()
getByIndex(8)
EndFunc
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Problem is an old trap...
It takes a small amount of time to copy to the clip board
especially large items..try a sleep after the Send
Func addToClipboard()
Send ("^c")
sleep(1000) ; try different values
$copied = ClipGet()
$clipBoard[Mod($counter,50)] = $copied
$counter +=1
EndFunc
anyway like your script..idea
The problem is the code for addToClipboard is running while the user still has the keys pressed down. As a result, the Send command designed to send just Ctrl+C is in effect sending Ctrl+Shift+C, so the text is never copied.
The solution is to wait for the user to raise those keys, using the _IsPressed function, then once all keys are released, execute the code. It may also be wise to disable the hotkey when you enter the function (and re-enable when you leave) so that holding the hotkey down for a long time doesn't keep triggering the function.
An alternative would be to send the WM_COPY message directly to the control with focus. This is not guaranteed to work for every control (though I'd be very surprised if it didn't). This would be a far more reliable method.
hope this is the end of the problem , I found another way to set/get data from clipboard , functions : _ClipBoard_SetData () & _ClipBoard_GetData() from library <Clipboard.au3> , after trying them it worked well , after all it seems like the problem was in setting and getting data from the clipboard..
will come later isA to assure whether its finally correct or not

Button = Website Link in AutoIT

I have made a button in AutoIT for this program we are making for work we will call it $okmystery and I want $okmystery to like to my company website. Here is a snippet of the code I have so far:
Dim $msg
GUISetState()
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
ExitLoop
Case $msg = $okbutton
; Minimize Current Window
WinSetState( $WINTITLE, "", #SW_MINIMIZE)
While Not BitAND(WinGetState($WINTITLE, ""), 16)
sleep( 250 )
WEnd
; Take Screen Shots and Logs
ScreenShotAndLogs()
; Compress Artifacts
If FileExists( $ZIPFILEPATH ) Then FileDelete( $ZIPFILEPATH )
_Zip_Create( $ZIPFILEPATH )
_Zip_AddFolderContents( $ZIPFILEPATH, $OUTPUTROOT )
DeleteOriginals()
; Restore main window
WinSetState( $WINTITLE, "", #SW_RESTORE)
;------------ Screen Shot
Case $msg = $okshot
; Minimize Current Window
WinSetState( $WINTITLE, "", #SW_MINIMIZE)
While Not BitAND(WinGetState($WINTITLE, ""), 16)
sleep( 250 )
WEnd
ScreenShot()
; Restore main window
WinSetState( $WINTITLE, "", #SW_RESTORE)
;----------------------------------
$okmystery = ShellExecute ("basic")
Run("Http://www.IT-Networks.org")
Case Default
; Do Nothing
EndSelect
WEnd
Exit( 0 )
It looks like you need to change the "$okmystery" case statement to match the other case statements (if those are all working like they're supposed to).
You can then try to ShellExecute() the url.
Case $msg = $okmystery
ShellExecute("Http://www.IT-Networks.org")
Here's a working example of a GUI with a button that opens your company website in your default web browser:
#include <GUIConstantsEx.au3>
Global $Button_1, $msg
GUICreate("Test GUI Button")
$okmystery = GUICtrlCreateButton("okmystery Button", 10, 30, 100)
GUISetState()
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
ExitLoop
Case $msg = $okmystery
ShellExecute("Http://www.IT-Networks.org")
EndSelect
WEnd

Resources