Automate different event handling



  • I know, that this isn’t really a notepad++ related question but maybe someone has an idea how to solve it.

    Some background information first.

    We are using npp to create and upload, what we call, instruction files.
    Those files instruct different machine to do certain things. (not going into more technical detail as I think this is irrelevant to my case)
    In addition we are using the file monitor feature from npp, together with an UDL to monitor the responses/log messages from those machines.

    My wish would be to be able to act on different combinations of messages in a more automated way.

    For example:
    I do see that machine A reports that limit 5 has been reached and machine B reports waiting on step 6.
    In such a case I would need to do defined tasks, like creating instruction files and send it to machine A and B.

    Next time, machine A reports that limit 5 has been reached and machine B reports waiting on step 5.
    As you see machine A reported the same message but machine B is waiting on a different step which then would
    require to send a different instruction file

    What I want to have is to get the messages from machine A and B and create the needed instruction file automatically,
    therefore I have investigated python script and lua script plugin to see how this can be achieved but I’m struggling on
    getting triggered when new messages appear. I’m using the modified event from scintilla but this seems not to work always.
    Sometimes it can be used and it opens the new instruction file but next time it doesn’t do anything but I do see the updated
    log file at that time.

    As said, this isn’t really a npp question but hopefully one has a tip for me - just in case I have made a stupid error in the script
    here is my test.

    from Npp import notepad, editor, SCINTILLANOTIFICATION
    import time 
    
    def create_instruction_sets(p1,p2,p3,p4,p5,p6):
        notepad.open('d:\\BX_instructions.txt')
        editor.replace('%%p1%%', p1)
        editor.replace('%%p2%%', p2)
        editor.replace('%%p3%%', p3)
        editor.replace('%%p4%%', p4)
        editor.replace('%%p5%%', p5)
        editor.replace('%%p6%%', p6)
    
    def check_state():
        return True
    
    def on_modified(args):
        if check_state():
            print '%d creating new instruction files' % time.time()
            create_instruction_sets(1,2,3,4,5,6)
        else:
            print '%d requirements not fulfilled' % time.time()
    
    editor.callback(on_modified, [SCINTILLANOTIFICATION.MODIFIED])
    

    Eko





  • @Scott-Sumner

    :-) - ahhmmm - yes we do :-)

    Eko



  • @Eko-palypse

    It is known that the file monitoring feature of Notepad++ works not reliable. You could use a solution which depends not on Notepad++.

    It is possible to monitor a whole directory or even a dedicated file with a WMI notification query (see demo VBScript below). Script execution is paused when calling ExecNotificationQuery. The polling interval is the granularity (in seconds) with which the system should check the monitored directory/file for changes.

    When a change has been detected ExecNotificationQuery returns and provides a CIM_DataFile object with informations about the changed file. With its help you can start another script that parses the changed file and generates your instruction files.

    Please Note: You have to keep an eye on race conditions! If a machine log file gets changed while a previous change is still processed, there is the risk that the scripts processing both changes interfere each other and produce corrupted instruction files.

    This solution has its pitfalls too (but I guess these are common to all monitoring methods under Windows because they are all based on the same core functionality):

    • It may happen that it produces too much notifications, but it should be possible for you to check that and cancel processing in this case.
    • If the changes of the machine log files happen too frequent, monitoring may fail.
    • If the directory with the monitored file contains lots of files, monitoring may fail.

    It is also possible to write a purely event driven script solution using WMI permanent event consumers. This would overcome the time granularity limit of this solution but it is also more complicated.

    Option Explicit
    
    Dim objFSO, objShell, objWMIService, strComputer
    Dim strDrive, strPath, strFileName, strExtension, strPollingInterval
    Dim strQuery, colEvents, objEvent, objTargetInst
    
    strComputer         = "."         'Dot means local machine
    strDrive            = "E:"        'Drive letter **including** colon
    strPath             = "\\Test\\"  'Path with preceding and trailing **doubled** backslashes
    strFileName         = "Test"      'File name **without** path and extension
    strExtension        = "txt"       'File name extension **without** preceding dot
    strPollingInterval  = "0.5"       'Polling interval (in seconds), can be a floating point number
    
    Set objShell      = CreateObject("WScript.Shell")
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!" & _
                                  "\\" & strComputer & _
                                  "\root\cimv2")
    
    'File name and extension could be omitted
    strQuery  = "SELECT * FROM __InstanceModificationEvent" _
              & "  WITHIN " & strPollingInterval _
              & "  WHERE TargetInstance ISA 'CIM_DataFile'" _
              & "    AND TargetInstance.Drive='" & strDrive & "'" _
              & "    AND TargetInstance.Path='" & strPath & "'" _
              & "    AND TargetInstance.Filename='" & strFileName & "'" _
              & "    AND TargetInstance.Extension='" & strExtension & "'"
    
    Set colEvents = objWMIService.ExecNotificationQuery(strQuery)
    
    Do
      Set objEvent      = colEvents.NextEvent()
      Set objTargetInst = objEvent.TargetInstance
    
      'Environment variables get expanded and PATH variable is used to find the
      'provided executable, i.e. you could simply write "notepad.exe"
      objShell.Run "%SystemRoot%\System32\notepad.exe """ & objTargetInst.Name & """", 1, False
    Loop
    


  • @dinkumoil

    Thank you very much for the answer, very much appreciated.

    I have no problem with the file monitoring, on the contrary, the monitoring works
    and I see that log entries have been added - only the modified event,
    sometimes, doesn’t get triggered.
    Unfortunately, I have not yet figured out when exactly that happens.

    But you have solved the mental block, thank you - I do not have to wait for the modified event in Npp / Scintilla I can also monitor the file via PythonScript plugin and then the load the instruction file accordingly - exactly - yes - I will do that.

    Race conditions are unlikely as both machines do need a new set of instructions
    to go on working again.

    Thanks again :-)

    Eko



  • @dinkumoil said:

    It is known that the file monitoring feature of Notepad++ works not reliable.

    I agree with @dinkumoil about this.

    @Eko-palypse said:

    only the modified event, sometimes, doesn’t get triggered. Unfortunately, I have not yet figured out when exactly that happens.

    Maybe this is all tied in with our assessment of the file monitoring feature being unreliable.



  • @Scott-Sumner

    I read that this might happen but, I personally, never encountered such situation. Whatsoever, I guess I found out why sometimes it didn’t work.
    I used the .txt extension for my test file, which, when loaded, results in using
    the normal text language and it seems that this language doesn’t
    support those callback/functionality, at least this happens when I tested it.
    As soon as I assign my UDL everything works as expected but.

    Finished work :-)

    Eko



  • @Eko-palypse

    monitoring as normal text sometimes doesn’t work … using UDL everything works as expected

    nice find, good to know if it’s consistently working using a udl or perhaps even something that’s built in everywhere like the ms-ini language parser.



  • @Meta-Chuh

    actually using normal text never worked - the issue was that I didn’t realize that it was not set to my UDL, where it worked always. :-(

    Eko


Log in to reply