Scripting Custom Messages to other objects?

Thursday, March 2, 2006 by brain21 | Discussion: DesktopX

I have an edit control window. I have a button. The button runs a script that say pings a machine in the network. It redirects the output of that command to a text file.

Now currently I have a 2nd button. When I click on that it sends a custom state (refreshresults) to the editbox (resultsbox)

So I click on one button to execute the script and pipe it to a file. Another button reads the file and displays it in the editbox.

What I want to do is have it so that when I click on the execute button IT reads the text file and sends the message to the edit box.

Now the obvious way to do this is what I have set up: On mouse down the script executes. On mouse up, or Command Executed it sends the message to the editbox.

This does not seem to work right, however.

Sometimes the script takes time to execute. So the "command Executed" event has ocurred. However, the script itself is still running, which means that it has not written to the file yet, so you dump nothing to the edit box.

I tried putting a Object.Sleep(5000) in the On_ScriptExit subroutine, but that seemns to do nothing really...

If I have several scripts they all write to the same results file.

So If I run ping 10.10.10.10 I get nothing dumped to the screen. I hit the refresh button and I then get the results in the editbox.

But lets say I didn't hit the refresh button. I execute the ping. Nothing in text/editbox.
Then I execute netstat -a
What happens is that when I click on the execute script button, it sends the message to the EditBox script to read in the text file. However, since netstat -a had not yet written to the text file, what gets dumped to the screen are the results from the PREVIOUSLY executed commands (ping in this case).


Refresh button works fine. I just want the execute button to wait a decent amount of time after it runs the script, and before it sends the resultsrefresh message to the resultsbox object. Again, putting a sleep in the exit routine doesn't do anything. Does the "Command Executed" state ocurr BEFORE the exit subroutine? That would explain my results.

The best solution here is for me to send the message in the script rather than via the properties. could I somehow do this ins the exit sub

Object.Sleep(5000)
DesktopX.ScriptObject("ResultsBox").State = "RefreshResults"

???

What is the right syntax? I get an error when I put in that code.

I also tried

DesktopX.ScriptObject("ResultsBox").StatePreempt = "RefreshResults"
That didn't seem to change anything. Again this is in the script for the Execute button, sending a message to the ResultsBox object.

Thanks,
Brain21

thomassen
Reply #1 Friday, March 3, 2006 4:06 AM
The state "RefreshResults" must allreayd exist before you try to use it.

And Are you using the Ping command in DesktopX? I thought that would suspend the rest of the script until it had finished. Or are you using an external app to ping it?
brain21
Reply #2 Friday, March 3, 2006 11:49 AM
I'm using the windows ping command
In the properties box I have only the state Mouse Away

When I click on the refresh button it sends the custom state/message "refreshresults" to the ResultsBox

Then in the script (for the results box) I have:

Sub Object_OnStateChange(State)
If State = "RefreshResults" Then
Dim ResultsBoxFileString
Dim ResultsFSO
Dim ResultsText

ResultsBoxFileString = "C:\autoqa\results.txt"
Set ResultsFSO = CreateObject("Scripting.FileSystemObject")
Set ResultsText = ResultsFSO.OpenTextFile(ResultsBoxFileString, 1, True)
Control.Text = ResultsText.ReadAll
Control.Text = Left(Control.Text, Len(Control.Text))
ResultsText.Close

Set ResultsBoxFileString = nothing
Set ResultsFSO = nothing
Set ResultsText = nothing

End If

End Sub

So, as far as I can tell RefreshResults does not already exist, and I reset it when I exit the script so it once again does not exist.

Thanks!

Brain21
brain21
Reply #3 Friday, March 3, 2006 11:58 AM
I'm thinking that the problem is not necessarily in the ResultsBox script, but rather the Execute button script that sends the state. If I could send the state via script rather than the properties dialog box, then I could sleep for a period of time before I send it. Otherwise, as soon as the script finishes the state is sent. I don't have an opportunity to actually wait for the file to get written to if necessary when I do it via the properties box.

