Jump to content

Problem with OnEvent mode combined with Objects.


Recommended Posts

When I have a script that uses an object, and the object is busy with something, Events do not call functions anymore.

When I use the File Monitoring script (found on this forum), hotkeyset("{esc}","closescript") does not work:

Hotkeyset("{esc}","closescript")

$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
$colMonitoredEvents = $objWMIService.ExecNotificationQuery _
    ("SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE " _
    & "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
    & "TargetInstance.GroupComponent= " _
    & "'Win32_Directory.Name=""c:\\\\1""'")

While 1
    $objEventObject = $colMonitoredEvents.NextEvent()
    
    Switch $objEventObject.Path_.Class()
        Case "__InstanceCreationEvent"
            ConsoleWrite ("A new file was just created: " & $objEventObject.TargetInstance.PartComponent() & @CR)
        Case "__InstanceDeletionEvent"
            ConsoleWrite ("A file was just deleted: " & $objEventObject.TargetInstance.PartComponent() & @CR)
        Case "__InstanceModificationnEvent"
            ConsoleWrite ("A file was just modified: " & $objEventObject.TargetInstance.PartComponent() & @CR)
    EndSwitch  
WEnd

closescript()
       Exit
EndFunc

Also, when I embed an IE window in a GUI, the close button does not function anymore (probably the same event vs. object kind of problem).

Is there a way to let the event - functions happen when the object is doing something??

Sorry for my confusing explanation, not so good english and I am kinda tired. Any help is greatly appreciated.

Edited by okdewit
Link to comment
Share on other sites

$colMonitoredEvents.NextEvent() is a blocking function call. Meaning that when it is called your script pauses until there is a return value. The events are occurring, they are just having to wait until another NextEvent occurs before they are handled/executed.

Link to comment
Share on other sites

So there is no way to rewrite this script so it checks events?

I can imagine a construction where I have a script with my program/gui/event handling, and a second script handling the detection of file changes, which passes data to the first script.

I think I'll go for that, if anyone has a better idea I would love to hear it :)

Thanks a lot for your explanation, I tried a few things and its clearer to me how this works :(

Edited by okdewit
Link to comment
Share on other sites

Well if you read the entire post where you obtained your original script, you will notice that they talk about asynchronous queries. Asynchronous queries will not block because they allow you to create your own callbacks (SINKs) for your queries. So here's a script that arcker wrote that I modified to meet your needs:

#include<array.au3>
#include<date.au3>
#include<guiconstants.au3>
Dim $arrComputers, $strQuery, $SINK, $objContext, $objWMIService, $objAsyncContextItem, $return, $account
Global $bExit = False
$arrComputers = _ArrayCreate(".")

HotKeySet("{esc}", "closescript")
Sink_Start($sink)
_find_folders("C:\1")

func _find_folders($path)
    $monitordrive  = stringleft($path,2)
    $monitorpath = StringReplace(stringtrimleft($path,2),"\","\\") & "\\"
    SINK_Add($monitordrive,$monitorpath,$sink)
    ConsoleWrite($path & @crlf)
    local $first=FileFindFirstFile($path & "\*.*")
    while 1
        $fichier = FileFindNextFile($first)
        if @error then ExitLoop
        if stringinstr(FileGetAttrib($path & "\" & $fichier),"D") then _find_folders($path & "\" & $fichier)
    WEnd       
EndFunc 

While Not $bExit
    Sleep(250)
WEnd

Func closescript ()
    $bExit = True
EndFunc

;******************************************************************************
func Sink_Start(byref $Sink)
    $SINK = ObjCreate("WbemScripting.SWbemSink")
    ObjEvent($SINK, "SINK_")
EndFunc

func SINK_Add($wmidrive,$wmipath,$sinkref)
    $objContext = ObjCreate("WbemScripting.SWbemNamedValueSet")
    $strQuery = "SELECT * FROM __InstanceOperationEvent WITHIN 20 WHERE TargetInstance ISA 'CIM_DataFile' and TargetInstance.Path = '" & $wmipath & "' and TargetInstance.drive = '" & $wmidrive & "'"
    $objWMIService = ObjGet("winmgmts:!\\.\root\cimv2")
    $objWMIService.ExecNotificationQueryAsync ($sinkref,$strQuery, Default, Default, Default, $objContext)
EndFunc

Func SINK_OnObjectReady ($objLatestEvent, $objAsyncContext)    ;Trap asynchronous events.
    Switch $objLatestEvent.Path_.Class()
        Case "__InstanceCreationEvent"
            ConsoleWrite ("A new file was just created: " & $objLatestEvent.TargetInstance.Properties_.item("Name").value & @CR)
        Case "__InstanceDeletionEvent"
            ConsoleWrite ("A file was just deleted: " & $objLatestEvent.TargetInstance.Properties_.item("Name").value & @CR)
        Case "__InstanceModificationnEvent"
            ConsoleWrite ("A file was just modified: " & $objLatestEvent.TargetInstance.Properties_.item("Name").value & @CR)
    EndSwitch  
;~     $filename= $objLatestEvent.TargetInstance.Properties_.item("Name").value
;~     ConsoleWrite($filename & @CRLF)
EndFunc   ;==>SINK_OnObjectReady

Func sink_onprogress ($iUpperBound, $iCurrent, $strMessage, $objWbemAsyncContext)
    ConsoleWrite("progress ... " & @CRLF)
    ConsoleWrite($iUpperBound & @CRLF & $iCurrent & @CRLF & $strMessage & @CRLF & $objWbemAsyncContext & @CRLF)
EndFunc   ;==>sink_onprogress

P.S. - In the future it is polite to give credit for code you didn't write. In this case, ptrex wrote the code in your first post.

Link to comment
Share on other sites

You can use a timeOut and Use the COM error, if it was successful:)

Hotkeyset("{esc}","closescript")
$oMyError = ObjEvent("AutoIt.Error","_COMError")
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
$colMonitoredEvents = $objWMIService.ExecNotificationQuery _
    ("SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE " _
    & "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
    & "TargetInstance.GroupComponent= " _
    & "'Win32_Directory.Name=""c:\\\\1""'")

While 1
    $objEventObject = $colMonitoredEvents.NextEvent(100)
    If Not @error Then
    Switch $objEventObject.Path_.Class()
        Case "__InstanceCreationEvent"
            ConsoleWrite ("A new file was just created: " & $objEventObject.TargetInstance.PartComponent() & @CR)
        Case "__InstanceDeletionEvent"
            ConsoleWrite ("A file was just deleted: " & $objEventObject.TargetInstance.PartComponent() & @CR)
        Case "__InstanceModificationnEvent"
            ConsoleWrite ("A file was just modified: " & $objEventObject.TargetInstance.PartComponent() & @CR)
    EndSwitch  
    EndIf
WEnd

Func closescript()
       Exit
EndFunc
   
Func _COMError()       
    Local $err = $oMyError.number
    If $err = 0 Then $err = -1
;~     Debug("Com Error", "Description: " & $oMyError.description, "ErrNumber: " & $oMyError.number)
;~ ConsoleWrite("COM Error: " & $err & @CRLF)
    SetError($err)  ; to check for after this function returns
EndFunc

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

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...