Thursday, March 3, 2011

Batch file called from Javascript/XPCOM doesn't show command prompt window

I am calling a batch file from Javascript in this fashion:

function runBatch(){
    var exe = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
    exe.initWithPath("C:\\test.bat");
    var run = Components.classes['@mozilla.org/process/util;1'].createInstance(Components.interfaces.nsIProcess);
    run.init(exe);
    var parameters = ["hi"];
    run.run(false, parameters,parameters.length);
}

my test batch file is:

echo on
echo %1 
pause
exit

Each time I call a batch file, however, the command prompt is not displayed, as it would be if I simply ran the batch file from the desktop. How can I remedy this and display a command prompt for the batch file?

Edit To be clear, the cmd.exe process is launched - I can see it in the task bar. But no window gets displayed. This snippet behaves similarly:

function runCmd(){  
var exe = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
exe.initWithPath("C:\\WINDOWS\\system32\\cmd.exe");
var run = Components.classes['@mozilla.org/process/util;1'].createInstance(Components.interfaces.nsIProcess);
run.init(exe);
run.run(false, null,0);
}
From stackoverflow
  • I'd try it with a more explicit approach:

    exe.initWithPath("cmd.exe /C \"C:\\test.bat\"");
    

    From the cmd.exe help screen:

    /C      Carries out the command specified by string and then terminates
    
    pc1oad1etter : Tried that, and it doesn't work either. Actually, just like in my example, it *does* launch cmd.exe - but no window is visible.
  • Did you try using the launch method of nsiLocalFile?

    function runBatch(){
        var exe = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
        exe.initWithPath("C:\\test.bat");
        exe.launch();
    }
    

    This should have "the same effect as if you double-clicked the file."

    pc1oad1etter : Yes. - this will open and show the window but will not let me pass parameters/arguments (which I failed to mention in my question)
    pc1oad1etter : Which led me to ... create a shortcut that has the parameters defined, and I can call the shortcut using nsiLocalFile... and the batch files gets run. But I want to have the parameters be dynamic.
    ng.mangine : Is there a way to create a shortcut on the fly?
  • The only solution I've heard so far (that should work, although I haven't done it yet, comes from Mook in the Mozilla xulrunner IRC channel:

    create a temporary batch file, writing in the batch file to call and arguments to pass it. then execute the temporary batch file.

    e.g.

    f = fopen("temp.bat"); 
    fprintf(f, "other.bat 1 2 3 4 5"); 
    fclose(f); 
    exec("temp.bat");
    

    not very elegant :-) but it should work.

  • Pfft, very ugly code.. A much nicer trick is to use Win.com to spawn a 16bit subsystem of the command prompt. Win.com will send the console to the right virtual terminal, showing you the output.

    var lPath = getWorkingDir.path + "\..\..\WINDOWS\system32\win.com"; lFile.initWithPath(lPath); var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess); process.init(lFile); var args = ["cmd.exe"]; process.run(false, args, args.length);

    Nicer, and works :)

  • You could try to use cmd /c start C:\test.bat. My guess would be, even if the first cmd process gets spawned without a window, the one that executes the batch (called by the start command) gets its window.

  • This code snippet seems to work fine. Of course, you have to change D:\Windows\system32\ to path to cmd.exe in your operation system.

    const FileFactory = new Components.Constructor("@mozilla.org/file/local;1","nsILocalFile","initWithPath");
    var str_LocalProgram = "D:\\Windows\\system32\\cmd.exe";
    var obj_Program = new FileFactory(str_LocalProgram); 
    var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
    process.init(obj_Program);
    var args = ["/C", "regedit.exe"];
    process.run(true, args, args.length);
    
  • Nothing is use full for me

0 comments:

Post a Comment