Perfom a ShellExecute from Firefox Addon

In my Firefox extensions I want to open certain files with the "default viewer" for that file type in Windows. So basically something similar to the ShellExecute('OPEN') function call of the Windows API. Is it possible? If so, how can that be achieved?

Answers:

Answer

Files

The closest thing is nsIFile::launch. However, it is not implemented for every conceivable platform (but it is implemented at least for Windows, OSX, GTK/Gnome and compatible, KDE and Android).

You cannot use ::launch to instruct the OS (in particular Windows) to use a verb other than open, though, so there is no equivalent to e.g. ShellExecute(..., "edit", ...).

Here is a sample on how to use it:

try {
  var file = Services.dirsvc.get("Desk", Ci.nsIFile);
  file.append("screenshot.png");
  file.launch();
}
catch (ex) {
  // Failed to launch because e.g. the OS returned an error
  // or the file does not exist,
  // or this function is simply not implemented for a particular platform.
}

You can of course create an nsIFile instance from "raw" paths as well, e.g. (I'm on OSX):

var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);

Cc and Ci are shortcuts to Components.classes and Components.interfaces that most of the mozilla and add-ons code uses. In the Add-on SDK you can get these via the Chrome Authority.

URIs

Edit I totally forgot that ShellExcute will also handle URLs. And you did ask only about "file type[s]", BTW.

Anyway, to open a random URI, you can use the nsIExternalProtocolService.

Option 1 - Launch with the default handler (not necessarily OS handler)

To launch with a default handler, which could also be a web protocol handler or similar, you can use the following code. Note that this might show a "Select application" dialog, when the user didn't choose a default for a protocol yet.

var uri = Services.io.newURI("https://google.com/", null, null);
var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
          .getService(Ci.nsIExternalProtocolService);
// You're allowed to omit the second parameter if you don't have a window.
eps.loadURI(uri, window);

Option 2 - Launch with the OS default handler, if any

If Firefox can find an OS default handler for a particular protocol, then the code will launch that default handler without user interaction, meaning you should be extra careful not to launch arbitrary URIs that might do harm (e.g. vbscript:...)!

var uri = Services.io.newURI("https://google.com/", null, null);
var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
          .getService(Ci.nsIExternalProtocolService);
var found = {};
var handler = eps.getProtocolHandlerInfoFromOS(uri.scheme, found);
if (found.value && handler && handler.hasDefaultHandler) {
  handler.preferredAction = Ci.nsIHandlerInfo.useSystemDefault;
  // You're allowed to omit the second parameter if you don't have a window.
  handler.launchWithURI(uri, window);
}

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.