Jump to content

How can i close all apps that are running with autoit?


Go to solution Solved by Gianni,

Recommended Posts

Posted (edited)
  On 3/5/2021 at 6:39 PM, Nine said:

Cause you probably trying to WinKill Windows itself.  Put a ConsoleWrite in the loop and when you know which windows is causing it, simply discard that window.

Expand  

No, I havent changed anything in the script. Its what you posted.
Also i dont know what you mean.
Maybe Progman? How to exclude it?

Edited by n1kobg
Posted (edited)

because WinList also captures the "Program Manager" windows, ie Windows itself, which, by closing itself, is equivalent to exiting Windows; so if you want to avoid it, as already suggested by @Nine, you have to exclude that window from WinKill (), as for example shown in line 8 (now commented by semicolon) This modified script shows, harmlessly, what would be "death row" windows

#include <array.au3>
Local $var = WinList(), $aVisible[0][2]

For $i = 1 To $var[0][0]
    ; Only display visble windows that have a title
    If $var[$i][0] <> "" And IsVisible($var[$i][1]) Then
        _ArrayAdd($aVisible, $var[$i][0] & '|' & $var[$i][1])
        ; if $var[$i][0] <> "Program Manager" then WinKill($var[$i][1])
    EndIf
Next

_ArrayDisplay($aVisible, "Windows to be killed")

Func IsVisible($handle)
    If BitAND(WinGetState($handle), 2) Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc   ;==>IsVisible

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Posted
  On 3/6/2021 at 8:21 AM, Chimp said:

because WinList also captures the "Program Manager" windows, ie Windows itself, which, by closing itself, is equivalent to exiting Windows; so if you want to avoid it, as already suggested by @Nine, you have to exclude that window from WinKill (), as for example shown in line 8 (now commented by semicolon) This modified script shows, harmlessly, what would be "death row" windows

#include <array.au3>
Local $var = WinList(), $aVisible[0][2]

For $i = 1 To $var[0][0]
    ; Only display visble windows that have a title
    If $var[$i][0] <> "" And IsVisible($var[$i][1]) Then
        _ArrayAdd($aVisible, $var[$i][0] & '|' & $var[$i][1])
        ; if $var[$i][0] <> "Program Manager" then WinKill($var[$i][1])
    EndIf
Next

_ArrayDisplay($aVisible, "Windows to be killed")

Func IsVisible($handle)
    If BitAND(WinGetState($handle), 2) Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc   ;==>IsVisible

 

Expand  

Yes, I understand that and assumed its progman but I guess I dont know how exactly to exclude it from WinKill () 

if $var[$i][0] <> "Program Manager" then WinKill($var[$i][1]) gives me error and If $var[$i][0] <> "Program Manager" And IsVisible($var[$i][1]) Then doesnt change anything
What am I missing here?

Posted (edited)
  On 3/6/2021 at 3:41 PM, Nine said:

Use a MsgBox for each handle before your WinKill and show the title of the window that is causing the shutdown attempt.  When you know it, do as you have been told by @Chimp

Expand  

You just reapeat yourself. You gave me the hint & I already know its the Program Manager. My problem is idk how to exclude it.  this gives me a syntax error.
I use WinGetHandle to remove but its not a good solution. Also it doesnt kill programs in the tray. I think WinGetHandle is better option but have hard time on it as well.

Local $var = WinList()
For $i = 1 To $var[0][0]
if $var[$i][0] <> "Program Manager" then WinKill($var[$i][1]) Then
    EndIf
Next
Local $hWnd = WinGetHandle("[CLASS:#32770]", "")
WinClose($hWnd)
Func IsVisible($handle)
    If BitAND(WinGetState($handle), 2) Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc   ;==>IsVisible

Edited by n1kobg
Posted
  On 3/7/2021 at 2:54 AM, n1kobg said:

You just reapeat yourself.

Expand  

Maybe but you do not seem to be able to help yourself.  And the syntax error what could that be.... 

Hmmm.  A misplaced Then and a useless Endif ?

BTW when you post code, use this tool.

Posted (edited)
  On 3/7/2021 at 12:53 PM, Nine said:

Maybe but you do not seem to be able to help yourself.  And the syntax error what could that be.... 

Hmmm.  A misplaced Then and a useless Endif ?

BTW when you post code, use this tool.

Expand  

Ok, thanx. I used a different file and had to delete some lines, i missed the Endif.
The thing is even without them and no syntaxed error it still doesnt work. Also if I could "help myslef" i wouldnt made the post in the first place.

