Shoutbox

Restart script through code - Printable Version

-Shoutbox (https://shoutbox.menthix.net)
+-- Forum: MsgHelp Archive (/forumdisplay.php?fid=58)
+--- Forum: Messenger Plus! for Live Messenger (/forumdisplay.php?fid=4)
+---- Forum: Scripting (/forumdisplay.php?fid=39)
+----- Thread: Restart script through code (/showthread.php?tid=66558)

Restart script through code by Shondoit on 09-23-2006 at 08:43 AM

I'm trying to restart a script trough code...

I was thinking, because Plus restarts the script when it detects changes, I would change the script, through my own script
So I open the script, write a nullstring, and close it again...
Theoraticaly it should work, it also works when I open in notepad
But I can't seem to open the file, because it is "in use" or something

Can anyone help me?

I have this code so far:

code:
function Restart () {
   try {
      var File = fso.OpenTextFile(MsgPlus.ScriptFilesPath + "\\Main.js", 8, 0, -1)
      File.WriteLine("")
      File.Close()
   } catch (e) {
      //Couldn't restart...
   }       
}
And somewhere else in the script, I just want to read the contents, but it gives the same error:
code:
var File = fso.OpenTextFile(MsgPlus.ScriptFilesPath + "\\Main.js", 1, 0, -1)
var Lines = File.ReadAll().split(/\r\n?|\n\r?/)
File.Close()

fso is a declared FileSystemObject
RE: Reading scriptfile by Matti on 09-23-2006 at 08:53 AM

Quite easy to understand, since Plus! is using the contents of the script to run it, and you're trying to modify your script from the script itself. :-/


RE: Reading scriptfile by Shondoit on 09-23-2006 at 08:55 AM

That's what I thought at first, but I still can change it in notepad (said that in the first post too)
So it should be possible


RE: Reading scriptfile by Eljay on 09-23-2006 at 08:57 AM

Not to mention this wouldnt work at all in a script unless the user had debugging options enabled (which is disabled by default), as only then is the script actually reloaded when its changed.


RE: Reading scriptfile by phalanxii on 09-23-2006 at 09:02 AM

Couldn't you just clear all the variables (set them to default) then call OnEvent_Initialize?


RE: Reading scriptfile by Shondoit on 09-23-2006 at 09:02 AM

No it doesn't, I tried it and it works when I have debuggin disabled...

I also made a new script, which has only the restart bit when I type '/restart', and a toast when it restarts. This works...

code:
function OnEvent_Initialize (MessengerStart) {
   MsgPlus.DisplayToast("Test", "Script loaded")
}
function OnEvent_ChatWndSendMessage (ChatWnd, Message) {
   if (/^\/restart/i.test(Message)) {
      var fso = new ActiveXObject("Scripting.FileSystemObject")
      try {
         var File = fso.OpenTextFile(MsgPlus.ScriptFilesPath + "\\Update.js", 8, 0, -1)
         File.WriteLine("")
         File.Close();
      } catch (e) {
         MsgPlus.DisplayToast("Test", "File in use")
      }
      return ""
   }
}

RE: Reading scriptfile by Eljay on 09-23-2006 at 09:05 AM

quote:
Originally posted by Scripting Documentation > Getting Started > Scripting Environment
When debugging option are enabled, if a script file is modified by an external application, the script is automatically reloaded to apply the changes. This means that every time you save your script, you instantly see the changes without having to perform any extra manipulation. Note however that in order to avoid any possible kind of confusion, this functionality is disabled while the script editor window is displayed. Also, remember that this feature is only intended to be used by developers, this means that you cannot rely on it for public use of your script (so don't code a feature that expects code file changes to be intercepted by Messenger Plus!).

RE: Reading scriptfile by Shondoit on 09-23-2006 at 09:08 AM

@Phalanxii, no, I can't. I'm working on an autoupdate, it installs with a .plsc, but sometimes the script isn't reloaded, so I need to do it in my script


@Eljay, it seems that the debugging options weren't disabled (even though I ticked it off) It doesn't work now :S

Does anyone have an idea how to restart the script then?


changed the thread title
RE: Restart script through code by CookieRevised on 09-23-2006 at 05:24 PM

First of all a very important note in regards to script updating

You should not be using the method explained below (or any other method to restart a script for that matter) to clean up old deprecated files in a subsequent update of your scripts! Unpredicted things can happen, and it is also a more complicated and longer piece of code than needed for this purpose....

Instead you should simply stick the next snippet in the script file you want to remove so that it is the only thing it contains:
(but dont forget to change the filename in it of course)

js code:
var fso = new ActiveXObject("Scripting.FileSystemObject");
try {
    // Replace 'todelete.js' with the file name this snippet is in.
    // In other words, if you want to remove the file 'hello.js',
    // then replace 'todelete.js' with 'hello.js' and add this entire snippet in 'hello.js'
    fso.DeleteFile(MsgPlus.ScriptFilesPath + "\\todelete.js");
} catch(e) {}
And of course you could also add some more fso.DeleteFile() lines if you have more than one file to delete.

The result will be that Plus! will overwrite the old file with this 'new' file when installing. And when the code is run right after that, the file immediatly removes itself. The result is that you have effectively cleaned up the old deprecated file.

This method is far easier, cleaner, faster and safer than using any other method which involves a script restart or what not. It is ideal in case your main script files with all your events and routines have been renamed in your next script update.


----------------------------------


How to start a script using script code

Regarding the debugging options:

Scripts are reloaded when the debugging option is enabled (and a change detection is fired).

But! Even if you disable the debugging option in the Plus! preferences, a script will still be able to be reloaded if you didn't untick the "show debug window" option in the main contactlist menu!

When you first disable the debug window and then untick the debugging option in the preferences, you'll see that scripts will not be reloaded anymore.

Note that turning everything back on will not enable the reloading of scripts, you need to turn everything on and restart messenger for that.

(if this is done intentially or not, I dunno, but it does sound like a bug though).

Thus a change will be detected if debugging is ticked or if the debug window option is ticked.


Now to the actual problem/request:

First forget everything which is been said in this thread (no offense to the other posters though), the problem is the very limited FileSystemObject object from JScript and nothing else....

Files can be opened in various ways and on the same time they can be locked in various ways and shared in various ways.

As you know, in JScript you can open a file for reading, writing, or appending. But there are more states like that.

What JScript also doesn't let you do is setting how the file is locked or setting how the file is shared when it is opened.

You might expect that if you open a file for reading, it is locked for writing, and vice versa. This might seem logic, but it isn't; files can be opened for reading while they are not locked for writing, meaning another process can write to it on the same time you're reading it. Windows knows a whole lot of such combinations which are not exposed to JScript.

The same goes for the sharing flag of opened files.

To overcome all this you need to use the Windows APIs to open a file.

--

All this said, you do not need to write to a JScript file in order to let Plus! detect a change in the script. Plus! uses the ReadDirectoryChanges API to detect changes in a script's directory and the flag FILE_NOTIFY_CHANGE_LAST_WRITE is one of the flags used with this API by Plus!.

This means you only need to change the time when the file was changed and Plus! will detect it.

Benefit of this is that you don't need to alter a single byte to the file itself.

Also, the datetime value used for this is saved as 64 bits (aka a QWORD). That means that the value has even a smaller unit than milliseconds (though you will never see this in day-to-day Windows use), but it does add the possebility for us to alter this value with a change smaller than 1 millisecond which will in practice not change the actual visible and used datetime value in Windows at all.

Thus, you can force a change detection without altering anything to the file itself.


See the attached function to do this in a proper way:

You simply call the ReloadScript() function with the name of the script, that's all.
It will return true if a change detection is forced, and false if it was not possible (like when you already have the file open in a locked state in some editor, or when you don't have debugging on and the debug window isn't set to be shown).

So be aware that reloading scripts will not always be possible. In fact, in normal Plus! use (thus without the debugging options, like most people use it) you can not reload scripts at all. And thus this is not a reliable way for a script to update/reload itself, not only that, it should also not considered safe to use this method for something like that. Instead use the method described in the first topic on top of this post.

However, restarting a script can be somewhat usefull for script developpers themselfs though (eg: to be used in a developper script to create other scripts, etc). Either way, I very strongly advise not to use this in public available scripts!

eg:
js code:
ReloadScript("Background Changer");

updated to work with Plus! 4 and 5
previous downloads: 115
RE: Restart script through code by Matti on 09-23-2006 at 05:33 PM

And once again, the day was saved by CookieRevised! :D (hmm, reminds me on the Powerpuff Girls)


RE: Restart script through code by saralk on 09-23-2006 at 06:23 PM

Please note that restarting scripts is a feature suggested in the Scripting API Wishlist thread.


RE: Restart script through code by Shondoit on 09-23-2006 at 07:11 PM

Thanks Cookie, I managed to get my piece of code working, but this is a better solution (y)
I said fso was a declared FileSystemObject... well, it wasn't :$
I tried that function in a test script, and it worked. So I copied it to my main script, but forgot the declaration
Also I didn't wrote 'something' to the file, I added a nullstring to the end... So it would open and close as if it were changed, and thus restart... anyway, yours is better

@Saralk, I believe it was a suggestion of me... Because there is no clean way of restarting it