MozillaZine

running an exe packed inside an extension

Talk about add-ons and extension development.
Torpark

User avatar
 
Posts: 16
Joined: October 5th, 2005, 9:06 am

Post Posted July 31st, 2006, 6:25 pm

What code would I need to run an exe file stored inside the extension archive (xpi) ?

max1million
 
Posts: 2810
Joined: November 15th, 2004, 5:03 am

Post Posted July 31st, 2006, 9:30 pm

In Firefox 1.5 the xpi is extracted to a folder with named with your extension's guid ( like {12345678-1234-1234-1234-123456789012} or sample@sam.org), inside the extension folder, inside your profile folder. You'll need to edit samplePath to reflect the folder (not in a .jar) that it's in.

If I didn't miss anything
Code: Select all
//**** get profile folder path ****
  var dsprops = Components.classes['@mozilla.org/file/directory_service;1']
      .getService(Components.interfaces.nsIProperties);
  var ProfilePath = dsprops.get("ProfD", Components.interfaces.nsIFile).path;

//**** add path to sample.exe, guid is the guid of your extension (in Firefox 1.5) or the folder it is installed to ****
  var samplePath = (ProfilePath + "\\extensions\\guid\\sample.exe");

//**** launch the exe ****
  var file = Components.classes["@mozilla.org/file/local;1"]
      .createInstance(Components.interfaces.nsILocalFile);
  file.initWithPath(samplePath);
  file.launch();

A good place to find more info and Example code http://kb.mozillazine.org/Extension_development
http://developer.mozilla.org/en/docs/Co ... plications

EDIT An additional note: I believe I should have used append to get to sub folders and files before getting the path, instead of using + to add to the path, for better cross platform support.

Edit again:
Perhaps more like :
Code: Select all
//**** get profile folder path ****
  var dsprops = Components.classes['@mozilla.org/file/directory_service;1']
      .getService(Components.interfaces.nsIProperties);
  var ProfilePath = dsprops.get("ProfD", Components.interfaces.nsIFile).path;

//**** initialize file ****
  var file = Components.classes["@mozilla.org/file/local;1"]
      .createInstance(Components.interfaces.nsILocalFile);
  file.initWithPath(ProfilePath);

//**** append each step in the path ****
  file.append("extensions");
  file.append("guid");
  file.append("sample.exe");

//**** run ****
  file.launch();
NOTE "ProfD" is refering to the "Profile Directory" which could be changed for others.
http://developer.mozilla.org/en/docs/Co ... cial_files
Last edited by max1million on February 19th, 2007, 4:34 am, edited 5 times in total.

bamm
 
Posts: 199
Joined: September 22nd, 2004, 2:24 am
Location: Marikina City, Philippines

Post Posted July 31st, 2006, 9:55 pm

Just in case he wants to run the exe with some command line parameters, I suggest the following code to launch the file:

Code: Select all
function sampleFunction(samplePath, parameter)
{
  var paramArray = parameter ? parameter.split(/\s+/) : [];
  var nsILocalFile = Components.classes["@mozilla.org/file/local;1"]
      .getService(Components.interfaces.nsILocalFile);
  var nsIProcess = Components.classes["@mozilla.org/process/util;1"]
      .getService(Components.interfaces.nsIProcess);
  nsILocalFile.initWithPath(samplePath);
  nsIProcess.init(nsILocalFile);
  nsIProcess.run(false, paramArray, paramArray.length);
  nsIProcess.close();
  return nsILocalFile;
}

Torpark

User avatar
 
Posts: 16
Joined: October 5th, 2005, 9:06 am

Post Posted August 1st, 2006, 7:33 am

max, code failed to work. I have sent your a private message on it.

Thank ya'll for your help so far. This has been maddening.

Torpark

User avatar
 
Posts: 16
Joined: October 5th, 2005, 9:06 am

Post Posted August 1st, 2006, 9:55 am

