Создать скрытый cmd javascript

Я ищу способ запустить команду cmd, не показывая пользователю окно cmd.

Я использую что-то вроде:

    
    function reboot()  {
          var ws = new ActiveXObject("WScript.Shell");
          ws.Exec("shutdown.exe -r -t 120");

    }
    

Но он все равно показывает окно, все равно его не показывать?

Спасибо


person Sandeep Bansal    schedule 17.01.2010    source источник
comment
Итак, вы хотите выключить компьютер пользователя без его ведома, какая замечательная идея!   -  person Zifre    schedule 18.01.2010
comment
Вот почему у нас не может быть хороших вещей... или большой песочницы JavaScript.   -  person Ryan Joy    schedule 18.01.2010
comment
Я надеюсь, что он имеет в виду автономный сценарий WSH, а не браузер.   -  person SLaks    schedule 18.01.2010
comment
@Zifre У меня только что был настоящий момент смех вслух   -  person alex    schedule 18.01.2010
comment
Это был запрос многих пользователей на программу выключения, которую я делаю, она используется для гаджета боковой панели, чтобы пользователь мог выполнить отключение по времени с боковой панели.   -  person Sandeep Bansal    schedule 18.01.2010
comment
@Sandeep Bansal: извините, я подумал, что, вероятно, есть какие-то допустимые варианты использования, но я не мог придумать ни одного в то время, и в вашем вопросе не было сказано, почему вы хотели это сделать. Это один из тех вопросов, когда нужно очень четко указать свои намерения, чтобы не показаться злонамеренным. Опять же, извините.   -  person Zifre    schedule 18.01.2010


Ответы (3)


Попробуйте использовать функцию Run вместо Exec и передайте 0 в качестве второго аргумента, чтобы он не показывал окно командной строки:

ws.Run("shutdown.exe -r -t 120", 0);

Окно выключения системы по-прежнему будет отображаться (я не думаю, что это можно как-то подавить).

person Phil Ross    schedule 17.01.2010
comment
Вот так C:\Windows\System32\mshta.exe javascript:new ActiveXObject('WScript.Shell').Run('cmd /c start /max C:\\Windows\\Notepad.exe',0,false); близко() - person Garric; 29.04.2021

Вы можете свернуть окно с помощью следующей команды:

cmd /c start /min SomeCommand

Я предполагаю, что вы знаете, что это не будет работать в браузере, и поэтому я предполагаю, что вы пишете автономный файл JScript с помощью WSH.

person SLaks    schedule 17.01.2010
comment
Ну, это через гаджет боковой панели, поэтому запуск из IE, так что это браузер, немного сложно сделать. - person Sandeep Bansal; 18.01.2010

Кажется, я понимаю, в чем твоя проблема. Вы хотите, чтобы jscript открывал файлы, как в vbscript. Но проблема в том, что jscript (cscript) открывается как консольное приложение и показывает вам при запуске консоль, которую вы ошибочно принимаете за окно cmd, в то время как wscript не имеет консоли и ничего вам не покажет.

Создать ярлыки. Один ярлык для cscript вместо wscript. Принудительно открыть файлы, чтобы они были видны. Сравните разницу в их поведении.

Но не думайте, что это решение всех проблем. wscript не имеет команд ctd (ctdout). Поэтому не все файлы, которые у вас есть, пройдут этот трюк. Попробуйте это на простом файле.

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()"

Я бы предложил такой файл javascript. Работает одинаково в обоих случаях.

var htmlfile=new ActiveXObject('htmlfile').parentWindow;
var alert = function(s){htmlfile.alert(s)};
alert('Hello world!')

Хорошо. Вам нужно закрыть само окно консоли javascript.

Вызов javascript из ярлыка, скрытого с параметрами (например, из ярлыка:

C:\Windows\System32\mshta.exe vbscript:Execute("CreateObject(""WScript.Shell"").Run ""cscript.exe """"С:\path\fname.js"""" """"par1 with whitespace"""" par2WithowtWhiteSpase"", 0:close")

...и не забудьте закрыть невидимый процесс в диспетчере задач после msta.

И даже cmd не покажет свое окно. Он будет выводить данные в консоль jscript, если конечно jscript открыт из cscript. Поэтому окна CMD быть не может. Данные будут выводиться непосредственно в консоль cscript.

Это уже непосредственно про cmd и про получение данных из его процесса:

chcp 1251,866 - меняем на свои региональные параметры

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();

Для тех, кто настаивает на том, чтобы дочерний поток Exec не открывал окно javascript:

Как оказалось, те, кто использует vbs, страдают от отсутствия черной консоли! Они хотят получать данные в процессе cscript! И, разумеется, они хотят сделать это в скрытом окне vbs.

Скрыть окно командной строки при использовании Exec()

Это пример реализации их кода для jscript.

Дальше полный бред. Это относится только к jscript, запускаемому wscript.exe. Для jscript из родного cscript в этом нет необходимости.

Это могло бы иметь смысл, если бы jscript запускался по умолчанию в процессе wscript. Но в jscript для этого в любом случае нужен ярлык windows для этого, который сам по себе может скрыть работу jscript без дополнительного кода.

Хотя, возможно, реализация этого кода была бы полезна при создании многопоточных приложений.

================

Вы должны сделать это в другом потоке, который вы скрыли.

Неважно, какой это будет поток, jscript, PS, Cmd.

Главное - дождаться его ответа с помощью сна или каким-то другим способом.

Самый простой способ получить ответ — в буфер обмена.

Exec останавливает ваш поток и работает только при получении параметров. Код останавливается, и вы ничего не можете с этим поделать.

Возможность запускать скрыто и получать результат есть в vbs. Omegastripes answer Скрыть окно командной строки при использовании Exec().

А по факту работа того скрипта как химера, но без перезапуска самого себя. Новый запуск собственного кода, при этом скрытого, в новом процессе в пространстве {C08AFD90-F2A1-11D1-8455-00A0C91F3880} как cscript, где уже из скрытого потока выдает exec. Затем находит себя и напрямую вставляет переменную обратно в код предварительного просмотра. (objParent.strRes = CreateObject(WScript.Shell).Exec(....)

Но вряд ли можно сделать такую ​​симуляцию переменных в javascript. Например, я даже не смог найти свой собственный новый объект потока cs из «этого» потока. Конечно, я найду его через wmic. Но как мне вставить (захватить) переменную прямо из процесса?

Мой непродуктивный код:

Не удивляйтесь, увидев результат. Это просто дочерний поток, который должен возвращать ответ и должен быть скрыт, но я сделал его видимым.

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();
}
person Garric    schedule 28.04.2021