如何更换/升级Chrome扩展程序?

时间:2015-12-16 08:42:36

标签: google-chrome google-chrome-extension

我的团队拥有Chrome扩展程序,而其他团队也有类似的扩展程序,但很快就会弃用,因此我们会接管所有现有用户。这就是问题 - 有没有办法将用户从他们的扩展迁移到我们的无缝?即有没有办法从用户端自动升级到我们的分机?

1 个答案:

答案 0 :(得分:0)

没有无缝方式,因为明显的安全原因,扩展程序无法安装其他扩展程序(即使有"management"权限),但这里有可能的升级路径。

我打电话给" old"扩展名A并假设其ID为"extension_a_id",并且" new"扩展B并假设它的ID是`extension_b_id"。

  1. 确保扩展程序可以相互通信。除非您在清单中明确定义"externally_connectable",否则默认情况应该如此;如果您这样做,请确保扩展程序B包含"extension_a_id" ID,反之亦然。

  2. 更新扩展程序B以包含在以下所有步骤中响应来自的请求的代码。在您确定大多数安装基础都有此版本(可能等待一周左右)之前,请不要继续。

    //// Extension B (background code) ////
    chrome.runtime.onMessageExternal.addListener(
      function(message, sender, sendResponse) {
        if(sender.id && sender.id == "extension_A_id") {
          /* ..processing code.. */
        }
      }
    );
    
  3. 在分机A中,添加一个安装了分机B的检查。通过ping它来这样做:

    //// Extension A ////
    chrome.runtime.onStartup.addListener(function() {
      isNewInstalled(function(response) {
        if(response) {
          transferPreferences(response.versionB); // See step 5
        } else {
          // Nag user to install, see step 4
        }
      });
    });        
    
    function isNewInstalled(callback) {
      chrome.runtime.sendMessage(
        "extension_B_id",
        {areYouThere: true},
        passResponseOrFalse(callback)
      );
    }
    
    function passResponseOrFalse(callback) {
      return function(response) {
        // It's important to evaluate chrome.runtime.lastError
        //   to prevent uncatchable exception, see http://stackoverflow.com/q/28431505
        if(chrome.runtime.lastError || !response) {
          callback(false);
        } else {
          callback(response);
        }
      }
    }
    
    //// Extension B (processing code) ////
    // Send version number just in case
    if(message.areYouThere) sendResponse({
      versionB: chrome.runtime.getManifest().version
    });
    
  4. 如果在步骤3中未安装扩展B,请唠叨用户进行安装:显示一个页面,说明升级和链接到CWS列表所需的原因。此步骤需要用户输入。

  5. 如果已在步骤3中安装了扩展程序B,请转移用户选项并自行卸载:

    //// Extension A ////
    function transferPreferences(versionB) {
      /* ..validate version of B.. */
      var prefs = {};
      /* ..fill prefs with data that needs to be transfered (JSON-encodable).. */
      chrome.runtime.sendMessage(
        "extension_B_id",
        {
          versionA: chrome.runtime.getManifest().version,
          preferences: prefs
        },
        passResponseOrFalse(goodbyeCruelWorld)
      );
    }
    
    function goodbyeCruelWorld(response) {
      if(response.processed) {
        // Does not require management permission
        chrome.management.uninstallSelf();
      } else {
        console.warn("It is not my time to die yet.");
      }
    }
    
    //// Extension B, processing code ////
    if(message.preferences) {
      /* ..validate message.versionA and process message.preferences.. */
      sendResponse({processed: true});
    }
    
  6. 安装扩展程序B时,向(可能已安装的)扩展程序A发送即时启动转移的消息:

    //// Extension B, background code ////
    chrome.runtime.onInstalled.addListener(function(details) {
      /* ..maybe check details.reason and new version.. */
      chrome.runtime.sendMessage(
        "extension_A_id",
        {iAmHere: true, versionB: chrome.runtime.getManifest().version},
        ignoreResponse
      );
    });
    
    function ignoreResponse(response) {
      // Again, evaluate to avoid exceptions;
      //   if needed, this is the place to check if A is still installed
      return chrome.runtime.lastError;
    }
    
    //// Extension A, background code ////
    chrome.runtime.onMessageExternal.addListener(
      function(message, sender, sendResponse) {
        if(sender.id && sender.id == "extension_B_id") {
          if(message.iAmHere) {
            sendResponse({
              versionA: chrome.runtime.getManifest().version
            });
            transferPreferences(message.versionB);
          }
        }
      }
    );
    
  7. 将扩展B的更新发布到上述所有内容。

  8. 结果:

    • 安装了B的用户不会注意到任何内容,因为ignoreResponse会吞噬邮件错误;
    • 两个已安装的用户将在B更新后立即启动转移并且将悄然完成;
    • 只有A的用户在每次扩展重启时都会被唠叨而不是安装B,而转移将自动开始。

    最后一个问题是不要用B中的偏好来破坏B的偏好;作为练习留给读者(也取决于实施)。