DataAvailable event never gets fired

Trying to make a live log viewer on Windows.

There is a log file and my shell runs windows commands such as ‘type log_file’ or ‘tail -f log_file’. ( with windows tail binary ).
So, I want to see the latest log entries in GUI automatically. The new entries are displayed in a textarea.

– calling method

  dim getLogDataShell_Run As New getLogDataShell
  finalCommand =  " cd " + DirectoryName + " & " + "type  " + FileName
  
  getLogDataShell_Run.Execute finalCommand

  If getLogDataShell_Run.ErrorCode <> 0 Then
    Msgbox "getLogDataShell_Run Error: " + Str(getLogDataShell_Run.ErrorCode)
  Else
    Logging("Check: getLogDataShell_Run executed : " + FileName )
  End If

– DataAvailable event

  Dim ResultBuffer As String
  ResultBuffer = Me.ReadAll
  
  Logging("DEBUG: getLogDataShell / DataAvailable event")
  
  MainWindow.MainContainerScreen.JOBMonitorList_area.AppendText ResultBuffer
  
  Logging("DEBUG: ResultBuffer(getLogDataShell): " + ResultBuffer)
  

It seems that the shell command is executed, but DataAvailable event never got fired.

Can you let me know which point I am missing?

Do you check the errorcode after issuing the execute?
Can you not just use the shell result?

There is a error check code above. I edited.
It says the shell runs fine.

What mode is that shell set to? DataAvailable doesn’t fire when mode = 0.

Yes, I know.
I just use a Async mode as following.

  Self.Mode = 1 // ASync
  Self.TimeOut = -1

Oh wait… that top method runs to completion and the shell object goes out of scope. Try defining it as a Module or Class property.

I might not understand. Can you tell me about it in more detail? Thanks.

Ah…

mgetLogDataShell module ( getLogDataShell type )

 dim getLogDataShell_Run As New getLogDataShell
  finalCommand =  " cd " + DirectoryName + " & " + "type  " + FileName
  
  mgetLogDataShell.Append(getLogDataShell_Run)
  getLogDataShell_Run.Execute finalCommand

It works now!!!

Thanks for your help. Nice.

Sure. In your method, you do this…

dim getLogDataShell_Run As New getLogDataShell

That means that when the method runs to completion, as a locally defined property, it gets destroyed.

What I’m suggesting is that you create a property on whatever contains this method, whether it’s a Window or a class or a Module.

name: getLogDataShell_Run Type: getLogDataShell

Then in your code, change that line to:

getLogDataShell_Run = New getLogDataShell

Doing so will use the new property which will only be destroyed when its container is destroyed.

Sorry. One more question.
It is not related to a Head sentence though.

With below command, I just get a log result once.

finalCommand =  " cd " + DirectoryName + " & " + "type  " + FileName

I need to display a new data whenever the log file is updated.
Do you have any idea?

yup. I think that ampersand is in the wrong place. Try putting it at the end of the line.

Looks fine to me - the way of running two commands on one line ( cd and type ).

To the OP - maybe store the modification date, or the size, of the file and then run a timer checking if either has changed ( via folderitem ).

EDIT. Be sure the program you are running and the log file are on the same drive ( eg. C ) else that cd probably won’t work.

Yes, & is fine as OS is Windows.

Trying to use ‘tail.exe’ command with -f option because I thought my shell could be updated with a real data.

finalCommand = " cd " + DirectoryName + " & " + "start """"/B " + InstallDirectory + UTIL_Directory + "tail -f " + FileName

It seems that Xojo shell works but DataAvailable event doesn’t get fired.
Because shell doesn’t get any data from the output of ‘tail -f’?

[quote=368621:@changwon lee]

It seems that Xojo shell works but DataAvailable event doesn’t get fired.[/quote]

Can you not use a mode 0 shell and just check the .result?

With a normal shell structure, I don’t find any data in .Result.

  dim getLogDataShell_Run As New Shell

  finalCommand =  " cd " + DirectoryName + " & " +  "start """"/B " + InstallDirectory + UTIL_Directory + "tail -f  " + FileName
  
  getLogDataShell_Run.Execute finalCommand  
  MainWindow.MainContainerScreen.JOBMonitorList_area.AppendText getLogDataShell_Run.Result

“‘tail’ is not recognized as an internal or external command,
operable program or batch file.”

This works:

[code]
Dim x as string
Dim i as integer
Dim s as shell

x=“cd c:\temp\ & type License.txt”
s=New Shell

s.Execute x

i=s.ErrorCode
If i <> 0 then msgbox str(i)
TextArea1.text=s.result[/code]

I suggest typing the command you are trying to run, in full, in notepad, then copy and paste into a command processor ( cmd ) to see if you have your systax correct. OR get your program to put it on the clipboard and try it manually in a command processor.

If your ‘tail’ command is an executable you would need to specify its whole path, checking there is a trailing “” before adding the “tail -f” bit.

I really suggest getting the program to put your constructed command on the clipbaord and checking it in a command processor.

‘tail.exe’ is not a native command in Windows. Downloaded in other site.
As you can see in the below, the shell command works fine, but thing is that I don’t see any data in .Result.
When I use ‘type’ command, I can.

C:\\Program Files (x86)\\MYAPP>start "" /B "C:\\Program Files (x86)\\MYAPP\\Utilities\\tail" -f  MYAPP.log

C:\\Program Files (x86)\\MYAPP>DFSA
DFAS
DFSAD
FS
ADF
SADF
SADFFSA
DFSDF
SADFASDF

With just ‘tail -100’ option, I see the result. However, I need to get a real data whenever the log file is updated.
That’s why I use ‘-f’ option.

I found a tail command. If you use “-f” on this one it still waits and does not close. Maybe that is the one you have. Try without the -f bit. What error does the shell return. This works. Why do you use “start”?

[code] Dim x as string
Dim i as integer
Dim s as shell

x=“f:\tail\tail.exe c:\temp\License.txt”
s=New Shell

s.Execute x

i=s.ErrorCode
If i <> 0 then msgbox str(i)
TextArea1.text=s.result[/code]

As for ‘start’ command, I tried to run the shell command as a background. It doesn’t matter here I guess.

Yes, ‘tail’ or ‘tail -100’ command would work. But, I need to incorporate into a Timer to get the latest data of a log file.
I wanted to do that with ‘-f’ option without Timer.

I believe as a workaround I can just use ‘tail’ and Timer.
Still wondering why Shell doesn’t get data with ‘-f’ option.