Its obvious Im missing something but cant figure out what it is. Sadly Im that advanced. I mean its just my 2nd program. I want to be able to stop all apps but exclude my program. im pretty sure WinGetHandle is the better way to do it but this works too. Well, almost works... I can do it with cmd but its an external tool I want to avoid.

Edited by n1kobg
Posted (edited)
  On 3/7/2021 at 1:29 PM, n1kobg said:

I mean its just my 2nd program

Expand  

maybe 

can help you.

#include <array.au3>

killEmAll()
Func killEmAll()
    Local $var = WinList()
    If UBound($var) < 2 Then Return SetError(1, 0, 1)
    ReDim $var[UBound($var)][3]
    For $i = 1 To $var[0][0]
        $var[$i][2] = 0 ; don't
        If $var[$i][0] <> "" And IsVisible($var[$i][1]) Then $var[$i][2] = 1 ; do
        If $var[$i][0] = "Program Manager" Then $var[$i][2] = 0 ; don't
    Next
;~ _ArrayDisplay($var, "Windows to be killed")
    For $i = 1 To $var[0][0]
        If $var[$i][2] Then
            ConsoleWrite($var[$i][1] & @TAB & $var[$i][0] & @CRLF) ; all this you wanna
;~          If Not WinClose($var[$i][1]) Then WinKill($var[$i][1])
        EndIf
    Next
EndFunc   ;==>killEmAll

Func IsVisible($handle)
    If BitAND(WinGetState($handle), 2) Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc   ;==>IsVisible

 

Edited by argumentum
=)

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted
  On 3/7/2021 at 1:37 PM, argumentum said:

maybe 

can help you.

#include <array.au3>
Local $var = WinList(), $aVisible[0][2]
ReDim $var[UBound($var)][3]
For $i = 1 To $var[0][0]
    $var[$i][2] = 0 ; don't
    If $var[$i][0] <> "" And IsVisible($var[$i][1]) Then $var[$i][2] = 1 ; do
    if $var[$i][0] = "Program Manager" Then $var[$i][2] = 0 ; don't
Next
;~ _ArrayDisplay($var, "Windows to be killed")
For $i = 1 To $var[0][0]
    If $var[$i][2] Then ConsoleWrite($var[$i][1] & @TAB & $var[$i][0] & @CRLF) ; all this you wanna WinClose()
Next

Func IsVisible($handle)
    If BitAND(WinGetState($handle), 2) Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc   ;==>IsVisible

 

Expand  

Thanks. I use Au3Info.exe & gpuview. The script doesnt work though. Ill look into it.

Posted (edited)

assuming ProcessExists will get all the windowed Processes first and in order (I think!) when combined with processclose while still in the loop and that the process pid checks as windowed @getting the new top windowed process pid 

I think this should do it quite well 

#include <WinAPIProc.au3>
#include <WinAPISysWin.au3>
#include <Array.au3>

Local $aVar = _WinAPI_EnumWindowsTop()
For $i = 1 To $aVar[0][0] - 1
    If Not _WinAPI_GetWindowLong($aVar[$i][0], $GWL_HWNDPARENT) And _WinAPI_GetWindowText($aVar[$i][0]) Then
        Local $iPID = WinGetProcess($aVar[$i][0])
        If Not $iPID Then ContinueLoop
        $sPN = _WinAPI_GetProcessName($iPID)
        If "SciTE.exe" = $sPN Then ContinueLoop
        Do
            $iPID = ProcessExists($sPN)
            If Not $iPID Then ExitLoop
            $hwnd = _IsProcessWindowed($iPID)
            If $hwnd Then
                ConsoleWrite($iPID & "  " & $sPN & "  " & _WinAPI_GetWindowText($hwnd) & @LF)
;~              ProcessClose($iPID)
                ExitLoop             ;disable this line when using ProcessClose
            Else
                ExitLoop
            EndIf
        Until @error
    EndIf
Next

Func _IsProcessWindowed($iPID)
    If $iPID = 0 Then Return SetError(1, 1, False)
    Local $aData = _WinAPI_EnumProcessWindows($iPID, 1)
    If @error Then Return SetError(@error, 2, False)
    Return $aData[UBound($aData) - 1][0]
EndFunc   ;==>_IsProcessWindowed

Edit: I see the above will need some polishing to work out the "explorer.exe" instances  

So essentially this should be enough:

#include <WinAPIProc.au3>
#include <WinAPISysWin.au3>

