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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With