Jump to content

List Running Tasks on Remote Machine


Recommended Posts

Hi guys, i am stuck with this piece of code and its driving me nuts....aaaargh..

I am trying to list the tasks running on a remote machine into a gui and i need to figure out how to display the results on the gui and separate the tasks so i can end them individually, i have got half way there and have hit a brick wall.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#include <File.au3>
#include <Constants.au3>

GLobal $in

Func guiexample()
    Local $msg
    Opt("GUIOnEventMode", 1)
    GUICreate("My GUI")
    GUISetState(@SW_SHOW)
    $test = GUICtrlCreateButton("List Tasks",20,20,100,100)
    GUICtrlSetOnEvent($test,"listtasks")
    $test2 = GUICtrlCreateButton("Kill Tasks",120,20,100,100)
    GUICtrlSetOnEvent($test2,"Killtask")
    GUISetOnEvent($GUI_EVENT_CLOSE,"exit1")
    $in = GUICtrlCreateInput("",20,130,200,200)


    While 1
        $msg = GUIGetMsg()

        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd
    GUIDelete()
EndFunc

guiexample()

Func listtasks()
$foo = Run("cmd.exe /c" & "tasklist", @SystemDir, @SW_HIDE, $STDERR_CHILD + $stdout_child)
        Local $line
        While 1
            $line = StdoutRead($foo)
            If @error Then ExitLoop
            $txt = FileOpen("test.txt",2)
            FileWrite($txt,$line)
            Sleep(2000)
        WEnd
            Dim $tx1
            $file = _FileReadToArray("test.txt",$tx1)
            _ArrayDisplay($tx1,"listview")
            For $i = $tx1[5] To $tx1[0] Step 1
            GUICtrlSetData($in, $i)
            Next
            FileClose($txt)
EndFunc

Func Killtask()
    Run("cmd.exe /c" & "taskkill /s  /IM $task", "")
EndFunc

Func exit1()
    Exit
EndFunc

Can somebody point me in the right direction, thanks in advance.

Nav

Link to comment
Share on other sites

Ok Guys i am one step closer, but i need some help with the last hurdle......

I have managed to get the tasks through the WMI but i need some help with adding them to a listview box.

I can get the results to display in a message box but need to add them to listview box

#include <GUIConstantsEx.au3>

    Opt("GUIOnEventMode", 1)
    GUICreate("My GUI",600,600)
    GUISetState(@SW_SHOW)
    $test = GUICtrlCreateButton("List Tasks",20,20,100,100)
    GUICtrlSetOnEvent($test,"gettasks")
    $test2 = GUICtrlCreateButton("Kill Tasks",120,20,100,100)
    GUICtrlSetOnEvent($test2,"")
    GUISetOnEvent($GUI_EVENT_CLOSE,"exit1")
    $in = GUICtrlCreateInput("",20,130,200,200)
    $in1 = GUICtrlCreateListView("",230,130,200,200)

Func gettasks()
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$strComputer = "localhost"
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   Local $Object_Flag = 0
   For $objItem In $colItems
      $Object_Flag = 1
      $Caption = $objItem.Caption
      MsgBox(1,"",$objItem.Caption)

  ;if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
   Next
  ;If $Object_Flag = 0 Then Msgbox(1,"WMI Output",$OutputTitle)
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Process" )
Endif

EndFunc

While 1
        $msg = GUIGetMsg()

        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd

Func exit1()
    Exit
EndFunc

Any help will be much appreciated...

Link to comment
Share on other sites

Hi,

try this:

#include <GUIConstantsEx.au3>
#include <array.au3>

;Opt("GUIOnEventMode", 1)
GUICreate("My GUI",600,600)
GUISetState(@SW_SHOW)
$test = GUICtrlCreateButton("List Tasks",20,20,100,100)
;GUICtrlSetOnEvent($test,"gettasks")
$test2 = GUICtrlCreateButton("Kill Tasks",120,20,100,100)
;GUICtrlSetOnEvent($test2,"")
;GUISetOnEvent($GUI_EVENT_CLOSE,"exit1")
$in = GUICtrlCreateInput("",20,130,200,200)
Global $in1 = GUICtrlCreateListView("Tasks                               ",230,130,200,200)

