I think I understand what your problem is. You want to get jscript to open files like in vbscript. But the problem is that jscript (cscript) opens as a console application and shows you the console on startup, which you mistakenly think is a cmd window, at the same time wscript has no console and won't show you anything.
Create shortcuts. One shortcut for cscript over for wscript. Force the opening of files to be visible. Compare the difference in their behavior.
But don't assume that this is the solution to all problems. wscript has no ctd (ctdout) commands. Therefore, not all files you have will go through this trick. Try this on a simple file.
C:\Windows\System32\mshta.exe "javascript:new ActiveXObject('WScript.Shell').Run('cscript E:\\path\\name.js',1,false);close()"
C:\Windows\System32\mshta.exe "javascript:new ActiveXObject('WScript.Shell').Run('wscript E:\\path\\name.js',1,false);close()"
I would suggest a javascript file like this. Works the same way in both cases.
var htmlfile=new ActiveXObject('htmlfile').parentWindow;
var alert = function(s){htmlfile.alert(s)};
alert('Hello world!')
Well. You need to close the javascript console window itself.
Call javascript from shortcut hidden with parameters (from shortcut for example:
C:\Windows\System32\mshta.exe vbscript:Execute("CreateObject(""WScript.Shell"").Run ""cscript.exe """"С:\path\fname.js"""" """"par1 with whitespace"""" par2WithowtWhiteSpase"", 0:close")
...and don't forget to close the invisible process in the Task Manager after msta.
And even cmd won't show its window. It will output data to the jscript console, if of course jscript is open from cscript. Therefore, there can be no CMD window. The data will be output directly to the cscript console.
This is already directly about cmd and about getting data from his process:
chcp 1251,866 - change it to your regional parameters
var htmlfile=new ActiveXObject('htmlfile').parentWindow;
var alert=function(s){htmlfile.alert(s)};
var echoIt='Hi'
//...solve the problem of doubling percentages in variables during transmission by introducing the parameter /v!
var cmdCode=[
'for /F "tokens=1-6 delims=:., " %A In ("!date! !time!") Do (Echo %A.%B.%C %D:%E:%F)',
'set var='+echoIt,
'echo %var%',
'echo !var!',
'echo You will not see this output on the javascript screen >0',
];//'setlocal disableDelayedExpansion' parameter is useless becose /v
var std, arr=[];
var WshRunning=0,WshFinished=1,WshFailed=2;var i=0;tryCount=0,output=[],errors=[];
with (new ActiveXObject('WScript.Shell')) {
std=Exec("cmd /v /q /k echo off"); //Turning on the /v option last, switches the output here in its entirety, including C:\...\notepad>
std.StdIn.WriteLine("chcp 1251>nul");
for(var i=0;i<cmdCode.length;i++) {
std.StdIn.WriteLine(cmdCode[i]);
};
std.StdIn.WriteLine("chcp 866>nul");
std.StdIn.WriteLine("exit");
do{
if (std.Status==WshFailed){
errors.push('Error in string '+i+' :\n '+std.StdErr.ReadLine());
tryCount++
}
else if(std.Status==WshRunning){
output.push(std.StdOut.ReadLine());
tryCount=0;
WScript.Echo('Running ...')
}
else if(std.Status==WshFinished){
var last=std.StdOut.ReadLine();
if(last.length>0){output.push(last)};last=undefined;
tryCount=21;
WScript.Echo('Finished ...')
}i++;
}while(tryCount<21);
}
WScript.Echo('')
if (output.length>0){for(var i=0;i<output.length;i++) {WScript.Echo(output[i])}}
if (errors.length>0){alert(errors)}
var x=WScript.StdIn.ReadLine();
or
var std, arr = [];
var oWsh = new ActiveXObject("WScript.Shell");
with (new ActiveXObject('WScript.Shell')) {
std = Exec("cmd /q /k chcp 1251>nul");
with (std.StdIn){
WriteLine("dir "+ oWsh.SpecialFolders("Desktop"));
WriteLine("exit");
}
arr = std.StdOut.ReadAll().split('\n'); //чтение данных
}
for (var i = 0; i < arr.length; i++) {
WScript.echo(i+' '+arr[i]);
}
var x = WScript.StdIn.ReadLine();
For those who insist that a child thread from Exec shouldn't bring up a javascript window:
As it turns out, those who use vbs suffer from the lack of a black console! They want to receive data in the cscript process! And needless to say, they want to do it in a hidden vbs window.
Hide command prompt window when using Exec()
This is an example implementation of their code for jscript.
Further, complete nonsense. This only applies to jscript launched by wscript.exe. For jscript from native cscript, this is not needed.
It might make sense if jscript was run by default in the wscript process. But in jscript for this, in any case, we need a windows shortcut for this, which itself can hide the work of jscript without additional code.
Although, perhaps, the implementation of this code would be useful in creating multi-threaded applications.
================
You must do this in another thread that you have hidden.
It doesn't matter what kind of stream it will be, jscript, PS, Cmd.
The main thing is - wait for his response back using sleep or in some other way.
The easiest way to get the answer is to the clipboard.
Exec stops your thread and it only works on receiving a parameters. The code stops, and you can't do anything about it.
The ability to run hidden and get the result is in vbs. Omegastripes answer Hide command prompt window when using Exec().
But in fact, the work of that script is like chimera, but without restarting itself. New launch of its own code, at the same time hidden, in a new process in the space {C08AFD90-F2A1-11D1-8455-00A0C91F3880} as cscript, where already from a hidden stream produces exec. Then finding itself and directly injecting the variable back into its previows code. (objParent.strRes = CreateObject("WScript.Shell").Exec(....)
But it is hardly possible to do such variable simulation in javascript. I couldn't even find my own new cs thread object from 'this' thread, for example. Of course I will find it via wmic. But how do I insert (grab) a variable directly from the process?
My unproductive code:
Don't be surprised to see the result. This is just a child thread that should return a response and that should be hidden, but I made it visible.
var htmlfile=new ActiveXObject('htmlfile').parentWindow;
var alert = function(s){htmlfile.alert(s)};
function sleep(milliseconds) {
function now() {return new Date().getTime();};
var date = now(), currentDate = null;
do {currentDate = now();} while (currentDate - date < milliseconds);
}
function RunCScriptHidden() // restarts the script in an invisible, child thread (now it is visible and receives the result)
{
strSignature = (new ActiveXObject("Scriptlet.TypeLib")).GUID.substring(0,38);
GetObject('new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}').putProperty(strSignature,this);
//WScript.FullName.toLowerCase().replace("cscript", "wscript") //we can start it as wscript
//"c:\windows\system32\cscript.exe" //nologo "G:\filePath\fileName.js" "/signature:{7081DE1F-FB01-40A7-9384-B676516064EF}"
objShell.Run ('"'+WScript.FullName.toLowerCase() + '" //nologo "' + WScript.ScriptFullName + '" "/signature:' + strSignature + '"', 1);
}
function WshShellExecCmd(){ // This is already executed as a child streem pass in invisible mode and should pass the result to the mine thread
try{
for(var objWnd = new Enumerator(new ActiveXObject('Shell.Application').Windows());!objWnd.atEnd();objWnd.moveNext()){
//I couldn't even find the parent process here. It appears as a windows explorer process. And I can't even imagine the possibility of working with its objects in the js space.
if (typeof(objWnd.item(WScript.Arguments.Named('signature')))=='object'){break;}
}
var objParent = objWnd.item(WScript.Arguments.Named('signature')).parent; //big problem
objWnd.Terminate;
exec = (new ActiveXObject("WScript.Shell")).Exec(strCmd);//alert('')
while (exec.Status == WshRunning){sleep(100);};
var err = null;
if (exec.ExitCode == WshFinished){err = exec.StdErr.ReadAll()}
else{output = exec.StdOut.ReadAll().split('\n')}
if (err==null){WScript.Echo('output: '+output[output.length-2])
/*objParent.*/strRes = output[output.length-2]; //here should be objParent //I can easily do it with the clipboard, but it's ugly
}
else{
/*objParent.*/wowError = err; //there should be objParent (transfer data to the main thread and bang this child), of course you need to slow down the thread
//(there is a related example on vbs where this works) https://stackoverflow.com/questions/32297699
}
}catch(e){
var strErr = 'WshShellExecCmd error: ';
strErr += '\nNumber:' + e.number;
strErr += '\nDescription:' + e.description;
WScript.Echo('errors: '+strErr)
var x = WScript.StdIn.ReadLine();
}
}
try{
var WshRunning = 0,WshFinished = 1,WshFailed = 2,objWnd,objShell,strCmd,strRes,objParent,strSignature,wowError,output,exec;
var objShell = WScript.CreateObject("WScript.Shell");
wowError=false;
var psCode="Write-Host 'Hello PS'";
strCmd='C:\\Windows\\System32\\Cmd.exe /c for /f "usebackq delims=" %a in (`C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -command "' + psCode + '"`) do echo %a';
if (WScript.Arguments.Named.Exists('signature')){
WshShellExecCmd();
// The output of the results here is for example only. Here or above, we need to pass data to the parent thread.
if (wowError==false){
WScript.Echo("result: " + strRes)
}
else{
WScript.Echo("Get result error: " + wowError.ToString());
}
var x = WScript.StdIn.ReadLine();
}else{
RunCScriptHidden();
while (strRes == strRes){sleep(1000);WScript.Echo("I am waiting to receive 'strRes'")};//Here it is possible to release your parent process, and just continue the program in over process, instead of this
}
}catch(err){
var strErr = 'error:';
strErr += '\nNumber:' + err.number;
strErr += '\nDescription:' + err.description;
WScript.Echo('errors: '+strErr)
var x = WScript.StdIn.ReadLine();
}