mshta and javascript

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
npocmaka_
Posts: 516
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: mshta and javascript

#16 Post by npocmaka_ » 17 Apr 2014 14:06

it's turned out that the mshta and internet explorer do not do a big difference between jscript and javascript and jscript directives are still valid even when they load a javascript for a web page.

So this allowed me to create an cmd script with UI:


Password submitter:

@if (@X)==(@Y) @end /*JScript comment
@echo off
mshta "about:<body onload='prepare()'><script language='javascript' src='file://%~dpnxf0'></script><input type='password' name='pass' size='15'></input><hr><button onclick='pipePass()'>Submit</button><body>" |findstr "^"
exit /b 0

**/

function prepare(){
//document.write("<input type='password' name='pass' size='15'></input><hr><button onclick='pipePass()'>Submit</button>");
}

function pipePass() {
//alert("blabla");
var pass=document.getElementById('pass').value;
var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
close(fso.Write(pass));

}



File selector:

Code: Select all

@if (@X)==(@Y) @end /*JScript comment
@echo off
mshta "about:<body onload='prepare()'><script language='javascript' src='file://%~dpnxf0'></script><input type='file' name='file' size='30'></input><hr><button onclick='pipeFile()'>Submit</button><body>" |findstr "^"
exit /b 0

**/

function prepare(){
   
}

function pipeFile() {

      var file=document.getElementById('file').value;
     var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
     close(fso.Write(file));

}


I still have a problem with dynamic changes of content to the page.It's added but calling functions from the added content causes troubles.

npocmaka_
Posts: 516
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: mshta and javascript

#17 Post by npocmaka_ » 18 Apr 2014 00:04

As adding html elements via command line call of MSHTA is limited I decided to add them dynamically from the script.But adding functions could cause a problem

Here's example with dynamically added buttons:


Code: Select all

@if (@X)==(@Y) @end/*JScript comment
@echo off
mshta "about:<title>chooser</title><body onload='prepare()'><script language='javascript' src='file://%~dpnxf0'></script><span id='container'>buttons:</span></body>" |findstr "^"
exit /b 0

**/

function clckd(a){
    // alert(a);
   var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
    ;
   close(fso.Write(a));
}

function prepare(){
   var element1 = document.createElement("input");
   element1.setAttribute("type", "button");
   element1.setAttribute("value", "yes");
   // this will not work on IE or MSHTA
   //element1.setAttribute("onclick", "clckd('yep');");
   element1.onclick= function() {clckd('yep');};
   
   var element2 = document.createElement("input");
   element2.setAttribute("type", "button");
   element2.setAttribute("value", "no");
   // this will not work on IE or MSHTA
   //element2.setAttribute("onclick", "clckd('nope');");
   element2.onclick= function() {clckd('nope');};


   var container = document.getElementById('container');
   container.appendChild(element1);
   container.appendChild(element2);

   //alert(document.getElementById('container').innerHTML);   
}

npocmaka_
Posts: 516
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: mshta and javascript

#18 Post by npocmaka_ » 20 Apr 2014 07:47

I'm continuing my games with self contained source files.Now I want to see how can I pass arguments to mshta - mainly to reduce mshta call line. The obvious way is to open stdin - ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0)

here's an .bat/gui file that creates radio button for each passed argument and at the end returns the number of the choosen button:

Code: Select all

@if (@X)==(@Y) @end /*JScript comment
@echo off

(
   echo %*
)|(
   mshta "about:<hta:application ShowInTaskbar=No Caption=no><title>radio</title><body onload='prepare()'><script language='javascript' src='file://%~dpnxf0'></script><span id='container'>All we hear is: <br></span></body>"
)|(
  for /f "tokens=* delims=" %%R in ('more') do (
    (echo(%%R)
   )
)

rem echo %result%
exit /b 0

**/

var argline;
var result;
var errmessage;
var elements = new Array();
var textnode;

