创建隐藏的cmd javascript

时间:2010-01-17 23:03:09

标签: javascript cmd

我正在寻找一种方法来运行cmd命令而不向用户显示cmd窗口。

我正在使用类似的东西:

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

    }
    

但它仍然显示窗口,无论如何不显示它?

由于

3 个答案:

答案 0 :(得分:5)

尝试使用Run函数而不是Exec并将其作为第二个参数传递0,以防止它显示命令提示符窗口:

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

系统关闭窗口仍会显示(我认为没有办法压制它)。

答案 1 :(得分:0)

您可以使用以下命令使窗口最小化:

cmd /c start /min SomeCommand

我认为您知道这在浏览器中不起作用,因此我假设您正在使用WSH编写独立的JScript文件。

答案 2 :(得分:-1)

我想我明白你的问题所在。您想让 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(); 

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 窗口中进行。

Hide command prompt window when using Exec()

这是他们的 jscript 代码的示例实现。

另外,完全是废话。这仅适用于 wscript.exe 启动的 jscript。对于来自原生 cscript 的 jscript,不需要。

如果在 wscript 进程中默认运行 jscript 可能是有意义的。但是在jscript中,无论如何,我们需要一个windows的快捷方式,它本身可以隐藏jscript的工作,不需要额外的代码。

尽管此代码的实现可能对创建多线程应用程序很有用。

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

您必须在隐藏的另一个线程中执行此操作。

不管它是什么类型的流,jscript、PS、Cmd。

最重要的是 - 使用睡眠或其他方式等待他的回复。

获得答案的最简单方法是剪贴板。

Exec 停止您的线程,它仅适用于接收参数。代码停止了,您对此无能为力。

隐藏运行并获得结果的能力在vbs中。 Omegastripes 回答 Hide command prompt window when using Exec()

但实际上,那个脚本的工作就像是chimera,只是没有重启。新推出自己的代码,同时隐藏在新进程空间{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();
}