mshta and javascript

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

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

mshta and javascript

#1 Post by npocmaka_ » 23 Jan 2014 16:16

if everybody else wondered if mshta could be used with javascript - it can:


Code: Select all

mshta javascript:eval("var objFSO=new ActiveXObject('Scripting.FileSystemObject'); var objFile = objFSO.CreateTextFile('jsetest',true); objFile.Write('blaah');objFile.Close();close();"); 


it's even a little bit more readable than vbscript because strings can be enclosed both of double and single quotes and the inner quotes of the other type do need to be escaped (don't know how to explain it better :) ). As it is javascript but no jscript there's no access to the WScript. But it's fun enough.

Initially tried with jscript:eval but on these places I saw that the javascript need to be used (just curious hacks):
http://vxheaven.org/forum/viewtopic.php?id=2338
http://jsunpack.jeek.org/dec/go?report= ... c5a7814d25


EDIT: How can I can delete my own thread/post here?
Last edited by npocmaka_ on 23 Jan 2014 16:39, edited 1 time in total.

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

Re: mshta and javascript

#2 Post by einstein1969 » 23 Jan 2014 16:38

i have this:

Code: Select all


rem mshta "javascript:close((V=(v=new ActiveXObject('SAPI.SpVoice')).GetVoices()).count&&v.Speak('Hello! I am '+V(0).GetAttribute('Gender')))"

rem mshta "about:<script>function b(){new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(d.ChooseColorDlg().toString(16));close();}</script><body onload='b()'><object id='d' classid='clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b'></object></body>"|more

rem mshta "javascript:res=screen.width+'x'+screen.height;alert(res);close();" 1 | more

rem for /f "usebackq tokens=1,* delims=[]" %i in (`mshta "javascript:close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(clipboardData.getData('Text')));"^|find /v /n ""`) do @set "c[%i]=%j"

rem mshta javascript:setTimeout('close()',10000)



einstein1969

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

Re: mshta and javascript

#3 Post by npocmaka_ » 23 Jan 2014 17:04

yes.There's no need to use eval...

On the third example - why is this "more" used?

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

Re: mshta and javascript

#4 Post by foxidrive » 23 Jan 2014 19:43

npocmaka_ wrote:EDIT: How can I can delete my own thread/post here?


Top right corner of your post is an edit button - you can edit your post.

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

Re: mshta and javascript

#5 Post by einstein1969 » 23 Jan 2014 20:29

npocmaka_ wrote:yes.There's no need to use eval...

On the third example - why is this "more" used?


with more wait for press ok before return prompt.

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

Re: mshta and javascript

#6 Post by npocmaka_ » 28 Jan 2014 06:51

get the free memory (in case of lacking WMIC):


Code: Select all

mshta "javascript:close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(GetObject('winmgmts:').ExecQuery('Select * from Win32_PerfFormattedData_PerfOS_Memory').ItemIndex(0).AvailableBytes));"|more


or assigned to variable (I've escaped everything suspicious ,but probably carets could be reduced):

Code: Select all

    for  /f "usebackq" %a in (`mshta ^"javascript^:close^(new ActiveXObject^(^'Scripting.FileSystemObject^'^).GetStandardStream^(1^).Write^(GetObject^(^'winmgmts:^'^).ExecQuery^(^'Select * from Win32_PerfFormattedData_PerfOS_Memory^'^).ItemIndex^(0^).AvailableBytes^)^);^"^|more`) do set free_mem=%a


EDIT: much more readable:

Code: Select all

mshta "javascript:close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(GetObject('winmgmts:').ExecQuery('Select * from Win32_PerfFormattedData_PerfOS_Memory').ItemIndex(0).AvailableMBytes));"|for /f %%a in ('more') do set free_mem=%%a

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: mshta and javascript

#7 Post by dbenham » 28 Jan 2014 11:08

I prefer to use FINDSTR "^" instead of MORE because it preserves the binary image, whereas MORE corrupts tabs. Also, MORE can freeze with large inputs.

Piping the result to MORE (or FINDSTR "^") is not needed if used within FOR /F :)

