Request a Demo Start Trial
Windows Analytics
Download Windows Analytics SDK
version 6.2.0

Inno Setup Installers


This document will walk you through creating an Inno Setup installer with DeskMetrics Analytics integrated. We’ll be working through the file examples/InnoSetup/setup_with_analytics.iss, so open it up and follow along.

We’ll make use of the following files from the SDK zip:

Include the bindings

If you’re using the unicode version of Inno Setup (you should be!) then include dma_unicode.iss, otherwise include dma_ansi.iss.

Next, define your app key and some of the recommended DeskMetrics properties described in the Data Modelling Guide.

// Include DeskMetrics Analytics
#include "../../sdk/dma_unicode.iss"

// Your app key - this can be found on the applications page of your DeskMetrics dashboard.
#define AppKey = '<YOUR_APP_KEY_HERE>'
#define TrackingId = '<YOUR_TRACKING_ID_HERE>'
#define SubId = '<YOUR_SUB_ID_HERE>'
#define Channel = '<YOUR_CHANNEL_HERE>'

Add some files

At the top of the [Files] section, include dma.dll. This file needs to be unpacked to the application install directory so it can be used by the application and uninstaller. If your installer is deploying a 64 bit application, or a .NET application targeting the AnyCPU or x64 architectures, then also add a similar directive for dma_x64.dll.

; Extract isa.dll to the application install directory
Source: "../../sdk/dma.dll"; DestDir: "{app}"
; .NET applications will typically need the 64 bit version of the dll as well
Source: "../../sdk/dma_x64.dll"; DestDir: "{app}"

Initialize the SDK

In the [Code] section, define the InitializeWizard procedure as required by Inno Setup. This is where we will start the SDK and establish the properties that should be sent on all analytics events.

procedure InitializeWizard();
  EntityId: String;
  InstallTime: Cardinal;
  // Collect click-tracking data.
  // If this installer was downloaded via a DeskMetrics tracking link, then
  // DMAGetClickData will populate the ClickId and TrackingLinkKey variables with
  // appropriate values.  Otherwise, blank strings will be used.
  EntityId := ''
  DMAResolveEntityId('{#AppKey}', EntityId)

  // NTP time check that will block, waiting on a response for up to 5000ms (5 seconds).
  // If a response is not received within that time, the local computer's UTC time will be used.
  InstallTime := DMAGetTimestamp(5000)

  // Load properties that may have been persisted to the registry by a previous version of the installer
  // or a previous run of this installer.
  DMALoadProperties('HKCU\SOFTWARE\HelloDeskMetrics\_dm', false)

  // Set some properties that should appear on all events sent by the SDK.  We recommend passing
  // false as the final parameter to these functions, indicating that the properties should *not* be
  // overwritten if they were already present in the data loaded from the registry.  This non-overwrite
  // policy will give us sensible behaviour if this installer is used to update an existing installation
  // to a newer version.  That is, the analytics events will still maintain the install_time, tracking_id,
  // sub_id, etc of the original installer.
  DMASetPropertyString('tracking_id', '{#TrackingId}', false)
  DMASetPropertyString('sub_id', '{#SubId}', false)
  DMASetPropertyString('channel', '{#Channel}', false)
  DMASetPropertyString('dm.entity_id', EntityId, false)
  DMASetPropertyUInt('install_time', InstallTime, false)
  DMASetPropertyString('cohort', '${dm.cohort:install_time}', false)

  // Save the properties to the registry so they will be available to the application and uninstaller.
  DMASaveProperties('HKCU\SOFTWARE\HelloDeskMetrics\_dm', false)

  // Start the analytics session.  This will trigger the automatic "install_launch" event.

Add a few code hooks

Define a few more Inno Setup procedures. Add DeskMetrics function calls to keep the SDK informed. Finally, stop the SDK in the ISADeinitializeSetup procedure.

procedure CurStepChanged(CurStep: TSetupStep);
  // Tell the analytics SDK which step we're on.

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
  // Your custom logic can go here.
  // Modify the Cancel and Confirm variables as you wish,
  // then pass them to DeskMetrics as shown below.

  // Be sure to make this the LAST line of code in the procedure.
  DMACancelButtonClick(CurPageID, Cancel, Confirm)

procedure DeinitializeSetup();
  // This will trigger the automatic "install" event and then block until all pending events have finished sending.


In the InitializeUninstall function, load the DeskMetrics properties from the registry and start the SDK. Hook the CurUninstallStepChanged procedure to keep DeskMetrics informed, and then stop the SDK in the DeinitializeUninstall procedure.

function InitializeUninstall(): Boolean;
  // Load properties that were persisted to the registry by the installer.
  DMALoadProperties('HKCU\SOFTWARE\HelloDeskMetrics\_dm', false)

  // Initialize the analytics SDK and begin the session.
  Result := True

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
  // Tell the analytics SDK which step we're on.

procedure DeinitializeUninstall();
  // Deinitialize the analytics SDK.
  // This will trigger the automatic "uninstall" event and then block until all pending events have finished sending.

Custom events

The integration that we’ve done so far will immediately give you powerful analytics about your installs and uninstalls. But what if you want more? Here’s how we might go about firing a completely custom analytics event from within the installer.

// Not required!
// Just for fun, lets send a custom analytics event when we reach the 'installing' page.
procedure CurPageChanged(CurPageID: Integer);
  JsonObj: Integer;

  if CurPageID = wpInstalling then
    // This will allocate a new json event object.  The event will already have all of the
    // properties that DeskMetrics is capable of adding on its own.
    JsonObj := DMAJsonObjectNew()

    // Attach some custom fields of our own:
    DMAJsonObjectPushString(JsonObj, 'greeting', 'Hello DeskMetrics!')
    DMAJsonObjectPushInt(JsonObj, 'star_rating', 5)
    DMAJsonObjectPushBool(JsonObj, 'positive_sentiment', True)

    // Send the 'copying_files' event.
    // This event, like every other, will be passed through the OnSendEvent callback defined above,
    // so all of the recommended properties will be attached before it is sent.
    DMASendObject('copying_files', JsonObj)

    // Free the memory for the json object.
    // Every object allocated with DMANewBaseEventData must freed with DMAJsonObjectFree.


Custom domains

If you’ve set up a custom domain for use with the analytics SDK then you can set the SDK to use it with a call to the DMASetAnalyticsBaseUrl function before DMAStart:

// We've set up a domain to use for analytics - so we'll set it here:

// Proceed to start the SDK as usual

Please remember that DMASetAnalyticsBaseUrl should only be called before DMAStart. If DMASetAnalyticsBaseUrl is called after DMAStart then your events will not be sent using your custom domain.