While 1
    $msg = GUIGetMsg()
        Select
            Case $msg = $GUI_EVENT_CLOSE
                Exit
            Case $msg = $test
                gettasks ()
            Case $msg = $test2
                exit1 ()
        EndSelect
WEnd

Func exit1()
    Exit
EndFunc

;use gettask ("Hostname") to get processes from other computer
Func gettasks($strComputer = "localhost")
    $count = 1
    Local $arTasks [1]
    $wbemFlagReturnImmediately = 0x10
    $wbemFlagForwardOnly = 0x20
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

    If IsObj($colItems) then
        Local $Object_Flag = 0
        For $objItem In $colItems
            $Object_Flag = 1
            ReDim $arTasks [$count]
            $arTasks [$count - 1] = $objItem.Caption
            $count += 1
            ;GUICtrlCreateListViewItem ($objitem.Caption, $in1)
            ;if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
        Next
        _ArraySort ($artasks)
        For $i = 0 To UBound ($artasks) - 1
            GUICtrlCreateListViewItem ($artasks [$i], $in1)
        Next
        ;If $Object_Flag = 0 Then Msgbox(1,"WMI Output",$OutputTitle)
    Else
        Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Process" )
    Endif
EndFunc

;-))

Stefan

Link to comment
Share on other sites

Thanks Stefan, i went with something similair in the end here is what i got, however now when i try to read the listview item and its text when selected it fails, any ideas??

#include <GUIConstantsEx.au3>
#Include <GuiListView.au3>

Opt("GUIOnEventMode", 1)
Global $in1

GUICreate("My GUI",220,700)
GUISetState(@SW_SHOW)
$list = GUICtrlCreateButton("List Tasks",10,10,100,30)
GUICtrlSetOnEvent($list,"gettasks")
$kill = GUICtrlCreateButton("Kill Tasks",110,10,100,30)
GUICtrlSetOnEvent($kill,"kill")
GUISetOnEvent($GUI_EVENT_CLOSE,"exit1")
$in1 = GUICtrlCreateListView("",10,45,200,600)
_GUICtrlListView_InsertColumn($in1, 0, "Tasks", 200)
GUICtrlSetFont($in1,10,"","","cambria")

Func kill()
    MsgBox(1,"",_GUICtrlListView_GetItemSelected($in1, 1),10)
EndFunc

Func gettasks()
$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$strComputer = "localhost"
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   Local $Object_Flag = 0
   For $objItem In $colItems
      $Object_Flag = 1
      $Caption = $objItem.Caption
      _GUICtrlListView_AddItem($in1, $objItem.caption)
   Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Process" )
Endif

EndFunc

While 1
        $msg = GUIGetMsg()

        If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd

Func exit1()
    Exit
EndFunc

I need to be able to read the text of the selected item as i will be passing that to a taskkill command for the remote machine. any ideas???

Thanks in advance....

Link to comment
Share on other sites

Hi,

you try to check, if item 1 is selected. Therefore you only get True or False (i guess mostly false :mellow: ) in your msgbox.

See helpfile function _GUICtrlListView_GetItemSelected ().

Try this:

Func kill()
    $arselect = _GUICtrlListView_GetSelectedIndices ($in1, "True")
    If $select [0] = "" Then 
        MsgBox (0,"Error", "No Selection")
    Else
        MsgBox(1,"",_GUICtrlListView_GetItemText($in1, $arselect [1]),5)
    EndIf
EndFunc

If you want to allow multi selection in your listview, you have to loop over array $arselect:

For $i = 1 To $arselect [0]
    MsgBox(1,"",_GUICtrlListView_GetItemText($in1, $arselect [$i]),5)
