Created
October 29, 2009 04:36
-
-
Save brettz9/221159 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // As a function or class, the following can be used to execute | |
| // command-line programs from Firefox. When used with executing | |
| // a batch file with arguments as at | |
| // http://gist.github.com/221161/ , Firefox can be made to pipe | |
| // success or error output to a file and then retrieve the file | |
| // (e.g., to make a FF extension which works as a command-line, | |
| // allowing copy-and-paste, logging, etc.) | |
| /** | |
| * Execute a file on the command line with the given arguments | |
| * @param {String} fileStr File in native format (e.g., "C:\\Users\\Brett") | |
| * @param {String[]} args Array of arguments to pass to the file | |
| * @returns {String} Process ID | |
| */ | |
| function run (fileStr, args) { | |
| var file = Components.classes["@mozilla.org/file/local;1"]. | |
| createInstance(Components.interfaces.nsILocalFile); | |
| file.initWithPath(fileStr); | |
| var p = Components.classes["@mozilla.org/process/util;1"] | |
| .createInstance(Components.interfaces.nsIProcess); | |
| p.init(file); | |
| p.run(false, args, args.length); | |
| return p.pid; // Can't use anymore, but does return in Windows at least | |
| } | |
| /** | |
| * Set up a Processor object | |
| * @class methods for executing command line executables | |
| * @param {String} fileStr The default file to use for executing processes | |
| */ | |
| function Processor (fileStr) { | |
| this.fileStr = fileStr; | |
| } | |
| /** | |
| * Wrap the arguments into an array | |
| * @private | |
| * @param {String[]|String|null|undefined} args The arguments (if any) to wrap | |
| */ | |
| Processor.prototype._wrapArgs = function (args) { | |
| if (!args) { | |
| args = []; | |
| } | |
| else if (typeof args === 'string') { | |
| args = [args]; | |
| } | |
| return args; | |
| }; | |
| /** | |
| * Accept an nsIProcess or nsIProcess2 instance and use it with a file stored on the object to initialize a | |
| * process; also passes through and wraps arguments | |
| * @private | |
| * @param {Components.interfaces.nsIProcess|Components.interfaces.nsIProcess2} p | |
| * @param {String[]|String|null|undefined} args The arguments (if any) to wrap | |
| * @x-todo This should ideally be able to do more than just initWithPath, e.g., accept nsIFile, etc. (as determined | |
| * configurably by esp. the constructor) | |
| */ | |
| Processor.prototype._runHelper = function (p, args) { | |
| var file = Components.classes["@mozilla.org/file/local;1"]. | |
| createInstance(Components.interfaces.nsILocalFile); | |
| file.initWithPath(this.fileStr); | |
| p.init(file); | |
| return this._wrapArgs(args); | |
| }; | |
| Processor.prototype._asyncHelper = function (args, observerObj, holdWeak) { | |
| var p = Components.classes["@mozilla.org/process/util;1"]. | |
| createInstance(Components.interfaces.nsIProcess2); | |
| args = this._runHelper(p, args); | |
| p.runAsync(args, args.length, observerObj, holdWeak || false); | |
| }; | |
| /** | |
| * Run an executable with optional arguments asynchronously, triggering a single callback upon completion or failure | |
| * @param {String[]|String|null|undefined} args The arguments (if any) to wrap and pass to the file | |
| * @param {Components.interfaces.nsIObserver} [observer] The Observer to be notified of progress of process | |
| * (can be an object or just a function that accepts the | |
| * observer arguments); called on main thread | |
| * 1) Takes nsIProcess2 as subject | |
| * 2) 'process-finished' or 'process-failed' as topic | |
| * @param {Boolean} [holdWeak] Whether or not to use a weak reference to the observer (default is false) | |
| * @example | |
| var p = new Processor('C:\\someFile'); | |
| p.runAsync([], {observe: | |
| function (subject, topic, data) { | |
| if (topic==='process-finished') { | |
| alert('finished process'); | |
| } | |
| else if (topic === 'process-failed') { | |
| alert('failed process'); | |
| } | |
| } | |
| }, true); | |
| */ | |
| Processor.prototype.runAsync = function (args, observer, holdWeak) { | |
| var observerObj = observer || null; | |
| if (typeof observer === 'function') { | |
| observerObj = {observe: observer}; | |
| } | |
| this._asyncHelper(args, observerObj, holdWeak); | |
| }; | |
| /** | |
| * Run an executable with optional arguments asynchronously, triggering different callbacks upon completion or failure | |
| * @param {String[]|String|null|undefined} args The arguments (if any) to wrap and pass to the file | |
| * @param {Function} [cbFinished] The callback to be notified of completion of process; called on main thread; passed | |
| * the following arguments: | |
| * 1) nsIProcess2 (subject) | |
| * 2) data | |
| * @param {Function} [cbFailed] The callback to be notified of failure of process; called on main thread; passed | |
| * the following arguments: | |
| * 1) nsIProcess2 (subject) | |
| * 2) data | |
| * @param {Boolean} [holdWeak] Whether or not to use a weak reference to the observer (default is false) | |
| * @example | |
| var p = new Processor('C:\\someFile'); | |
| p.runAsync([], | |
| function (subject, data) { | |
| alert('finished process'); | |
| }, | |
| function (subject, data) { | |
| alert('failed process'); | |
| } | |
| }, true); | |
| */ | |
| Processor.prototype.runAsyncUtil = function (args, cbFinished, cbFailed, holdWeak) { | |
| if (cbFinished || cbFailed) { | |
| cbFinished = cbFinished || function (subject, data, topic) {}; | |
| cbFailed = cbFailed || function (subject, data, topic) {}; | |
| var observerObj = {observe: | |
| function (subject, topic, data) { | |
| // Topic moved as last argument to callbacks since we don't need it (we already know what it is) | |
| if (topic==='process-finished') { | |
| cbFinished(subject, data, topic); | |
| } | |
| else if (topic === 'process-failed') { | |
| cbFailed(subject, data, topic); | |
| } | |
| } | |
| }; | |
| } | |
| this._asyncHelper(args, observerObj, holdWeak); | |
| }; | |
| /** | |
| * Execute a command line executable file with a given argument or arguments (if any) | |
| * @param {String[]|String|null|undefined} args The arguments (if any) to wrap and pass to the file | |
| * @returns {String} Process ID (Can't use this within nsIProcess anymore, but does return in Windows at least) | |
| */ | |
| Processor.prototype.run = function (args) { | |
| var p = Components.classes["@mozilla.org/process/util;1"] | |
| .createInstance(Components.interfaces.nsIProcess); | |
| args = this._runHelper(p, args); | |
| p.run(false, args, args.length); | |
| return p.pid; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment