拦截/处理mime类型/文件

时间:2014-07-03 17:49:23

标签: firefox-addon firefox-addon-sdk xpcom

如何禁用.torrent文件/内容类型application / x-bittorrent的默认操作(例如,使用对话框或运行程序打开),而是处理扩展中的数据?

2 个答案:

答案 0 :(得分:3)

有多种方法可以归结为nsIMimeService / nsIHandlerServicensIMimeInfo并设置相应的nsIHandlerInfo。例如。请参阅PDF.js making itself the handler for PDF files(通过有效禁用所有处理程序或插件并实现流转换器)或我的answer on how to register a web protocol handler(不是与mime相关但与协议相关,但处理程序信息仍然适用)。

根据您处理事项的方式,您可以使用nsIHandlerApp - 验证的界面,例如将uri(协议)或文件(mime)直接传递给某些本地或Web应用程序,或实现像PDF.js这样的完整流式转换器。

理论上,还可以实现新的nsIHandlerApp派生接口,特别是launchWithURI(协议)或launchWithFile(mime内容类型和文件扩展名)(下载))。但是,这有点棘手,因为nsIHandlerService只处理内置接口。

答案 1 :(得分:1)

根据@nmaiers帖子,您就是这样做的:

如果mime类型已存在,则执行此操作。如果它不存在我不知道如何添加它,可能是一些寄存器功能。

出于某种原因,我的torrent的类型是application/x-download我不明白为什么。如果你想知道我如何理解这一点,我会告诉你。因此,在下面的示例中,我将其用作文件类型。

当我们console.log(wrappedHandlerInfo)时,我们发现它看起来像这样: variable viewer on wrappedHandlerInfo

所以现在让我们列举所有应用程序处理程序(我从这里得到了这个:MXR :: gApplicationsPane,如果.type == 'application/x-download' let's打破了,那么我们就可以玩那个对象。

var handlerService = Cc['@mozilla.org/uriloader/handler-service;1'].getService(Ci.nsIHandlerService);

var listOfWrappedHandlers = handlerService.enumerate();
var i = 0;
while (listOfWrappedHandlers.hasMoreElements()) {
  var wrappedHandlerInfo = listOfWrappedHandlers.getNext().QueryInterface(Ci.nsIHandlerInfo);
  console.log(i, 'handler for', wrappedHandlerInfo.type, wrappedHandlerInfo);
  if (wrappedHandlerInfo.type == 'application/x-download') {
    break;
  }
  i++;
}
console.log('Listed ', i, ' handlers');
console.log('wrappedHandlerInfo=', wrappedHandlerInfo); //should be the application/x-download one as we broke the loop once it found that

现在我们必须设置它的属性然后保存它。

// Change and save mime handler settings.
wrappedHandlerInfo.alwaysAskBeforeHandling = false;
wrappedHandlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
handlerService.store(wrappedHandlerInfo);

我不知道该怎么改变这些属性,也许@nmaier可以告诉我们。

我们在MXR :: nsIHandlerService.idl #L69看到商店这样做:

69    * Save the preferred action, preferred handler, possible handlers, and
70    * always ask properties of the given handler info object to the datastore.
71    * Updates an existing record or creates a new one if necessary.
72    *
73    * Note: if preferred action is undefined or invalid, then we assume
74    * the default value nsIHandlerInfo::useHelperApp.
75    *
76    * @param aHandlerInfo  the handler info object
77    */
78   void store(in nsIHandlerInfo aHandlerInfo);

另一种方式

好的,我找到了更好的方法,这样你就不需要循环来找到处理程序。

这样做:

var mimeService = Cc['@mozilla.org/mime;1'].getService(Ci.nsIMIMEService);
var CONTENT_TYPE = ''; //'application/x-download'; can leave this blank
var TYPE_EXTENSION = 'torrent';

var handlerInfo = mimeService.getFromTypeAndExtension(CONTENT_TYPE, TYPE_EXTENSION);
console.info('handlerInfo:', handlerInfo); //http://i.imgur.com/dUKox24.png

    // Change and save mime handler settings.
    handlerInfo.alwaysAskBeforeHandling = false;
    handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
    handlerService.store(handlerInfo);

handlerInfo对象略有不同,因为它具有保存torrent的primaryExtension属性。

using nsiMIMService to get the handlerinfo object


双向问题

两种方式的问题在于,如果mime类型不存在,你必须以某种方式注册它,我不知道如何。可能使用mime服务和一些注册功能。

2014年8月3日更新

我想我找到了上面子弹中提到的问题的解决方案(两种方式都存在问题)。

MXR :: addPossibleApplicationHandler

235   addPossibleApplicationHandler: function(aNewHandler) {
236     var possibleApps = this.possibleApplicationHandlers.enumerate();
237     while (possibleApps.hasMoreElements()) {
238       if (possibleApps.getNext().equals(aNewHandler))
239         return;
240     }
241     this.possibleApplicationHandlers.appendElement(aNewHandler, false);
242   },
243 

这是addPossibleApplicationHandler的代码,我们可能只需要复制并以某种方式进行编辑。

2014年8月3日更新

好的,这是如何添加协议处理程序(它只添加一个nsIWebAppHandler,但我确定添加一个本地意义的nsIAppHandler它应该是类似的,不需要uri param:

https://gist.github.com/Noitidart/2faaac70c62bc13e7773#add-a-handler-to-a-protocol


有关nsIMIMEService中可用功能的信息:MXR :: nsIMIMEService.idl