Since the beginning and end of the javascript code is constant, it is a good candidate for simple macros :) That makes it easier to incorporate javascript into batch using mshta.

Code: Select all

@echo off
setlocal

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

:: Direct instantiation requires that output is piped
%beginJS% GetObject('winmgmts:').ExecQuery('Select * from Win32_PerfFormattedData_PerfOS_Memory').ItemIndex(0).AvailableBytes %endJS% | findstr "^"

:: FOR /F does not need pipe
for /f %%N in (
  '%beginJS% GetObject('winmgmts:').ExecQuery('Select * from Win32_PerfFormattedData_PerfOS_Memory').ItemIndex(0).AvailableBytes %endJS%'
) do set free_mem=%%N
echo free_mem=%free_mem%
EDIT - I had forgotten to use the macros in the direct call. All fixed now.

Dave Benham
Last edited by dbenham on 28 Jan 2014 13:34, edited 2 times in total.

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

Re: mshta and javascript

#8 Post by npocmaka_ » 28 Jan 2014 11:57

Yes.That looks better.This pattern can be used as a substitute of command line arguments for the mshta line.

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

Re: mshta and javascript

#9 Post by npocmaka_ » 29 Jan 2014 05:37

Experiment with starting an invisible/hidden/background process:

Code: Select all

@echo off
setlocal
set "executable='notepad.exe'"
set "exedir='c:\\'"


@echo off
setlocal

set "beginJS=mshta "javascript:var w32ps= GetObject('winmgmts:').Get('Win32_ProcessStartup');w32ps.SpawnInstance_();w32ps.ShowWindow=0;var rtrnCode=GetObject('winmgmts:').Get('Win32_Process').Create(%executable%,%exedir%,w32ps,null);"


set "endJS=close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write('Return code:'+rtrnCode));""


for /f "delims=" %%N in (
  '%beginJS%%endJS%'
) do set "res=%%N"
echo %res%
endlocal


Here's the MS doc: http://msdn.microsoft.com/en-us/library ... 88(v=vs.85).aspx
(here's script that also can start a background process , but using EVENTCREATE,and the new switches of SCHTASKS - it works only from vista and above : http://ss64.org/viewtopic.php?pid=6022 )

It works but I must rewrite this in vbscript.Javascript has no passing an argument by reference (vbscript has) and I can get only the return code of the create process function ,but not the PID.Unless I find another way to get the PID , the vbscript will be better option here.

Btw.It's possible to create background process with 'WScript.Shell' activex object but Win32_Process allows more control ....

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

Re: mshta and javascript

#10 Post by npocmaka_ » 30 Jan 2014 18:03

Starting a hidden process with vbscript:

Code: Select all

@echo off
setlocal
   
   rem ::: check if help need to be called :::
   rem :
   
   for /f "usebackq tokens=1,2,3,4,5,6,7 delims= " %%A in ('-h -help /help /h "" /? -?') do (
      for %%# in (%%A %%B %%C %%D "%%~E" ) do if /i "%~1" equ "%%~#" goto :help
    
      if "%~1" equ "%%~F" goto :help
      if "%~1" equ "%%~G" goto :help
   )

   rem :
   rem :::  end help checks                 :::
   
   
   rem ::: arg parsing and checking         :::
   rem :
   set /A shifter=1
   set "workdir=."
   set "commandline= "
   set "exec="
   
   
   :arg_parser
   
   
   if "%~1" equ "-exec" set "exec=%~2"
   if "%~1" equ "-commandline" set "commandline=%~2"
   if "%~1" equ "-workdir" set "workdir=%~2"
   
   shift & shift
   set /A shifter=shifter + 1
   
   if %shifter% EQU 4 goto :end_arg_parser
   if "%~1" EQU "" goto :end_arg_parser
   goto :arg_parser
   
     
   :end_arg_parser
   rem :
   rem ::: end of arg parsing               :::
   
   rem ::: validate arguments               :::
   rem :
   
   set "exec_path="
   if not defined exec echo executable not defined && exit /b 1
   if exist "%exec%" for /f "usebackq" %%E in ("%exec%") do set "exec_path=%%~dpfsnxE"
   if not defined exec_path for %%E in ("%exec%") do set "exec_path=%%~dpfsnx$PATH:E"
   if not defined exec_path echo executable "%exec%" does not exist && exit /b 2
   for %%W in ("%workdir%") do set "workdir=%%~dpW"
   if not exist "%workdir%" echo target directory  "%workdir%" not exist && exit /b 3

   rem :
   rem ::: end of validation                :::
   
   rem ::: construct mshta command          :::
   rem :
   set "vbs_w32process=vbscript:execute("set w32ps=GetObject(""winmgmts:"").Get(""Win32_ProcessStartup"").SpawnInstance_():w32ps.ShowWindow=0:"
   set "vbs_stream_writer=CreateObject(""Scripting.FileSystemObject"").GetStandardStream(1).Write(""Rerurn code: ""&"
   set "vbs_start_process=GetObject(""winmgmts:"").Get(""Win32_Process"").Create(""%exec_path% %commandline%"",""%workdir%"",w32ps,pid)&vbCrLf&""PID: ""&pid)"
   set "vbs_end=:Close")"
   
   rem :
   rem ::: end construct mshta command      :::
   
   rem ::: call mshta                       :::
   rem :
   mshta %vbs_w32process%%vbs_stream_writer%%vbs_start_process%%vbs_end%| findstr "^"
   rem :
   rem ::: end  mshta call                   :::