function clckd(){
     // alert(a);
    var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);

   //fso.Write(line);
    //close(fso.Write(a));
   
   for (i = 0; i < elements.length; i++) {
      if (elements[i].checked ) {
         close(fso.Write(i+1));
         //alert(i+1);
      }
   }
   
}

function prepare(){
   
   try {
      var fso2= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0);
      argline=fso2.ReadLine();
      //alert(argline);
      //argline = "radio gaga radio gogo someone still loves you"
      var args=argline.split(" ");
   } catch (err) {
      errmessage = "cannot get the input";
      var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
      fso.Write(errmessage);
   }
   
   var br_element = document.createElement('br');;

   var i;
   var temp_element;   
    for (i = 0; i < args.length; i++) {
      temp_element =  document.createElement("input");
      temp_element.setAttribute("type", "radio");
      temp_element.setAttribute("name", "gaga");
      temp_element.setAttribute("value", i);
      temp_element.setAttribute("id", "gaga".concat(i));
      temp_element.value=args[i];
      elements.push(temp_element);   
   }
   
    for (i = 0; i < args.length; i++) {
      var br_element = document.createElement('br');;
      var container = document.getElementById('container');
      
       textnode=document.createTextNode("_"+args[i]+".");
       container.appendChild(elements[i]);   
       container.appendChild(textnode);
       container.appendChild(br_element);
    }
   container.appendChild(br_element);
    var submit = document.createElement("input");
   
    submit.setAttribute("type", "button");
    submit.setAttribute("value", "submit");
    submit.onclick= function() {clckd();};
    container.appendChild(submit);

    //alert(document.getElementById('container').innerHTML);   
}


the result (I still have one unwanted element):

Image


According to this post:

Code: Select all

http://blogs.technet.com/b/heyscriptingguy/archive/2005/04/20/how-can-i-pass-command-line-variables-to-an-hta-when-it-starts.aspx


the hta has HTA.ID.commandLine

and it works with javascript too (though it show the also the call of mshta also):

Code: Select all

@if (@X)==(@Y) @end /*JScript comment
@echo off


   mshta "about:<hta:application ID='objTestHTA' ShowInTaskbar=yes Caption=no><title>radio</title><body onload='Window_Onload()'><script language='javascript' src='file://%~dpnxf0'></script><span id='container'><br></span></body>" test arguments|more


rem echo %result%
exit /b 0

**/

function Window_Onload(){
   alert(objTestHTA.commandLine);
   var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1)
   
   for (i in objTestHTA) {
      fso.writeline(i);
   }
   fso.writeline("---parent element---");
   for (i in objTestHTA.parentElement) {
      fso.writeline(i);
   }
   
   fso.writeline("---body---");
   for (i in document.body) {
      fso.writeline(i);
   }
   alert(objTestHTA.parentElement.parentElement.ownerDocument)
   close();
}



