Search code examples
windowsinstallationinno-setuplicensing

Inno Setup - How to validate serial number online


Using Inno Setup, setup.exe was given to a client, according to contract he is allowed only to use 2016 and 2017. But on 01-01-2018 he should not be able to continue with same serial 2017.

How to make the setup.exe by innosetup limited to from and to date?

[Setup]
#define SerialNumber "2017"
UserInfoPage=yes

[Code]
function CheckSerial(Serial: String): Boolean;
begin
  Result := Serial = '{#SerialNumber}';
end;
  • setup.exe is executed
  • license key is inserted
  • after submit, i want to check URL https://www.example.com/query/license?id=2017
  • if the result is ok or nok based on that the installation continue

Solution

  • Starting with a code from: Inno Setup - HTTP request - Get www/web content, you will get something like:

    [Setup]
    UserInfoPage=yes 
    
    [Code]
    
    // Presence of the CheckSerial event function displays the serial number box.
    // But here we accept any non-empty serial.
    // We will validate it only in the NextButtonClick,
    // as the online validation can take long.
    function CheckSerial(Serial: String): Boolean;
    begin
      Result := (Serial <> '');
    end;
    
    function NextButtonClick(CurPageID: Integer): Boolean;
    var
      WinHttpReq: Variant;
      Url: string;
    begin
      Result := True;
      if CurPageID = wpUserInfo then
      begin
        WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
        Url := 'https://www.example.com/serial.php?serial=' +
               WizardForm.UserInfoSerialEdit.Text;
        WinHttpReq.Open('GET', Url, False);
        WinHttpReq.Send('');
        // Depending on implementation of the server,
        // use either HTTP status code (.Status)
        // or contents of returned "page" (.ResponseText)
        // Here we use the HTTP status code:
        // 200 = serial is valid, anything else = serial is invalid,
        // and when invalid, we display .ResponseText
        Result := (WinHttpReq.Status = 200);
        if not Result then
          MsgBox(WinHttpReq.ResponseText, mbError, MB_OK);
      end;
    end;
    

    A simple server-side validation PHP script (serial.php) would be like:

    <?
    
    if (empty($_REQUEST["serial"]) || ($_REQUEST["serial"] != "2017"))
    {
        header("HTTP/1.0 401 The serial number is not valid");
        // error message to be displayed in installer
        echo "The serial number is not valid";
    }
    

    enter image description here


    For consideration:

    • This validation is not difficult to bypass, i.e. using a proxy server.
    • It also does not prevent the user from extracting the files from the installer and installing them manually.
    • You may consider instead an on-line download of the actual files only after validating the serial number.
    • Or downloading some license file that the application will require for functioning. You need that anyway, if you want to enforce the application to stop working once the license expires.
    • Or you can also encrypt the installer and make the online service return the decryption password:
      Read Inno Setup encryption key from Internet instead of password box

    For a similar question, see also
    How to store serial numbers in a Sharepoint List, for to call from Inno Setup and verify if is autorized user?