It Worked! Max, I was wrong, your code is great. I just didn't set the right GUID!

Brilliant!

keyriosity
 
Posts: 12
Joined: October 20th, 2006, 2:03 pm

Post Posted November 10th, 2006, 5:04 pm

I have an InstallShield exe. I want to pack it inside my xpi so that when the extension is being installed, the exe gets launched. I wanted to know in which file is the code change to be implemented?

TIA.

keyriosity
 
Posts: 12
Joined: October 20th, 2006, 2:03 pm

Post Posted November 10th, 2006, 5:09 pm

i just wanted to add this information to my above post. i have an install.rdf and not an install.js in my xpi bundle.

max1million
 
Posts: 2810
Joined: November 15th, 2004, 5:03 am

Post Posted November 12th, 2006, 12:55 am

keyriosity
The above code is for running an executable after install is compete. You could use it as a second phase of install by testing for existence of the file, running it, then deleting it (or move it), so that it is run once, only on the first restart. The test although quick, would occur every-time Firefox is loaded. And depending on what you are installing, may require a second restart of browser or restart of OS. Note: Setting a preference would tend to stick (even after uninstall) making reinstall/upgrade fail if the pref is not first cleared.
http://developer.mozilla.org/en/docs/nsIFile:exists
http://developer.mozilla.org/en/docs/nsIFile:remove
http://developer.mozilla.org/en/docs/nsIFile
http://developer.mozilla.org/en/docs/Co ... s:File_I/O

If you want to run during install before the first restart, then you'll probably need install.js (last I know Firefox still can install from .js) which is ignored in current Firefox (and Thunderbird?) if you also have install.rdf which is required for upload to addons.mozilla.org. You should be able to get around that by by multiple item packaging. Pack the .xpi with with install.js (no install.rdf, no chrome.manifest) and the installer.exe inside .xpi, then pack that in another .xpi with install.rdf as if you were making a multi item package (.xpi). A note, I've not had need to try it yet.
http://developer.mozilla.org/en/docs/XP ... ds:execute
http://developer.mozilla.org/en/docs/XP ... _Reference
http://kb.mozillazine.org/Install.js
http://developer.mozilla.org/en/docs/Mu ... _Packaging
http://kb.mozillazine.org/Install.rdf
http://developer.mozilla.org/en/docs/Ex ... _Packaging

keyriosity
 
Posts: 12
Joined: October 20th, 2006, 2:03 pm

Post Posted November 14th, 2006, 11:47 am

i am trying approach #2 - packaging an xpi inside another. i'll let you know what happens.
thanks very much for your help.

max1million
 
Posts: 2810
Joined: November 15th, 2004, 5:03 am

Post Posted August 5th, 2007, 7:48 pm

Looks like FF's extension manager won't send the old style extension.xpi in Multiple Item Package to xpinstall. Won't run install.js from inside an xpi in the pakage.

max1million
 
Posts: 2810
Joined: November 15th, 2004, 5:03 am

Post Posted August 6th, 2007, 3:33 am

Cleaned up a bit?

Using nsILocalFile.launch
Code: Select all
var file = Components.classes['@mozilla.org/file/directory_service;1']
    .getService(Components.interfaces.nsIProperties)
    .get("ProfD", Components.interfaces.nsILocalFile);
file.append("extensions");
file.append("guid"); // guid of extension
file.append("sample.exe");
if (file.exists()) file.launch();

Using nsIProcess to run a nsILocalFile
Code: Select all
var file = Components.classes['@mozilla.org/file/directory_service;1']
    .getService(Components.interfaces.nsIProperties)
    .get("ProfD", Components.interfaces.nsILocalFile);
file.append("extensions");
file.append("guid"); // guid of extension
file.append("sample.exe");
if (file.exists()) {
  var process = Components.classes['@mozilla.org/process/util;1']
      .getService(Components.interfaces.nsIProcess);
  process.init(file);
  var arguments= [] ; // command line arguments array
  process.run(false, arguments, arguments.length);
}

