1 Reply Latest reply: Jun 5, 2013 7:08 AM by 989211 RSS

    Registration key in installer

    989211
      I have built the installer for my Javafx application using the documentation. In the installer, I have also specified license where the user needs to confirm. And it works well.

      What I need to do now is that: There is a registration key for the application, which the user needs to put manually. How do I do that? Only if he successfully enters the key, should he be able to install it.
        • 1. Re: Registration key in installer
          989211
          I solved it by using Inno.

          Build the installer with verbose="true" in build.xml. For example on my computer, it looks like:

          <fx:deploy width="${javafx.run.width}" height="${javafx.run.height}"
          nativeBundles="all" verbose="true"
          outdir="${basedir}/${dist.dir}" outfile="Pina">

          On running it, it will generate some temporary files. On my computer, it can be seen at: C:\Users\Jatin\AppData\Local\Temp\build6069397957260201875.fxbundler\windows
          Copy the Pina.iss file and place it in "MyProject/package/windows" folder. Make "package" and "windows" folder if they dont exist.

          The below is my code contents of the Pina.iss file:
          function returnTrue(): Boolean;
          begin
            Result := True;
          end;
          
          function returnFalse(): Boolean;
          begin
            Result := False;
          end;
          
          function InitializeSetup(): Boolean;
          begin
          // Possible future improvements:
          //   if version less or same => just launch app
          //   if upgrade => check if same app is running and wait for it to exit
          //   Add pack200/unpack200 support? 
            Result := True;
          end; 
          
          function SetFocus(hWnd: HWND): HWND;
            external 'SetFocus@user32.dll stdcall';
          function OpenClipboard(hWndNewOwner: HWND): BOOL;
            external 'OpenClipboard@user32.dll stdcall';
          function GetClipboardData(uFormat: UINT): THandle;
            external 'GetClipboardData@user32.dll stdcall';
          function CloseClipboard: BOOL;
            external 'CloseClipboard@user32.dll stdcall';
          function GlobalLock(hMem: THandle): PAnsiChar;
            external 'GlobalLock@kernel32.dll stdcall';
          function GlobalUnlock(hMem: THandle): BOOL;
            external 'GlobalUnlock@kernel32.dll stdcall';
          
          var
            SerialPage: TWizardPage;
            SerialEdits: array of TEdit;
          
          const
            CF_TEXT = 1;
            VK_BACK = 8;
            SC_EDITCOUNT = 2;
            SC_CHARCOUNT = 5;
            First_Box = '50858';      //first key
            Second_Box = '28975';     //second key
          
          function GetClipboardText: string;
          var
            Data: THandle;
          begin
            Result := '';
            if OpenClipboard(0) then
            try
              Data := GetClipboardData(CF_TEXT);
              if Data <> 0 then
                Result := String(GlobalLock(Data));
            finally
              if Data <> 0 then
                GlobalUnlock(Data);
              CloseClipboard;
            end;
          end;
          
          function TryPasteSerialNumber: Boolean;
          var  
            S: string;
            I: Integer;
            J: Integer;
            Delimiter: string;
          begin
            Result := True;
            Delimiter := '-';
            S := GetClipboardText;    
            if Length(S) <> ((SC_EDITCOUNT * SC_CHARCOUNT) + 
              ((SC_EDITCOUNT - 1) * Length(Delimiter))) then
              Exit;    
            for I := 0 to GetArrayLength(SerialEdits) - 1 do
            begin
              J := (I * SC_CHARCOUNT) + (I * Length(Delimiter)) + 1;
              SerialEdits.Text := Copy(S, J, SC_CHARCOUNT);
          end;
          end;

          function GetSerialNumber(const ADelimiter: Char): string;
          var
          I: Integer;
          begin
          Result := '';
          for I := 0 to GetArrayLength(SerialEdits) - 1 do
          Result := Result + SerialEdits[I].Text + ADelimiter;
          Delete(Result, Length(Result), 1);
          end;

          procedure OnSerialEditChange(Sender: TObject);
          var
          I: Integer;
          CanContinue: Boolean;
          begin
          CanContinue := True;
          for I := 0 to GetArrayLength(SerialEdits) - 1 do
          if Length(SerialEdits[I].Text) < SC_CHARCOUNT then
          begin
          CanContinue := False;
          Break;
          end
          else
          begin
          if i= GetArrayLength(SerialEdits) - 1 then
          begin
          if (SerialEdits[0].Text = First_Box) and (SerialEdits[1].Text = Second_Box) then
          WizardForm.NextButton.Enabled := CanContinue;
          end;
          end;

          end;

          procedure OnSerialEditKeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
          var
          Edit: TEdit;
          EditIndex: Integer;
          begin
          Edit := TEdit(Sender);
          EditIndex := Edit.TabOrder - SerialEdits[0].TabOrder;
          if (EditIndex = 0) and (Key = Ord('V')) and (Shift = [ssCtrl]) then
          begin
          if TryPasteSerialNumber then
          Key := 0;
          end
          else
          if (Key >= 32) and (Key <= 255) then
          begin
          if Length(Edit.Text) = SC_CHARCOUNT - 1 then
          begin
          if EditIndex < GetArrayLength(SerialEdits) - 1 then
          SetFocus(SerialEdits[EditIndex + 1].Handle)
          else
          SetFocus(WizardForm.NextButton.Handle);
          end;
          end
          else
          if Key = VK_BACK then
          if (EditIndex > 0) and (Edit.Text = '') and (Edit.SelStart = 0) then
          SetFocus(SerialEdits[EditIndex - 1].Handle);
          end;

          procedure CreateSerialNumberPage;
          var
          I: Integer;
          Edit: TEdit;
          DescLabel: TLabel;
          EditWidth: Integer;
          begin
          SerialPage := CreateCustomPage(wpWelcome, 'Serial number validation',
          'Enter the valid serial number');

          DescLabel := TLabel.Create(SerialPage);
          DescLabel.Top := 16;
          DescLabel.Left := 0;
          DescLabel.Parent := SerialPage.Surface;
          DescLabel.Caption := 'Enter the valid serial number and continue with the installation...';
          DescLabel.Font.Style := [fsBold];

          SetArrayLength(SerialEdits, SC_EDITCOUNT);
          EditWidth := (SerialPage.SurfaceWidth - ((SC_EDITCOUNT - 1) * 8)) div SC_EDITCOUNT;

          for I := 0 to SC_EDITCOUNT - 1 do
          begin
          Edit := TEdit.Create(SerialPage);
          Edit.Top := 40;
          Edit.Left := I * (EditWidth + 8);
          Edit.Width := EditWidth;
          Edit.CharCase := ecUpperCase;
          Edit.MaxLength := SC_CHARCOUNT;
          Edit.Parent := SerialPage.Surface;
          Edit.OnChange := @OnSerialEditChange;
          Edit.OnKeyDown := @OnSerialEditKeyDown;
          SerialEdits[I] := Edit;
          end;
          end;

          procedure CurPageChanged(CurPageID: Integer);
          begin
          if CurPageID = SerialPage.ID then
          WizardForm.NextButton.Enabled := False;
          end;

          procedure InitializeWizard;
          begin
          CreateSerialNumberPage;
          end;


          Fore more info: http://stackoverflow.com/questions/10385319/custompage-for-serial-number-in-inno-setup