Next

in the else tree.

;-))

Stefan

Edited by 99ojo
Link to comment
Share on other sites

  • Moderators

With 99ojo's suggestions, the below works for me. Prompts the user for the asset number right off the bat. Only thing that I would add would be some sort of loop, so if the user clicks List Tasks again, they get prompted for a new asset:

#include <GUIConstantsEx.au3>
#include <GUIListView.au3>
#include <array.au3>

$strComputer = InputBox("Which asset", "Please enter asset tag")
GUICreate("My GUI",600,600)
GUISetState(@SW_SHOW)
$test = GUICtrlCreateButton("List Tasks",20,20,100,100)
$test2 = GUICtrlCreateButton("Kill Tasks",120,20,100,100)
$test3 = GUICtrlCreateButton("Exit",220,20,100,100)
$in = GUICtrlCreateInput("",20,130,200,200)
Global $in1 = GUICtrlCreateListView("Tasks                              ",230,130,200,200)

While 1
    $msg = GUIGetMsg()
        Select
            Case $msg = $GUI_EVENT_CLOSE
                Exit
            Case $msg = $test
                gettasks ()
            Case $msg = $test2
                exit1 ()
   Case $msg = $test3
    Exit
        EndSelect
WEnd

Func exit1($strComputer = $strComputer)
    $arselect = _GUICtrlListView_GetSelectedIndices ($in1, "True")
    If $arselect [0] = "" Then 
        MsgBox (0,"Error", "No Selection")
    Else
        $process = _GUICtrlListView_GetItemText($in1, $arselect [1])
  RunWait( "taskkill /s " & $strComputer & " /IM " & $process )
    EndIf
EndFunc

Func gettasks($strComputer = $strComputer)
    $count = 1
    Local $arTasks [1]
    $wbemFlagReturnImmediately = 0x10
    $wbemFlagForwardOnly = 0x20
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
                                        $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

    If IsObj($colItems) then
        Local $Object_Flag = 0
        For $objItem In $colItems
            $Object_Flag = 1
            ReDim $arTasks [$count]
            $arTasks [$count - 1] = $objItem.Caption
            $count += 1
        Next
        _ArraySort ($artasks)
        For $i = 0 To UBound ($artasks) - 1
            GUICtrlCreateListViewItem ($artasks [$i], $in1)
        Next
    Else
        Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Process" )
    Endif
EndFunc

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

  • 2 weeks later...

Thanks for all your help Guys :mellow:

Got it working, here is the finished product.

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

Opt("GUIOnEventMode", 1)
Global $in1

GUICreate("Remote Task Manager", 220, 720)
GUISetState(@SW_SHOW)
$assetfield = GUICtrlCreateInput("", 10, 10, 200, 20)
$list = GUICtrlCreateButton("List Tasks", 10, 40, 100, 30)
GUICtrlSetOnEvent($list, "gettasks")
$kill = GUICtrlCreateButton("End Task", 110, 40, 100, 30)
GUICtrlSetOnEvent($kill, "kill")
GUISetOnEvent($GUI_EVENT_CLOSE, "exit1")
$in1 = GUICtrlCreateListView("", 10, 75, 200, 600)
$col = _GUICtrlListView_InsertColumn($in1, 0, "Tasks", 200)
GUICtrlSetFont($in1, 10, "", "", "cambria")

Func kill()
    $arselect = _GUICtrlListView_GetSelectedIndices($in1, "True")
    If $arselect[0] = "" Then
        MsgBox(0, "Error", "No Selection")
    Else
        $process = _GUICtrlListView_GetItemText($in1, $arselect[1])
        RunWait("taskkill /s " & GUICtrlRead($assetfield) & " /IM " & $process)
    EndIf
    Sleep(1000)
    gettasks()
EndFunc   ;==>kill

$close = GUICtrlCreateButton("Close", 10, 680, 200, 30)
GUICtrlSetOnEvent($close, "exit1")

