5

I'm creating this HTA app with JScript that writes a BAT file and opens it in cmd afterwards.

If I manually open the created BAT file from windows it works like it should.
When I open it through my HTA, the file opens but only outputs Echo and pause.

Please keep in mind, I'm very very new at programming.

Here is the JScript.

// Write the Bat file
// When run from HTA all I get is the "Echo Done" and "Pause"
// When I run from Windows without HTA, all of it works.
function writeBat() {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.CreateTextFile("C:/test/test.bat");
    s.WriteLine('@echo off');
    s.WriteLine('set output=C:/test/new/');
    s.WriteLine('FOR %%a in (*.mkv) DO ("C:/Program Files/MKVToolNix/mkvmerge.exe" -o "%output%%%~na.mkv" "%%a")');
    s.WriteLine('echo Done.');
    s.WriteLine('pause');
    s.Close(); }

// Run the Bat file.
function runBat() {
var MyObject = new ActiveXObject("wscript.shell");
MyObject.Run("C:/test/test.bat"); }

Here is the Batch file.

@echo off
set output=C:/test/new/
FOR %%a in (*.mkv) DO ( "C:/Program Files/MKVToolNix/mkvmerge.exe" -o "%output%%%~na.mkv" "%%a")
echo Done.
pause

And the HTML

<form>
<input type="button" value="Write Bat" onClick="writeBat()">
<input type="button" value="Run Bat" onClick="runBat()">
</form>
user692942
  • 16,398
  • 7
  • 76
  • 175
Jon
  • 85
  • 7
  • 1
    add one `echo %cd%` in the batch file to check the running directory and if needed add additional `pushd c:\directory` line. – npocmaka Feb 24 '16 at 11:22
  • JavaScript and JScript while the syntax is similar are [not equivalent](http://stackoverflow.com/a/135256/692942). What you have written here is JScript. – user692942 Feb 24 '16 at 11:51
  • 1
    As I said in the post, I'm very new at this. Thanks for clearing up the Jscript thing. As for the answer, `%cd%` show the path to desktop so I added `s.WriteLine('pushd "%~dp0"');` at the top and it works!! Thank you so much! – Jon Feb 24 '16 at 13:48

1 Answers1

4

Well, you found your answer. The context of the HTA is in a different working directory from the context of the batch script. You have to have the batch script cd or pushd to "%~dp0". This is pretty standard for batch scripts added to context menus and so forth.

s.WriteLine('pushd "%~dp0"');

... as you have already done is the correct solution. You should also

s.WriteLine('@echo off & setlocal');

... to limit the scope of the variables in this batch script to the runtime of the batch script itself.


But the main reason I'm posting an answer is for the purpose of providing more information on the Chakra engine. Even with IE9, 10, 11, Edge, whatever installed, the Windows Script Host maintains the feature set as it existed in JScript 5.7. According to MSDN documentation:

Starting with JScript 5.8, by default, the JScript scripting engine supports the language feature set as it existed in version 5.7. This is to maintain compatibility with the earlier versions of the engine. To use the complete language feature set of version 5.8, the Windows Script interface host has to invoke IActiveScriptProperty::SetProperty.

What that is saying is, if you want to use methods in JScript 5.8 or newer (such as JSON methods, Object.keys, Array.prototype.forEach(), and so on), you basically have to write your own Windows Script Host interpreter. But, with HTA, there's an easy hack that will enable IE9 features. Simply add the following line to the top of your HTA file:

<meta http-equiv="x-ua-compatible" content="IE=9" />

Before:

<script>
function get() {
    try {
        var json = JSON.parse(document.getElementById('json').value);
        alert(json.var1);
    }
    catch(e) {
        alert(e.message);
    }
}
</script>
<textarea id="json">{"var1": "It works!"}</textarea>
<button onclick="get()">Go!</button>

Output:

'JSON' is undefined

After:

<meta http-equiv="x-ua-compatible" content="IE=9" />
<script>
function get() {
    try {
        var json = JSON.parse(document.getElementById('json').value);
        alert(json.var1);
    }
    catch(e) {
        alert(e.message);
    }
}
</script>
<textarea id="json">{"var1": "It works!"}</textarea>
<button onclick="get()">Go!</button>

Output:

It works!


This hack isn't limited to HTA, though. It can also be made to work for console JScript and JScript.NET by creating an htmlfile COM object, writing the <meta> tag to it, then copying the newly exposed methods and objects into the current script host.

Community
  • 1
  • 1
rojo
  • 24,000
  • 5
  • 55
  • 101
  • Thanks you for your input! I was reading somwhere that I should'nt do it with unless I had to. Seems I can skip it for this project, can get handy for next one. Thanks for taking your time. – Jon Mar 02 '16 at 10:43