endlocal
exit /b 0

:help
echo %~nx0 -exec executable [-commandline commandLine] [-workdir workdir]
exit /b 0



Passing by reference works like charm.I mean really like a charm - the variable is not even declared before passing to the function (the pid variable) and after then is accessible and has a value. :shock: I don't know which language is more annoying vbscript or javascript.

edit: commandline parameter should not contain quotes (though the surounding quotes are stripped and are not a problem)
Last edited by npocmaka_ on 16 Apr 2014 15:54, edited 1 time in total.

andrikaa
Posts: 1
Joined: 12 Feb 2014 23:45

Re: mshta and javascript

#11 Post by andrikaa » 26 Feb 2014 23:55

Where is the best place to find Java and Javascript tut's that are easy enough to follow so that i can start learning java and javascript as well as good websites that i can learn the language. thanks in advance.

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

Re: mshta and javascript

#12 Post by einstein1969 » 04 Mar 2014 17:34

Hi npocmaka_,

nice work on start process! :D I have think about this but i have not work with mshta and Wmi/winmgmts.

It is possible get the time with this method? I have read that the performance counters use time with high precision(millisec o microsec*/10).

Other mshta tricks:

Code: Select all

mshta "about:<img src='http://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/402px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg'>"

mshta "javascript:new ActiveXObject('WMPlayer.OCX').cdromCollection.Item(0).Eject();window.close();"


Einstein1969

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: mshta and javascript

#13 Post by Ed Dyreen » 04 Mar 2014 22:27

andrikaa wrote:Where is the best place to find Java and Javascript tut's that are easy enough to follow so that i can start learning java and javascript as well as good websites that i can learn the language. thanks in advance.
Java and JavaScript are 2 totally different beasts.

Unlike VB and VBScript, Java has nothing to do with javaScript they are 2 totally different beasts from different companies. In fact jScript from Microsoft comes closer to java from borland then javaScript. Java is a platform independent programming language which should not be used for client side programming unless security is of no concern. javaScript is a client side scripting language that runs inside your browser.