Func gettasks()
    If StringLen(GUICtrlRead($assetfield)) = 0 Then
        MsgBox(1, "Blank", "Asset Number Blank. Please provide the assett number")
    Else
        _GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($in1))
        $wbemFlagReturnImmediately = 0x10
        $wbemFlagForwardOnly = 0x20
        $strComputer = GUICtrlRead($assetfield)
        $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
        $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
                $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

        If IsObj($colItems) Then
            Local $Object_Flag = 0
            For $objItem In $colItems
                $Object_Flag = 1
                $Caption = $objItem.Caption
                _GUICtrlListView_AddItem($in1, $objItem.caption)
            Next
        Else
            MsgBox(0, "WMI Output", "No WMI Objects Found for class: " & "Win32_Process")
        EndIf
    EndIf
EndFunc   ;==>gettasks

While 1
    $msg = GUIGetMsg()

    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
Func exit1()
    Exit
EndFunc   ;==>exit1

Thanks Once Again.

Nav

Link to comment
Share on other sites

Hello there...eventually this could be of some interest:

Your version only works perfect if locally logged on user account is existing on the remote machine and has permissions there. Here an example how to check for a certain service on a remote machine using an other than the locally logged in user:

Global $h_wbemFlagReturnImmediately = 0x10
Global $h_wbemFlagForwardOnly = 0x20
Global $h_wbemFlags = $h_wbemFlagReturnImmediately + $h_wbemFlagForwardOnly

Global $a_Hosts[3] = ["HOST-1", "HOST-2", "HOST-3"]         ; change here to match your environment
Global $a_Processes[4] = ["process-1.exe", "process-2.exe", "process-3.exe", "regedit.exe"]
Global $s_AdminUser = "Administrator"                       ; change here to match your environment
Global $s_AdminPW = "password"                              ; change here to match your environment


For $i=0 To UBound($a_Hosts) -1
    $s_ProcessRunning = _CheckRemoteProcesses($a_Hosts[$i], $a_Processes, $s_AdminUser, $s_AdminPW)
Next


Func _CheckRemoteProcesses($s_Host, $a_Processes, $s_AdminUser, $s_AdminPW)

    Local $o_RemoteWMIService, $o_Process, $o_colProcesses
    Local $s_ProcessExists = "NO"
    Local $i_Result = 0, $s_ProcessRunning

    ; Create an object for the remote host's WMI interface and authenticate against it
    $o_SWbemLocator = ObjCreate("WbemScripting.SWbemLocator")
    If IsObj($o_SWbemLocator) Then
        $o_RemoteWMIService = $o_SWbemLocator.ConnectServer($s_Host, "root\CIMV2", $s_AdminUser, $s_AdminPW)
        If IsObj($o_RemoteWMIService) Then
            $o_colProcesses = $o_RemoteWMIService.ExecQuery("Select * from Win32_Process", "WQL", $h_wbemFlags)
            If IsObj($o_colProcesses) Then
                For $o_elements In $o_colProcesses
                    For $i=0 To UBound($a_Processes) -1
                        If $o_elements.Name == $a_Processes[$i] Then
                            ConsoleWrite(@CRLF & $s_Host & ": Process " & $a_Processes[$i] & " exists." & @CRLF)
                            $s_ProcessExists = "YES"
                        EndIf
                    Next
                Next
            EndIf
            If $s_ProcessExists = "NO" Then ConsoleWrite(@CRLF & $s_Host & ": No process found." & @CRLF)
            Return $s_ProcessExists
        Else
            ConsoleWrite(@CRLF & $s_Host & ": Probably wrong password or account disabled/inactive.")
            Return $s_ProcessExists = "Error"
        EndIf
    Else
        ConsoleWrite(@CRLF & ": Can't setup SWbemLocator object.")
        Return $s_ProcessExists = "Error"
    EndIf

EndFunc   ;==>_CheckRemoteProcesses

Best Regards,

Chris

Edited by cherdeg
Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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