检测Chrome扩展程序首次运行/更新


Answers:


174

在较新版本的Chrome(自Chrome 22起)中,您可以使用该chrome.runtime.onInstalled事件,它更加干净。

例:

// Check whether new version is installed
chrome.runtime.onInstalled.addListener(function(details){
    if(details.reason == "install"){
        console.log("This is a first install!");
    }else if(details.reason == "update"){
        var thisVersion = chrome.runtime.getManifest().version;
        console.log("Updated from " + details.previousVersion + " to " + thisVersion + "!");
    }
});

2
这次真是万分感谢!我在Internet上发现的所有内容都是将扩展程序的版本存储在localStorage中,直到我最终偶然发现此答案时,这当然是一个可行的解决方案,但令我感到惊讶的是chrome没有为此内置任何功能!我很高兴,我没有辜负:)
JMTyler

2
自Chrome 22于2012
-Redzarf

1
chrome.runtime.onInstalled会检测何时在后台安装应用或扩展程序。但是,它没有执行的操作是检测到chrome.app.runtime.onLaunched事件的第一次触发...
realkstrawn93 2014年

3
我使用了这段代码一段时间,并且效果很好,直到我的扩展请求更新的新权限(该扩展将暂停该扩展,直到用户接受该权限为止)。当许可被接受并且扩展名未被暂停时,onInstalled事件将不会触发,因此更新脚本也将不会运行。值得一提的是那些在onInstalled上运行更新脚本的人,在您请求新权限的情况下,您可能需要侦听其他事件。
伊林2014年

2
@Elimm似乎是Chrome的错误,您应该在错误跟踪器上报告。
Alvin Wong

72

更新了答案以反映清单的v3:

Chromium现在具有一组chrome.runtime API,可让您获取扩展程序的版本。

要获取当前版本:

chrome.runtime.getManifest().version

若要在首次安装扩展程序时,扩展程序更新为新版本以及Chromium更新为新版本时进行监听,可以使用该onInstalled事件。

chrome.runtime.onInstalled.addListener((details) => {
   const currentVersion = chrome.runtime.getManifest().version
   const previousVersion = details.previousVersion
   const reason = details.reason

   console.log('Previous Version: ${previousVersion }')
   console.log('Current Version: ${currentVersion }')

   switch (reason) {
      case 'install':
         console.log('New User installed the extension.')
         break;
      case 'update':
         console.log('User has updated their extension.')
         break;
      case 'chrome_update':
      case 'shared_module_update':
      default:
         console.log('Other install events within the browser')
         break;
   }

})

就这样!


旧答案,2011年之前

如果要检查扩展程序是否已安装或更新,可以执行以下操作:

  function onInstall() {
    console.log("Extension Installed");
  }

  function onUpdate() {
    console.log("Extension Updated");
  }

  function getVersion() {
    var details = chrome.app.getDetails();
    return details.version;
  }

  // Check if the version has changed.
  var currVersion = getVersion();
  var prevVersion = localStorage['version']
  if (currVersion != prevVersion) {
    // Check if we just installed this extension.
    if (typeof prevVersion == 'undefined') {
      onInstall();
    } else {
      onUpdate();
    }
    localStorage['version'] = currVersion;
  }

如果我在Gmail的内容脚本中运行getVersion(),则会获得Gmail应用程序版本号。我应该指出,有很多问题会阻止此类脚本的工作:a)安装插件时,需要将内容脚本注入页面中,并且页面已经加载,内容脚本会没有注入到页面中,则必须重新加载页面)。b)可以从后台脚本获取插件的版本号,但是后台脚本无法访问localStorage,只有内容脚本可以访问,但尚未加载...
Victor S

3
这篇帖子很棒...您应该将此帖子标记为答案。谢谢穆罕默德!
frenetix'2

3
@VictorS上面的内容旨在在后台页面中使用,如果您打算在内容脚本中使用它,则只需直接调用chrome.app.getDetails()。version。我之所以执行getVersion的原因是因为在Chrome扩展开发的早期,没有chrome.app对象,因此我们必须XHR清单。您可以将所有操作都放在一个闭包中,这样就可以保证调用正确的方法。我通常将所有内容封装在一个类对象中。
Mohamed Mansour '02

1
太好了,对我有用。请注意,上面的代码缺少分号,并且“ undefined”不应该带有引号。
mpoisot 2012年

@mpoisot抱歉地说,您对“未定义”有误。(我知道我参加这个聚会已经很晚了,但是这对于像我这样偶然遇到的其他人可能很重要。)他没有试图检查prevVersion == 'undefined'...他正在检查typeof prevVersion == 'undefined'typeof检查变量是否未定义时使用它更健壮...请参阅此处以了解原因:stackoverflow.com/a/3550319/130691
JMTyler 2013年

20

幸运的是,现在有一些与此相关的事件(自Chrome版本22和25起为更新事件)。

对于已安装的事件:

chrome.runtime.onInstalled.addListener(function() {...});

对于OnUpdateAvailable事件:

chrome.runtime.onUpdateAvailable.addListener(function() {...});

开发人员文档中有关OnUpdateAvailable的重要摘录说:

在有可用更新但由于应用当前正在运行而未立即安装时触发。如果不执行任何操作,则下次卸载后台页面时将安装更新,如果希望尽快安装,则可以显式调用chrome.runtime.reload()。


9

简单。扩展程序首次运行时,localStorage为空。首次运行时,您可以在其中写入一个标志,以将所有随后的运行标记为非第一次。

例如,在background.htm中:

var first_run = false;
if (!localStorage['ran_before']) {
  first_run = true;
  localStorage['ran_before'] = '1';
}

if (first_run) alert('This is the first run!');

编辑:要检查扩展名是否刚刚更新,请在首次运行时存储版本而不是简单的标志,然后当当前扩展名版本(通过XmlHttpRequest清单显示)而不等于存储在时localStorage,扩展名已已更新。


注意不要在内容脚本中这样做。该页面上的localStorage与其他代码和扩展名共享。因此,这在内容脚本中不起作用。
huyz 2011年

对于打包的应用程序,这确实是在后台页面中使用的绝对解决方案,因为打包的应用程序localStorage确实在其自己的单独窗口中,并且不与@huyz提到的页面上的其他代码和扩展共享。但是,对于扩展名,不是这种情况。
realkstrawn93 2014年

1
但是,这需要存储权限。
Pacerier's
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.