Try to figure out your requirements first. What am I going to create, which platform etc..
You will likely need multiple technologies to cover all aspects of the "system" you are creating.
Then select the language/s that best fit the requirements.

Learning programming models is more beneficial than learning the details of a programming language and can be as fun as programming.
The language is no more than a technical artifact.

If you want to learn javaScript because you want to create a cool website. I would advise the book Web Programming Step by Step.
This will teach you the basics of client and server side programming, using languages like PHP and javaScript. Here are javaScript tutorials from the World Wide Web Consortium, the main international standards organization for the World Wide Web. _http://www.w3schools.com/js/DEFAULT.asp

If you want to learn java because you want to create a game, I advise reading some books on Object Oriented programming and the site of Oracle ( the current owner of java ) http://docs.oracle.com/javase/ and a proper editor like eclipse.
You may be overwhelmed if you didn't read the proper books or get hooked.

Sponge Belly
Posts: 216
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: mshta and javascript

#14 Post by Sponge Belly » 05 Mar 2014 05:03

Hi Einstein1969! :-)

Is this what you were looking for?

Code: Select all

set ldt=For Each objItem in GetObject(""winMgmts:\\.\root\cimv2""^).^
ExecQuery(""Select LocalDateTime from Win32_OperatingSystem ^
where Primary=True""^):CreateObject(""Scripting.FileSystemObject""^).^
GetStandardStream(1^).Write objItem.LocalDateTime:Next:Close

for /f %%l in ('mshta vbscript:execute("%ldt%"^)') ^
do echo(WMI LocalDateTime: %%l


I like the CD-Eject snippet. Keep ’em coming!

- SB

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

Re: mshta and javascript

#15 Post by einstein1969 » 05 Mar 2014 19:10

Sponge Belly wrote:Hi Einstein1969! :-)

Is this what you were looking for?

Code: Select all

set ldt=For Each objItem in GetObject(""winMgmts:\\.\root\cimv2""^).^
ExecQuery(""Select LocalDateTime from Win32_OperatingSystem ^
where Primary=True""^):CreateObject(""Scripting.FileSystemObject""^).^
GetStandardStream(1^).Write objItem.LocalDateTime:Next:Close

for /f %%l in ('mshta vbscript:execute("%ldt%"^)') ^
do echo(WMI LocalDateTime: %%l


I like the CD-Eject snippet. Keep ’em coming!

- SB


Thanks SB,

I have tried the code but there is a problem with the precision.
I don't know where is the problem but i would like to try the "performance
counters" for compare the result. I expect an accuracy of 1 millisec or better.
I think that the counters are based on low kernel timer.

with localDateTime the precision on my machine is 15.625 milliseconds
according with this discovered.

Code: Select all

@echo off
cls
echo(
set ldt=set f=CreateObject(""Scripting.FileSystemObject""^).GetStandardStream(1^):^
set GO=GetObject(""winMgmts:\\.\root\cimv2""^):^
For C=1 to 10 : ^
For Each O in GO.ExecQuery(""Select LocalDateTime from Win32_OperatingSystem ^
where Primary=True""^):f.Writeline O.LocalDateTime:Next:^
Next:^
Close

for /f %%l in ('mshta vbscript:execute("%ldt%"^)') ^
do echo(WMI LocalDateTime: %%l


result:

Code: Select all


WMI LocalDateTime: 20140306015912.149000+060
WMI LocalDateTime: 20140306015912.211000+060
WMI LocalDateTime: 20140306015912.227000+060
WMI LocalDateTime: 20140306015912.227000+060
WMI LocalDateTime: 20140306015912.243000+060
WMI LocalDateTime: 20140306015912.258000+060
WMI LocalDateTime: 20140306015912.274000+060
WMI LocalDateTime: 20140306015912.274000+060
WMI LocalDateTime: 20140306015912.290000+060
WMI LocalDateTime: 20140306015912.305000+060


EDIT: ref. Acquiring high-resolution time stamps

einstein1969

Post Reply