The reason I print the document and hta object properties is to find Window_onLoad function but I think its not accessible through javascript (javascript is case sensitive while vbscript is not - I've tried few variants but may be I should test all of them .But in vbscript window_onload is defined as subroutine , but function.Javascript has only functions ...).

With vbscript it works perfectly.

Code: Select all

:sub echo(str) :end sub
echo off
'>nul 2>&1|| copy /Y %windir%\System32\doskey.exe '.exe >nul

'& echo/
'& echo %~nx0
'& echo asd |mshta "about:<html><head><title>Command Line Agruments</title><HTA:APPLICATION ID='objTestHTA' APPLICATIONNAME='Command Line Agruments' SINGLEINSTANCE='yes'></head><SCRIPT Language='VBScript' src='%~dpnxf0'></SCRIPT><body></body></html>"  asd dsa asd
'& exit /b


Sub Window_onLoad
   Msgbox objTestHTA.commandLine
   
    arrCommands = Split(objTestHTA.commandLine, chr(34))
    For i = 3 to (Ubound(arrCommands) - 1) Step 2
        Msgbox arrCommands(i)
    Next
   close
   document.wite(objTestHTA.commandLine)
   'Msgbox objTestHTA.version
End Sub

'http://blogs.technet.com/b/heyscriptingguy/archive/2005/04/20/how-can-i-pass-command-line-variables-to-an-hta-when-it-starts.aspx


some things that I've used

http: //scripting.cocolog-nifty.com/blog/2006/09/mshtaexeurl_40fe.html - a japanese guy that posted info how mshta can be called from command line

https: //groups.google.com/forum/#!msg/alt.msdos.batch.nt/b8q29_uLfQs/4uoVLRo1uOsJ - Tom Lavedas technique for bat/jscript files

http: //with-love-from-siberia.blogspot.com/2012/10/continuing-long-lines-in-batch-script.html - siberia-man

http: //ss64.org/viewtopic.php?pid=6195#p6195 here saw jeb to pipe to for /f

http: //blogs.technet.com/b/heyscriptingguy/archive/2005/04/20/how-can-i-pass-command-line-variables-to-an-hta-when-it-starts.aspx - technet about hta command line arguments.

http: //stackoverflow.com/a/16622325/388389 - how to create bat/vbs hybrid

Last edited by npocmaka_ on 20 Apr 2014 08:34, edited 1 time in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: mshta and javascript

#19 Post by foxidrive » 20 Apr 2014 08:04

It's great to see your work. :)

npocmaka_
Posts: 516
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: mshta and javascript

#20 Post by npocmaka_ » 20 Apr 2014 09:52

foxidrive wrote:It's great to see your work. :)


10x foxidrive. I have a few more ideas to test ,hope I'll have time.But I'm exited to have a way for UI applications with cmd with no temp files.

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: mshta and javascript

#21 Post by Squashman » 20 Apr 2014 10:17

npocmaka_ wrote:
foxidrive wrote:It's great to see your work. :)


10x foxidrive. I have a few more ideas to test ,hope I'll have time.But I'm exited to have a way for UI applications with cmd with no temp files.

That would be cool.

I played around with having User Interfaces with Poweshell a few years ago. But since my fellow co-workers didn't appreciate my hard work I gave up on doing any more scripting for them. My new job might get me back into it.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: mshta and javascript

#22 Post by foxidrive » 20 Apr 2014 10:34

Squashman wrote:My new job might get me back into it.


New job! That sounds promising. :thumbsup:

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: mshta and javascript

#23 Post by einstein1969 » 28 Feb 2016 09:36

Can anyone expert post scripts for get this functions with MSHTA/javascript and return into variable with FOR/F?

- Time (Low & High precision)
- Random
- PID

thanks

einstein1969

npocmaka_
Posts: 516
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: mshta and javascript

#24 Post by npocmaka_ » 28 Feb 2016 12:22

einstein1969 wrote:Can anyone expert post scripts for get this functions with MSHTA/javascript and return into variable with FOR/F?

- Time (Low & High precision)
- Random
- PID

thanks

einstein1969


Random is easy.May be aven a request to random.org is possible.But the only advantage I see compared to batchscript %random% is you can generate 64bit random integers.What exactly do you need?

Neither javascript nor the wmic classes can get the time to microseconds. Highest possible precision is up to milliseconds.May be w32tm could help here - http://stackoverflow.com/questions/1432 ... -with-this

I've tried to get the current PID of the cmd with the WSH and MSHTA but in both cases parent process leads to WscriptHost.exe.And the parent parent to the system processes.I'll try to dig deeper...

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: mshta and javascript

#25 Post by einstein1969 » 29 Feb 2016 06:16

ok. One thing at the time.

The problem with the batch-dos %RANDOM% is the precision on SEED. It renew the SEED every 1 second. Then There is problem of achieve same random number on concurrent CMD process.

You can may reference at http://stackoverflow.com/questions/19694021/random-generator-in-the-batch/19697361

The solution is also that of using an alternate generator as AAcini proposed.

Aacini wrote:@echo off

rem Generate random numbers via a Linear Feedback Shift Register(LFSR):
rem http://en.wikipedia.org/wiki/Linear_fee ... t_register

rem Fibonacci LFSR with taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1

if not defined lfsr for /f "tokens=3,4 delims=:." %%a in ("%time%") do set lfsr=3%%a%%b
set /A "bit = ( (lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1"
set /A "lfsr = (lfsr >> 1) | (bit << 15)"
echo %lfsr%
exit /B

But This is based on variable %TIME% with precision on centisecond (15,6... millisecond exactly)

Einstein1969

npocmaka_
Posts: 516
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: mshta and javascript

#26 Post by npocmaka_ » 02 Mar 2016 15:36

random (though I don't know if loosing a focus to the cmd for a moment is critical.If it is you'll need WSH and jscript. I also don't know if it will do the job for you and how precise it is) :


Code: Select all

@echo off

call :random

exit /b %errorlevel%

:random [var]
setlocal
set "rtrn=%~1"

:: Define simple macros to support JavaScript within batch
set "beginJS=mshta "javascript:code(close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write("
set "endJS=)));""



:: FOR /F does not need pipe
for /f "tokens=2* delims=." %%M in (
  '%beginJS% Math.random() %endJS%'
) do set random=%%N


endlocal && (
   if "%rtrn%" equ "" (
      echo %random%
      exit /b %errorlevel%
   ) else (
      set %rtrn%=%random%
      exit /b %errorlevel%
   )
)

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: mshta and javascript

#27 Post by einstein1969 » 04 Mar 2016 12:40

Thanks npocmaka_.

This work well. It is possible get the time with millisecond in the same manner?

In this mode it's possible to get "near" unique identifier RANDOM+TIME. (using mshta)

With this identifier it's possible to chatch the PID using the tecnique suggest by dbenham (Eliminating COLLISION) and merging with the method suggest by Squashman (Using TITLE).

Another possibility for fast random is using the first RANDOM by MSHTA how seed for the random method by Aacini wich is more fast.

Einstein1969

PS. This link is a doc that reference 100 nanoseconds time in wmi classes. Can we use this?
https://technet.microsoft.com/en-us/library/cc757283(WS.10).aspx
https://web.archive.org/web/20120427130816/http://msdn.microsoft.com/en-us/library/windows/desktop/aa394317(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/aa394323(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/aa394308(v=vs.85).aspx
Last edited by einstein1969 on 04 Mar 2016 16:36, edited 2 times in total.

einstein1969
Expert
Posts: 960
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: mshta and javascript

#28 Post by einstein1969 » 04 Mar 2016 16:23

Edit previus post!

npocmaka_
Posts: 516
Joined: 24 Jun 2013 17:10
Location: Bulgaria
Contact:

Re: mshta and javascript

#29 Post by npocmaka_ » 18 Apr 2020 03:16

Unfortunately GetObject("winmgmts:") does not work anymore from mshta and is detected as a thread :( . I'm almost sure some naughty boy has read this thread and use it to do some bad things .

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: mshta and javascript

#30 Post by penpen » 18 Apr 2020 07:20

I couldn't believe that and wrote the following "test.hta" and started that using the "test.bat" in the same directory:
It worked (at least on my win 10, ver 10.0.18362.778; last time updated: yesterday)!

"test.hta"

Code: Select all

<!DOCTYPE html>
<html lang="en">
<head>
	<title>A Simple HTA Application</title>
 	<HTA:APPLICATION
		APPLICATIONNAME = "CloseAllCalculators"
	/>
	<script>
	function closeAll(name) {
		try {
			var e = new Enumerator(GetObject("winmgmts:").execquery("select * from Win32_process where Name='" + name + "'"));
			for(e.moveFirst(); !e.atEnd(); e.moveNext()){
				e.item().Terminate();
			}
		}
		catch(error) {
			alert(error.message);
		}
	}
	</script>
</head>

<body>
	<button onclick="closeAll('Calculator.exe')">Close all instances of 'Calculator.exe'.</button>
</body>
 
</html>
"test.bat"

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion
for %%a in ("test.hta") do mshta.exe "%%~fa"
goto :eof
penpen

Edit: Corrected that i Initially copy-pasted only the first 1.5 lines of my batch.

Post Reply