Jump to content

How to invoke a JavaScript function from cmd[]?


Recommended Posts

While working on my AIO-DVD, I've found that some installs seem a little "temperamental". For example, WinRAR will sometimes leave a WinRAR folder in the Start -> Programs menu even though I've written a cmd to shift it. I've experimented with adding a "sleep" after the WinRAR install and that helps, so it looks like I just need to find a way of being sure that the install has completed.

I've decided to achieve this by watching until the WinRAR folder appears and then waiting a further 10s or so (while the install finishes up). Alternatively, I might just wait until the install process has vanished from the system (once I figure out which process it is ...). Either way, I don't want to wait forever, just in case something goes wrong: I'd much rather have an unattended install that finishes even though it might not have completely swept up after itself rather than have an install that hangs!

I can achieve this by cobbling together a js function, but I cannot find a way of invoking it from a cmdN[pn] statement.

So if I have a function called like this:

LimitedWaitForFile("C:\x.txt", 122)

how can I invoke it from cmd1[pn]?

Link to comment
Share on other sites


If you mean that "cmd1[pn]" is command console window ?..

John

No, I mean I have a function in api.js that looks like this:

function Test()
{
// does something cool
}

and an entry in config.js that reads like this:

prog[pn]=['Test']
uid[pn]=['TEST']
desc[pn]=['Test.']
ordr[pn]=[10]
cmd1[pn]=[' ... invoke Test() from here ...']
cat[pn]=['JS-Test']
pn++

So I want to use my home-grown function, Test(), in the cmd[] block. I can achieve the same thing (in this specific case) by doing some AutoIt tricks and throwing together a more complicated cmd[] line, but I'd prefer to do it all in Javascript (for maintainability).

Link to comment
Share on other sites

@deadbug,

There are two quick ways you can call another function from within WPI (without a lot of recoding effort).

1. You can take advantage of a function inside of core.js called "function ReplacePath(v)" that starts around line 323 (which is what I think you want). This will require you to define a new variable and replace text within the command with the data contained inside the variable. There are several examples contained within this function, an easy one to look at is the way Kel handles %wpipath% and replaces that token with the variable wpipath. wpipath actually gets resolved in this same file around line 15 under "function defaultWPI()".

2. Or you can make a call from an outside executable, script, or dll through a function inside of installer.js called "function handleCommand(cmd)" that starts around line 337. This is where you could substitute a command you've included in the cmd lines (I currently invoke an AutoIT Script from this function that contains many of my functions inside that I just pass commandlines like ProcessWaitClose, ProcessCloseAll, ProcessClose, ProcessWait, WinClose, WinKill...I've also added all the Delete, Copy, and Sleep functions as I don't like the CMD Window in my face during install - just a quirk on my part.

Probably the harder part is figuring out if you want to thump those commands everytime in the config page or remember to include them everytime there is a new release. You could also mod configwizardtemplate_config.htm to add those new commands in the dropdowns of each of the commands.

I'd also be interested in seeing your LimitedWaitForFile function if you're willing to post it.

Note: If the function line numbers don't match up properly, just do a search on those functions...I'm working on wpi6.2 but also make a few mods here and there so they may not exactly match up.

Link to comment
Share on other sites

@deadbug,

There are two quick ways you can call another function from within WPI (without a lot of recoding effort).

"Quick" and "no effort" - music to my ears :-)

Those places you pointed me at were exactly where I needed to look. Thanks.

I looked at adding a %JSCRIPT% piece of magic but it looks like anything between % characters _always_ gets replaced, either with magic or with the contents of an environment variable. What I want is for the code that normally invokes WshShell.Run() to call eval() instead.

So I opted for a slightly different approach. I assume that anything that starts with "JSCRIPT=" should be invoked as JavaScript.

In installer.js I added this:


if (cmdName=='regb' || cmdName=='rega')
{
// EXISTING STUFF HERE
}
else
cmdLine=handleCommand(cmdLine);

// <NEW STUFF>
// Treat an inital 'JSCRIPT=' as a request to evaluate a javascript expression
if (cmdLine.indexOf("JSCRIPT=")==0)
{
cmdLine.replace(/JSCRIPT=/gi, "");
try
{
ReturnCode=eval(cmdLine);
result=getText(InstallSuccess);
programs[item].success=true;
WriteLogLine('JSCRIPT Function SUCCEEDED: status='+ReturnCode+' {'+cmdLine+'}');
WriteRebootSuccess(item,true);
}
catch(ex)
{
result=getText(InstallFail);
programs[item].fail=true;
WriteLogLine('JSCRIPT Function FAILED: status='+ReturnCode+' {'+cmdLine+'}');
WriteRebootFail(item,true);
}
return
}

// </NEW STUFF>

// Here if not JSCRIPT
try
{
}

Probably the harder part is figuring out if you want to thump those commands everytime in the config page or remember to include them everytime there is a new release. You could also mod configwizardtemplate_config.htm to add those new commands in the dropdowns of each of the commands.

Well if it eventually scratches my itch, I'll probably hop over to the "new features request" thread and beg for someone to implement it properly :-)

For now I've modified installer.js to spot JavaScript functions and I've slapped my TimedWaitForFile() function in api.js.

If invoking arbitrary JavaScript functions makes it into the base product, then I guess it would be worthwhile having a userfunctions.js that WPI invokes but never tocuhes (and doesn't ship, so there's never any danger of altering the user's code). Shouldn't be more than one line of code somewhere to read it if it exists.

I'd also be interested in seeing your LimitedWaitForFile function if you're willing to post it.

Here it is, in all its ugliness:


function TimedWaitForFile(filename,timeout)
{
position="api.js";
whatfunc="TimedWaitForFile()";

count = 0
while (!FileExists(filename) && count < timeout)
{
count = count + 1
Pause(1,0)
}

if (FileExists(filename))
{
return 0
}

return 1
}

I've tested it thusly:


prog[pn]=['New Function Test 2']
uid[pn]=['TESTNEWFUNCTION 2']
desc[pn]=['Tests a new function']
ordr[pn]=[14]
cmd1[pn]=['JSCRIPT=TimedWaitForFile("C:\WPI_Log.txt",20)']
cmd2[pn]=['JSCRIPT=TimedWaitForFile("C:\WPI_LogX.txt",5)']
cond[pn]=[''];
dflt[pn]=['yes']
forc[pn]=['true']
cat[pn]=['Startup']
pn++

It seems to work in isolation; now it's time to go build a DVD!

Many thanks for the pointers.

Link to comment
Share on other sites

  • 6 months later...
  • 1 month later...

I just implemented this excellent idea. I have wanted something like this for a while.

In your commands, do things like this:

JSCRIPT=alert("Opens a window")

Use WPI's commands to write directly to registry without RegEdit

JSCRIPT=WriteRegKey("HKEY_CURRENT_USER\\Software\\WPI\\WPI_Rocks",1,"REG_DWORD")

New function

JSCRIPT=TimedWaitForFile("C:\Program Files\WinRAR.exe",10)

Waits 10 seconds while checking if the file exists. Will continue once file does exist or reaches timeout. Simple way to really wait before moving on to next command. Handy for installers that "exit" before really done.

This might be something to look at for Office installations...............??????

Link to comment
Share on other sites

I also just added

JSCRIPT=TimedWaitForDelete(delay,file,timeout)

This could be used to check if an installer temp file has been deleted. delay is number of seconds before start checking.

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...