【问题标题】:Intercept/handle mime type/file拦截/处理 mime 类型/文件
【发布时间】:2014-07-03 17:49:22
【问题描述】:

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

【问题讨论】:

  • 我调查过了,但我不确定。我研究了 firefox 如何使浏览器成为默认应用程序,它使用 shell 服务,尝试在这里调查:mxr.mozilla.org/mozilla-release/source/browser/components/…
  • 我想过这个。如果您想说用户从操作系统文件资源管理器中单击文件,那么您必须针对每个操作系统执行一些操作。但是,如果您希望用户单击具有某些扩展名的 Firefox 中的链接,则可以通过附加组件进行处理。不是我之前评论中的 shell 方法。不过我得坐下来做这件事,现在凌晨 335 点太累了!
  • 是的,我想在单击链接时覆盖 Firefox 默认操作。我发现一些旧代码使用观察者并过滤所有请求和响应,然后在禁用弹出对话框的洪流时内联文件附件,但它似乎不再起作用。肯定有一种方法可以简单地为 mime 类型本身注册一个句柄吗?
  • 好的,所以 Firefox 在选项中有一个用于 mime 类型的处理程序。所以你得弄乱它,我调查了它,但我不知道如何将它设置为扩展。这是 mxr 上用于设置 mime 类型处理程序的来源:MXR :: mozilla-releaseImage of Firefox mime type to hanlder options menu

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


【解决方案1】:

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

根据您的处理方式,您可以使用nsIHandlerApp-ervied 接口,例如将 uri(协议)或文件(mime)直接传递到某个本地或 Web 应用程序,或实现一个完整的流转换器,如 PDF.js。

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

【讨论】:

  • 感谢这个很棒的帖子。这不是勺子喂食解决方案,我花了一周左右的时间,但我把它搞定了。为普通用户制作了这个简单的附加组件,以将 webmamil 客户端安装为 mailto 处理程序。 AMO :: MailtoWebmails。我将您归功于“协议 XPCOM 教育:P
【解决方案2】:

根据@nmaiers 的帖子,这是你的做法:

如果 mime 类型已经存在,您就是这样做的。如果它不存在我不知道如何添加它,可能是一些注册功能。

出于某种原因,我的torrents 的类型是application/x-download,我不知道为什么。如果你想知道我是如何计算出来的,我会告诉你的。因此,在下面的示例中,我将其用作文件类型。

当我们console.log(wrappedHandlerInfo) 时,我们看到它看起来像这样:

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

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 对象略有不同,因为它有一个primaryExtension 属性来保存种子。


两种方式都有问题

这两种方式的问题是,如果 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 参数:

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


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多