Also, in the script above...
if the results.txt file is completely empty, the script throws an error. If I open the results.txt and put even a single space in it and save it, then the script does NOT throw an error.

I tried putting in

If Control.Text = "" Then
MsgBox "The results file is empty"
exit sub
End If

The problem here is that if I put this BEFORE Control.Text = Results.Text.ReadAll then you will get that popup message everysingle time. Since it has not yet read in the file, it is always = "" at this stage.

If I place it AFTER that line, well it's too late, and the code is basically useless, because if the file is 0 bits then the Control.Text = Results.Text.ReadAll line is the one that throws the error.

Is there anyway around this other than making sure that I actually create a results.txt file and put a single character or space in it whenever I amy package this app up and put it on another machine?

Thanks again,

Brain21
thomassen
Reply #4 Friday, March 3, 2006 12:11 PM
Have you tried making a function in the target script, for instance Public Sub refreshResults

Then in the pinging script call that function:


'Pinging code here
Sleep(2000)
DesktopX.ScriptObject("targetObject").refreshResult
thomassen
Reply #5 Friday, March 3, 2006 12:12 PM
Another thing. Do you use executre the windows ping?`useing the Shell scripting object?
I imagined that there is a way to call it so your script will halt the rest of the script until the application you called terminates.
brain21
Reply #6 Friday, March 3, 2006 4:47 PM
Looks like that might do it. Instead of sending a message in the pinging script, I call a soubroutine from the pinging script. So the flow is in the pinging script

perform ping
sleep
DesktopX.ScriptObject("ResultsBox").RefreshResults

THen in the other (resultsbox) object I create the subroutine

Sub ResultsRefresh

and do the screen refresh there rather than an OnStateChange subroutine which does it upon getting a message.

Correct?

I'll try it this weekend. Thanks.

As far as using WShell, I think the script runs the command line, and sends the message to the other object right away. I can't remember now... Before I dissect that, I'll just try your suggestion.

Thanks,

Brain21
thomassen
Reply #7 Friday, March 3, 2006 7:42 PM
I suppose you are using WshShell.Exec to start the ping?

If you use WshShell.Run http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/6f28899c-d653-4555-8a59-49640b0e32ea.asp you can set the last parameter to True in order to have your script pause the execution of the next statement until the app has finished. This is better as you don't have to guess how long it would take to perform the ping.
Note that the script and object will be blocked from doing anything else until it's done it's job. You probably want to make sure that script runs in a separeate thread. Look in the menues of the DX script editor to make it run in a thread of its own.
brain21
Reply #8 Monday, March 6, 2006 3:20 PM
I'm using WshShell.Run and have it set to True. That may keep the script from running, but it still sends the message (configured in the properties dialog) to the other object.

Have not played with it yet, haven't had time.

So I should be able to do as described above, but since I am using WshShell.Run & True, then I don't really need the sleep statement in there?

Brain21
thomassen
Reply #9 Monday, March 6, 2006 3:35 PM
correct. no need for Sleep then.
Call the other object's refresh function after the Run command. It's a better way of sending messages to objects as oppose to sending it through the States. I'd only use the States if I wanted the object's appearnce to reflect what's going on.

WshShell.Run('command', intWindowStyle, True)
DesktopX.ScriptObject("ResultsBox").RefreshResults
brain21
Reply #10 Thursday, March 9, 2006 1:14 PM
Works like a charm! Thanks...

Brain21
thomassen
Reply #11 Friday, March 10, 2006 3:47 AM

Please login to comment and/or vote for this skin.

Welcome Guest! Please take the time to register with us.
There are many great features available to you once you register, including:

  • Richer content, access to many features that are disabled for guests like commenting on the forums and downloading skins.
  • Access to a great community, with a massive database of many, many areas of interest.
  • Access to contests & subscription offers like exclusive emails.
  • It's simple, and FREE!



web-wc01