Newer Version Available

This content describes an older version of this product. View Latest

InstallHandler Interface

Enables custom code to run after a managed package installation or upgrade.

Namespace

System

Usage

App developers can implement this interface to specify Apex code that runs automatically after a subscriber installs or upgrades a managed package. The package install or upgrade can be customized based on details of the subscriber’s organization. For instance, you can use the script to populate custom settings, create sample data, send an email to the installer, notify an external system, or kick off a batch operation to populate a new field across a large set of data.

The post install script is invoked after tests have been run, and is subject to default governor limits. It runs as a special system user that represents your package, so all operations performed by the script appear to be done by your package. You can access this user by using UserInfo. You only see this user at runtime, not while running tests.

If the script fails, the install or upgrade is aborted. Any errors in the script are emailed to the user specified in the Notify on Apex Error field of the package. If no user is specified, the install or upgrade details are unavailable.

The post install script has the following additional properties.
  • It can initiate batch, scheduled, and future jobs.
  • It can’t access Session IDs.
  • It can only perform callouts using an async operation. The callout occurs after the script is run and the install is complete and committed.
  • It can’t call another Apex class in the package if that Apex class uses the with sharing keyword. This keyword can prevent the package from successfully installing. See the Apex Developer Guide to learn more.
The InstallHandler interface has a single method called onInstall, which specifies the actions to be performed on install or upgrade.
1public interface InstallHandler {
2  void onInstall(InstallContext context)
3};
The onInstall method takes a context object as its argument, which provides the following information.
  • The org ID of the organization in which the installation takes place.
  • The user ID of the user who initiated the installation.
  • The version number of the previously installed package (specified using the Version class). The version is always a three-part number, such as 1.2.0.
  • Whether the installation is an upgrade.
  • Whether the installation is a push.
The context argument is an object whose type is the InstallContext interface. This interface is automatically implemented by the system. The following definition of the InstallContext interface shows the methods you can call on the context argument.
1public interface InstallContext { 
2  ID organizationId();
3  ID installerId();
4  Boolean isUpgrade();
5  Boolean isPush()
6  Version previousVersion();
7}

InstallHandler Methods

The following are methods for InstallHandler.

onInstall(context)

Specifies the actions to be performed on install/upgrade.

Signature

public Void onInstall(InstallContext context)

Parameters

context
Type: System.InstallContext

Return Value

Type: Void

InstallHandler Example Implementation

The following sample post install script performs these actions on package install/upgrade.
  • If the previous version is null, that is, the package is being installed for the first time, the script:

    • Creates a new Account called Newco and verifies that it was created.
    • Creates a new instance of the custom object Survey, called Client Satisfaction Survey.
    • Sends an email message to the subscriber confirming installation of the package.
  • If the previous version is 1.0, the script creates a new instance of Survey called ”Upgrading from Version 1.0”.
  • If the package is an upgrade, the script creates a new instance of Survey called ”Sample Survey during Upgrade”.
  • If the upgrade is being pushed, the script creates a new instance of Survey called ”Sample Survey during Push”.
1public class PostInstallClass implements InstallHandler {
2  global void onInstall(InstallContext context) {
3    if(context.previousVersion() == null) {
4      Account a = new Account(name='Newco');
5      insert(a);
6      
7      Survey__c obj = new Survey__c(name='Client Satisfaction Survey');
8      insert obj;
9               
10      User u = [Select Id, Email from User where Id =:context.installerID()];   
11      String toAddress= u.Email;
12      String[] toAddresses = new String[]{toAddress};
13      Messaging.SingleEmailMessage mail = 
14        new Messaging.SingleEmailMessage();
15      mail.setToAddresses(toAddresses);
16      mail.setReplyTo('support@package.dev');
17      mail.setSenderDisplayName('My Package Support');
18      mail.setSubject('Package install successful');
19      mail.setPlainTextBody('Thanks for installing the package.');
20      Messaging.sendEmail(new Messaging.Email[] { mail });
21      }
22    else
23      if(context.previousVersion().compareTo(new Version(1,0)) == 0) {
24      Survey__c obj = new Survey__c(name='Upgrading from Version 1.0');
25      insert(obj);
26      }
27    if(context.isUpgrade()) {
28      Survey__c obj = new Survey__c(name='Sample Survey during Upgrade');
29      insert obj;
30      }
31    if(context.isPush()) {
32      Survey__c obj = new Survey__c(name='Sample Survey during Push');
33      insert obj;
34      }
35    }
36  }
You can test a post install script using the new testInstall method of the Test class. This method takes the following arguments.
  • A class that implements the InstallHandler interface.
  • A Version object that specifies the version number of the existing package.
  • An optional Boolean value that is true if the installation is a push. The default is false.
This sample shows how to test a post install script implemented in the PostInstallClass Apex class.
1@isTest
2static void testInstallScript() {
3  PostInstallClass postinstall = new PostInstallClass();
4    Test.testInstall(postinstall, null);
5    Test.testInstall(postinstall, new Version(1,0), true);
6    List<Account> a = [Select id, name from Account where name ='Newco'];
7    System.assertEquals(a.size(), 1, 'Account not found');
8  }