Or in Firefox you can use nsIExtensionManager to get to the extension's installed in (guid) directory as nsIFile and nsIProcess to run it (launch don't work on it)
Code: Select all
var file = Components.classes["@mozilla.org/extensions/manager;1"]
      .getService(Components.interfaces.nsIExtensionManager)
      .getInstallLocation("guid")
      .getItemLocation("guid"); // guid of extension
file.append("sample.exe");
if (file.exists()) {
  var process = Components.classes['@mozilla.org/process/util;1']
      .getService(Components.interfaces.nsIProcess);
  process.init(file);
  var arguments= [] ; // command line arguments array
  process.run(false, arguments, arguments.length);
}

For a run once you can replace the last 2 line in either of the last 2 code blocks with:
Code: Select all
  process.run(true, arguments, arguments.length);
  file.remove(false);
}
The true should block other processes and pause the script till the executable is finished, then remove the file.

Elzilla
 
Posts: 2
Joined: March 18th, 2008, 6:09 am

Post Posted March 18th, 2008, 9:15 am

Is there anyway to run an executable during install when we have an install.rdf and not an install.js?

max1million
 
Posts: 2810
Joined: November 15th, 2004, 5:03 am

Post Posted March 18th, 2008, 11:58 pm


neelamravi
 
Posts: 3
Joined: September 23rd, 2008, 1:06 am

Post Posted September 25th, 2008, 3:57 am

Hi All,
I have a code which runs an EXE from the extension. Everything seems to be fine,but the arguments(args) while passing to the RUN method,I want to pass two file paths to this EXE as one is input parameter and other is output parameter. For first parameter i mentioned as "-in" and for out parameter i mentioned as "-out". I tried removing this two("-in","-out") also but no change in result. Can any one help me, how can i pass the two parameters to the EXE in run method. Please..... ](*,) ](*,)
Code: Select all
var dsprops = Components.classes['@mozilla.org/file/directory_service;1']
          .getService(Components.interfaces.nsIProperties);
   var ProfilePath = dsprops.get("ProfD", Components.interfaces.nsIFile).path;
   var samplePath = (ProfilePath + "\\extensions\\guid\\OpenXMLViewer.exe");
   var file = Components.classes["@mozilla.org/file/local;1"]
                         .createInstance(Components.interfaces.nsILocalFile);
   file.initWithPath(samplePath);
   var process = Components.classes["@mozilla.org/process/util;1"]
                            .createInstance(Components.interfaces.nsIProcess);
   process.init(file);
   var args = [" -in D:\\OpenXML_SilverLight\\abc.docx"," -out D:\\OpenXML_SilverLight\\abc.html"];
   process.run(true, args, args.length);

wanderingstan
 
Posts: 9
Joined: September 15th, 2004, 3:08 am
Location: Osnabrück, Germany

Post Posted December 13th, 2008, 3:41 pm

The previous code was a little ambiguous about where to replace "guid" with your actual guid. (At least I was confused...) Here is the exact code that worked for me:
Code: Select all
    // Launch external scanning program                               
    var file = Components.classes["@mozilla.org/extensions/manager;1"]
          .getService(Components.interfaces.nsIExtensionManager)
          .getInstallLocation("myextension@stan.james") // guid of extension, replace with yours
          .getItemLocation("myextension@stan.james"); // guid of extension, replace with yours
    file.append("simpletwain.exe"); // exe file, residing in the top-level folder of your extension (alongside content folder, not in it)
    if (file.exists()) {
      var process = Components.classes['@mozilla.org/process/util;1']
          .getService(Components.interfaces.nsIProcess);
      process.init(file);
      var arguments= [] ; // command line arguments array
      process.run(false, arguments, arguments.length);
    }
    else {
      promptService.alert(window,'Error','Could not find external exe');
    }


Return to Extension Development


Who is online

Users browsing this forum: No registered users and 1 guest