Local $aVar = _WinAPI_EnumWindowsTop()
For $i = 1 To $aVar[0][0] - 1
    If Not _WinAPI_GetWindowLong($aVar[$i][0], $GWL_HWNDPARENT) And _WinAPI_GetWindowText($aVar[$i][0]) Then
        Local $iPID = WinGetProcess($aVar[$i][0])
        If Not $iPID Then ContinueLoop
        $sPN = _WinAPI_GetProcessName($iPID)
        If "SciTE.exe" = $sPN Then ContinueLoop
        ProcessClose($iPID)
    EndIf
Next

 

Edited by Deye
Updated the second snippet to be Speedier
Posted (edited)
  On 3/7/2021 at 10:13 PM, Deye said:

assuming ProcessExists will get all the windowed Processes first and in order (I think!) when combined with processclose while still in the loop and that the process pid checks as windowed @getting the new top windowed process pid 

I think this should do it quite well 

#include <WinAPIProc.au3>
#include <WinAPISysWin.au3>
#include <Array.au3>

Local $aVar = _WinAPI_EnumWindowsTop()
For $i = 1 To $aVar[0][0] - 1
    If Not _WinAPI_GetWindowLong($aVar[$i][0], $GWL_HWNDPARENT) And _WinAPI_GetWindowText($aVar[$i][0]) Then
        Local $iPID = WinGetProcess($aVar[$i][0])
        If Not $iPID Then ContinueLoop
        $sPN = _WinAPI_GetProcessName($iPID)
        If "SciTE.exe" = $sPN Then ContinueLoop
        Do
            $iPID = ProcessExists($sPN)
            If Not $iPID Then ExitLoop
            $hwnd = _IsProcessWindowed($iPID)
            If $hwnd Then
                ConsoleWrite($iPID & "  " & $sPN & "  " & _WinAPI_GetWindowText($hwnd) & @LF)
;~              ProcessClose($iPID)
                ExitLoop             ;disable this line when using ProcessClose
            Else
                ExitLoop
            EndIf
        Until @error
    EndIf
Next

Func _IsProcessWindowed($iPID)
    If $iPID = 0 Then Return SetError(1, 1, False)
    Local $aData = _WinAPI_EnumProcessWindows($iPID, 1)
    If @error Then Return SetError(@error, 2, False)
    Return $aData[UBound($aData) - 1][0]
EndFunc   ;==>_IsProcessWindowed

Edit: I see the above will need some polishing to work out the "explorer.exe" instances  

So essentially this should be enough:

#include <WinAPIProc.au3>
#include <WinAPISysWin.au3>

Local $aVar = _WinAPI_EnumWindowsTop()
For $i = 1 To $aVar[0][0] - 1
    If Not _WinAPI_GetWindowLong($aVar[$i][0], $GWL_HWNDPARENT) And _WinAPI_GetWindowText($aVar[$i][0]) Then
        Local $iPID = WinGetProcess($aVar[$i][0])
        $sPN = _WinAPI_GetProcessName($iPID)
        If "SciTE.exe" = $sPN Then ContinueLoop
        WinClose($aVar[$i][0])
    EndIf
Next

 

Expand  

Thank you. Although it leaves the tray, its better than nothing. How to exclude my program here?

Edited by n1kobg
Posted (edited)
  On 3/8/2021 at 6:00 PM, n1kobg said:

Thank You, man :)

Expand  

you're welcome

Edit: Use  ProcessClose($iPID) instead of  WinClose($aVar[$i][0]) So the closing of everything will go much faster

WinClose is the more graceful way of closing a program, That is allowing a program to do a self cleanup before closing

ProcessClose is like  WinKill ( "title" [, "text"] )

#include <WinAPIProc.au3>
#include <WinAPISysWin.au3>

Local $aVar = _WinAPI_EnumWindowsTop()
For $i = 1 To $aVar[0][0] - 1
    If Not _WinAPI_GetWindowLong($aVar[$i][0], $GWL_HWNDPARENT) And _WinAPI_GetWindowText($aVar[$i][0]) Then
        Local $iPID = WinGetProcess($aVar[$i][0])
        If Not $iPID Then ContinueLoop
        $sPN = _WinAPI_GetProcessName($iPID)
        If $sPN = "SciTE.exe" Then ContinueLoop ; youre ProgramName.exe if windowed it needs to remain active
        ProcessClose($iPID)
    EndIf
Next

 

Edited by Deye
added edits as response to ripdad's at the next post
Posted (edited)

Instead of force closing an AutoIt app, you could use: Inter-Process Communication (IPC)

I have several apps that use it for various things including sending a shutdown message.

That way, you have full control of the way each app closes. Not to mention, much more graceful.

And, it won't matter if it's an au3 or exe.

 

Edited by ripdad

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...