copyleft Posted July 1, 2023 Share Posted July 1, 2023 I'm still learning AutoIt and don't quit understand how to invoke Windows api's correctly. But I am trying to write an Autoit script that disables all network connections and logs off a user after the Windows display times out or (better yet after the screen saver come on). However, my script, below complains there is no defined function for " _WinAPI_GetMonitorPowerStatus" and no declaration for "$PowerDeviceD0". Is there some file missing in my AutoIt "include" directory? #RequireAdmin #include <WinAPI.au3> #include <Constants.au3> Global $hWnd = WinWait("[CLASS:Progman]", "", 10) Global $iLastState = _WinAPI_GetMonitorPowerStatus() While 1 $iCurrentState = _WinAPI_GetMonitorPowerStatus() If $iCurrentState <> $iLastState Then If $iCurrentState = $PowerDeviceD0 Then Run("netsh interface set interface ""Local Area Connection"" admin=disable", "", @SW_HIDE) Run("shutdown -l -f", "", @SW_HIDE) EndIf $iLastState = $iCurrentState EndIf Sleep(1000) WEnd Link to comment Share on other sites More sharing options...
Andreik Posted July 1, 2023 Share Posted July 1, 2023 (edited) Because there is no such API. Where did you find _WinAPI_GetMonitorPowerStatus() in WinAPI.au3 or in help file? Why not something like this? $hDummyWin = GUICreate('') GUIRegisterMsg(0x0218, 'WM_POWERBROADCAST') HotKeySet('{ESC}', 'Quit') While True Sleep(10) WEnd Func WM_POWERBROADCAST($hWnd, $Msg, $wParam, $lParam) Switch $wParam Case 0x0004 ; PBT_APMSUSPEND ; Disable stuffs Case 0x0012 ; PBT_APMRESUMEAUTOMATIC ; Enable stuffs EndSwitch EndFunc Func Quit() Exit EndFunc Edited July 1, 2023 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
copyleft Posted July 1, 2023 Author Share Posted July 1, 2023 Sorry. I'm lost. Where do I put: Run("netsh interface set interface ""Local Area Connection"" admin=disable", "", @SW_HIDE) Run("shutdown -l -f", "", @SW_HIDE) Should I replace "While True" with that run code? Link to comment Share on other sites More sharing options...
Andreik Posted July 1, 2023 Share Posted July 1, 2023 (edited) Func WM_POWERBROADCAST($hWnd, $Msg, $wParam, $lParam) Switch $wParam Case 0x0004 ; PBT_APMSUSPEND Run("netsh interface set interface ""Local Area Connection"" admin=disabled", "", @SW_HIDE) Case 0x0012 ; PBT_APMRESUMEAUTOMATIC Run("netsh interface set interface ""Local Area Connection"" admin=enabled", "", @SW_HIDE) EndSwitch EndFunc The loop is to keep your app running. Edited July 1, 2023 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
copyleft Posted July 1, 2023 Author Share Posted July 1, 2023 I appreciate your effort to help me. But I am trying to write an Autoit script that disables all network connections and logs off a user after the Windows display times out. Executing your code, above, does not do that. Link to comment Share on other sites More sharing options...
Andreik Posted July 1, 2023 Share Posted July 1, 2023 (edited) What do you mean by Windows display times out? If you want just to run some code to disable all network connections when the screen saver is running, this is the way: #include <WinAPISys.au3> HotKeySet('{ESC}', 'Quit') While True If IsScreenSaverRunning() Then ; Disable here network and logoff EndIf Sleep(10) WEnd Func Quit() Exit EndFunc Func IsScreenSaverRunning() Local $pvParam = DllStructCreate('bool') _WinAPI_SystemParametersInfo(0x0072, 0, DllStructGetPtr($pvParam)) ; SPI_GETSCREENSAVERRUNNING Return DllStructGetData($pvParam, 1) EndFunc If you want to run the code when the screen in turning off, you can do this: expandcollapse popup#include <WinAPIConv.au3> Global Const $tagGUID_CONSOLE_DISPLAY_STATE = '{6FE69556-704A-47A0-8F24-C28D936FDA47}' Global Const $DISPLAY_OFF = 0x00 Global Const $DISPLAY_ON = 0x01 Global $dStatus = Null, $bExit = False HotKeySet('{ESC}', 'Quit') $hDummyWindow = GUICreate('') $hPSN = RegisterPowerSettingNotification($hDummyWindow) GUIRegisterMsg(0x0218, 'WM_POWERBROADCAST') Do Switch $dStatus Case $DISPLAY_OFF $dStatus = Null ; Disable here network and logoff Case $DISPLAY_ON $dStatus = Null ; Enable network maybe EndSwitch Sleep(10) Until $bExit UnregisterPowerSettingNotification($hPSN) Func RegisterPowerSettingNotification($hWnd) Local $tGUID = _WinAPI_GUIDFromString($tagGUID_CONSOLE_DISPLAY_STATE) Local $aCall = DllCall('user32.dll', 'handle', 'RegisterPowerSettingNotification', 'handle', $hWnd, 'ptr', DllStructGetPtr($tGUID), 'dword', 0) Return $aCall[0] EndFunc Func UnregisterPowerSettingNotification($hHandle) If $hHandle <> Null Then DllCall('user32.dll', 'bool', 'UnregisterPowerSettingNotification', 'handle', $hHandle) EndFunc Func WM_POWERBROADCAST($hWnd, $iMsg, $wParam, $lParam) Local $tPOWERBROADCAST_SETTING = DllStructCreate('ulong Data1;ushort Data2;ushort Data3;byte Data4[8]; dword DataLength; BYTE Data[1]', $lParam) Local $tGUID = _WinAPI_StringFromGUID(DllStructGetPtr($tPOWERBROADCAST_SETTING)) If $tGUID = $tagGUID_CONSOLE_DISPLAY_STATE Then $dStatus = DllStructGetData($tPOWERBROADCAST_SETTING, 'Data') EndFunc Func Quit() $bExit = True EndFunc If you want to run the code when the device enters to sleep mode, use the code from my previous post. Just decide what you want to do. Edited July 2, 2023 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
copyleft Posted July 2, 2023 Author Share Posted July 2, 2023 (edited) Yes, I meant when the screen goes blank after a set period of minutes. However, I tried your second script and nothing happens. Does this script need to be running all the time to detect the console display state? I'm beginning to think that Microsoft just doesn't want any automatic disconnection of network connections, especially on Windows 11. I created a script that initially worked when triggered by Windows Task manager. But it would not run a second time and I basically ended up having the same problem these guys had. And even manually invoking "netsh interface set interface ""Local Area Connection"" admin=disabled" my PC somehow turns networking back on overnight. Not sure what's going on. Definitely not a virus. This is a clean install. I'll mark tthis issue as closed. Thanks again for trying to help me. Edited July 2, 2023 by copyleft update Link to comment Share on other sites More sharing options...
Andreik Posted July 2, 2023 Share Posted July 2, 2023 Quote Does this script need to be running all the time to detect the console display state? What do you think? mikell 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
copyleft Posted July 2, 2023 Author Share Posted July 2, 2023 (edited) Well, with your second script running and the Wndows screen display set to timeout after 1 minute. Nothing happens after several minutes. Edited July 2, 2023 by copyleft Link to comment Share on other sites More sharing options...
Solution Andreik Posted July 2, 2023 Solution Share Posted July 2, 2023 What do you expect to happen? Did you modified the script in any way? When the words fail... music speaks. Link to comment Share on other sites More sharing options...
copyleft Posted July 3, 2023 Author Share Posted July 3, 2023 (edited) I am marking this as solved, even though it isn't. As my knowledge of AutoIt is evidently not as extensive as yours, we seem to be talking past each other. Edited July 3, 2023 by copyleft Link to comment Share on other sites More sharing options...
argumentum Posted July 3, 2023 Share Posted July 3, 2023 27 minutes ago, copyleft said: As my knowledge of AutoIt is evidently not as extensive as yours, ...I should not butt in but, you Run() and Run(). Should RunWait() and Run(). That is a failure in logic. 9 hours ago, copyleft said: Does this script need to be running all the time Another logic failure. 9 hours ago, copyleft said: my PC somehow turns networking back on overnight. Not sure what's going on. Then that's that. But you should log every operation on your code while debugging. If some other Program is doing something else ( like turning the network back on ), then you'll have to investigate that. 33 minutes ago, copyleft said: I am marking this as solved, even though it isn't. Don't quit. But from a member since 2004, your line of questions are quite unexpected. Again, don't quit. Tho, why do you wanna turn the network off ?, what do you gain from that ? Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Andreik Posted July 3, 2023 Share Posted July 3, 2023 I will give you another example but I would kindly suggest to learn basic AutoIt. expandcollapse popup#include <WinAPIConv.au3> Global Const $tagGUID_CONSOLE_DISPLAY_STATE = '{6FE69556-704A-47A0-8F24-C28D936FDA47}' Global Const $DISPLAY_OFF = 0x00 Global Const $DISPLAY_ON = 0x01 Global $dStatus = Null, $bExit = False HotKeySet('{ESC}', 'Quit') $hDummyWindow = GUICreate('') $hPSN = RegisterPowerSettingNotification($hDummyWindow) GUIRegisterMsg(0x0218, 'WM_POWERBROADCAST') Do Switch $dStatus Case $DISPLAY_OFF $dStatus = Null ConsoleWrite('Your display just turned off. Run your damn code here' & @CRLF) MouseMove(Random(0, @DesktopWidth, 1), Random(0, @DesktopHeight, 1)) Case $DISPLAY_ON $dStatus = Null ConsoleWrite('Your display just turned on.' & @CRLF) EndSwitch Sleep(10) Until $bExit UnregisterPowerSettingNotification($hPSN) Func RegisterPowerSettingNotification($hWnd) Local $tGUID = _WinAPI_GUIDFromString($tagGUID_CONSOLE_DISPLAY_STATE) Local $aCall = DllCall('user32.dll', 'handle', 'RegisterPowerSettingNotification', 'handle', $hWnd, 'ptr', DllStructGetPtr($tGUID), 'dword', 0) Return $aCall[0] EndFunc Func UnregisterPowerSettingNotification($hHandle) If $hHandle <> Null Then DllCall('user32.dll', 'bool', 'UnregisterPowerSettingNotification', 'handle', $hHandle) EndFunc Func WM_POWERBROADCAST($hWnd, $iMsg, $wParam, $lParam) Local $tPOWERBROADCAST_SETTING = DllStructCreate('ulong Data1;ushort Data2;ushort Data3;byte Data4[8]; dword DataLength; BYTE Data[1]', $lParam) Local $tGUID = _WinAPI_StringFromGUID(DllStructGetPtr($tPOWERBROADCAST_SETTING)) If $tGUID = $tagGUID_CONSOLE_DISPLAY_STATE Then $dStatus = DllStructGetData($tPOWERBROADCAST_SETTING, 'Data') EndFunc Func Quit() $bExit = True EndFunc Set your screen to turn off after 1 minute, wait and then enjoy the magic (I mean, watch the console). When the words fail... music speaks. Link to comment Share on other sites More sharing options...
seadoggie01 Posted July 3, 2023 Share Posted July 3, 2023 WinAPI is difficult for me and I've been here a while. I'll try explaining what Andreik wrote, but first, let's look at what's fundamentally wrong with your original code... On 7/1/2023 at 12:22 PM, copyleft said: Run("netsh interface set interface ""Local Area Connection"" admin=disable", "", @SW_HIDE) Run("shutdown -l -f", "", @SW_HIDE) These two lines of code look harmless enough, however, they won't do what you're expecting. The Run function starts a task and immediately moves on without waiting for it to finish, so netsh and shutdown happen at (basically) the same time. As argumentum mentioned, you'll want to swap Run with RunWait. RunWait, well, it waits for the command to finish before moving on, so you'll actually disable your network interface before shutting down. With that out of the way, let's add some comments to Andreik's code to make it ... erm... readable? 😁 I've made a couple of minor changes as well expandcollapse popup#include <WinAPIConv.au3> #include <WindowsConstants.au3> ; To get rid of the magic number -- $WM_POWERBROADCAST ; A constant pulled from https://learn.microsoft.com/en-us/windows/win32/power/power-setting-guids Global Const $tagGUID_CONSOLE_DISPLAY_STATE = '{6FE69556-704A-47A0-8F24-C28D936FDA47}' ; Also constants, also defined in link above Global Const $DISPLAY_OFF = 0x00 Global Const $DISPLAY_ON = 0x01 ; Global variables, available anywhere in the script. It's a good idea to limit the number of these as much as possible ; Also, when following the stricter conventions, they start with $__g_<name>... helps you realize that they're global Global $__g_dStatus = Null, $__g_bExit = False ; If the user presses Escape at any point, run the quit function (can be on any screen) HotKeySet('{ESC}', 'Quit') Func Quit() ; Set the global variable so we can quit the script elsewhere $__g_bExit = True EndFunc ; Let's add a main function... this helps to avoid "local" variables that are actually global Main() Func Main() ; Creates a GUI to use to register WinAPI events with. This is quite common with WinAPI. I'd guess it's because events in a GUI are easy to watch for? Local $hDummyWindow = GUICreate('') ; Register the PowerSettingNotification event to our GUI (this function returns a handle, we'll keep it to unregister later) Local $hPSN = RegisterPowerSettingNotification($hDummyWindow) ; Now we tell our GUI that we want to run OnPowerChange when we receive the message GUIRegisterMsg($WM_POWERBROADCAST, 'OnPowerChange') ; Now we wait for the global variable to be updated with the power info Do Switch $__g_dStatus Case $DISPLAY_OFF $__g_dStatus = Null ; Maybe we don't have to swear at people in the console? Just a thought ConsoleWrite('Your display just turned off. Run your code here' & @CRLF) ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; Here you'd call your code to edit the network interface and shutdown ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Case $DISPLAY_ON $__g_dStatus = Null ConsoleWrite('Your display just turned on.' & @CRLF) EndSwitch ; We try to add at least a small sleep call to loops so we don't eat all of the CPU Sleep(10) Until $__g_bExit ; Here we unregister the GUI for power notifications... probably not necessary since you're shutting down, but it's good practice UnregisterPowerSettingNotification($hPSN) EndFunc Func RegisterPowerSettingNotification($hWnd) Local $tGUID = _WinAPI_GUIDFromString($tagGUID_CONSOLE_DISPLAY_STATE) Local $aCall = DllCall('user32.dll', 'handle', 'RegisterPowerSettingNotification', 'handle', $hWnd, 'ptr', DllStructGetPtr($tGUID), 'dword', 0) Return $aCall[0] EndFunc Func UnregisterPowerSettingNotification($hHandle) If $hHandle <> Null Then DllCall('user32.dll', 'bool', 'UnregisterPowerSettingNotification', 'handle', $hHandle) EndFunc ; This function is called by windows internals. It sets $__g_dStatus so other functions can see it. ; !!!!!! Do NOT put your code in here. See GUIRegisterMsg in the help file for reasons. !!!!!! Func OnPowerChange($hWnd, $iMsg, $wParam, $lParam) ; Create a struct from the data in $lParam. The structure is defined here: https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-powerbroadcast_setting ; Note: (this is the confusing part to me) a GUID is defined elsewhere and you have to replace GUID with its definition: https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid Local $tPOWERBROADCAST_SETTING = DllStructCreate('ulong Data1;ushort Data2;ushort Data3;byte Data4[8]; dword DataLength; BYTE Data[1]', $lParam) ; Get a pointer to the structure and get the string from it (!? Again, getting a bit lost here, but we're basically getting the message) Local $tGUID = _WinAPI_StringFromGUID(DllStructGetPtr($tPOWERBROADCAST_SETTING)) ; If the message matches the Power Setting that we're looking for, then set the global variable to Data (note that there are unique names in the DLL struct above and data is last) If $tGUID = $tagGUID_CONSOLE_DISPLAY_STATE Then $__g_dStatus = DllStructGetData($tPOWERBROADCAST_SETTING, 'Data') EndFunc This is a more difficult topic, so don't be discouraged if you don't get it right away or struggle with writing WinAPI code at first. All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
seadoggie01 Posted July 3, 2023 Share Posted July 3, 2023 12 hours ago, Andreik said: kindly suggest to learn basic AutoIt. 12 hours ago, Andreik said: Run your damn code here Yeah, real "kind". And isn't "learning basic AutoIt" what this forum is all about? 🙄 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
Andreik Posted July 3, 2023 Share Posted July 3, 2023 (edited) If you can't figure out to replace a comment to your desired functionality which it's pretty basic, you need to learn basics. And regarding with what he is asking, yes, you need to learn basics before to get into more complicated APIs. I gave him plenty basic pieces of code and he couldn't figure out, so your comment it's kinda useless. A forum community will assist you in learning but do your own part of the learning. Edited July 3, 2023 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
copyleft Posted July 3, 2023 Author Share Posted July 3, 2023 (edited) @seadoggie01. Wow. Thanks so much for the annotated code; it's been a while since I've run into a post so helpful. Back it 2004 there were a lot more like you around this forum; but now it's a lot of negative energy. Edited July 3, 2023 by copyleft Link to comment Share on other sites More sharing options...
argumentum Posted July 3, 2023 Share Posted July 3, 2023 22 minutes ago, copyleft said: ...but now it's a lot of negative energy. If you behave like an asshole, .. it just don't help either. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Andreik Posted July 3, 2023 Share Posted July 3, 2023 These negative forces solved your problem and constantly pointed you in the right direction but back in 2004 I suppose scripts had to run to actually do something, right? Since the OP's question has been answered I think a moderator can lock this thread. I feel it might end bad for some sensitive people around. PS: @seadoggie01 just type damn in the search box of the forum and you'll get 139 pages of results, so don't be a drama queen. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Developers Jos Posted July 4, 2023 Developers Share Posted July 4, 2023 @All, lets get back to solving issues and leave the emotions somewhere else... so either comment on the topic at hand or simply press the ignore button please. spudw2k 1 SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now