2

this is my code to enter a port number from user.upon installing i want to get the port number changed in apache tomcat server.xml file.

Iam passing apache tomcat zip file also using files section and unzip it in run section

var
javaVersion: String;
javaPath: String;

//port number code

function SetFocus(hWnd: HWND): HWND;
external 'SetFocus@user32.dll stdcall';

var
 SerialPage: TWizardPage;
  SerialEdits: array of TEdit;

const
 CF_TEXT = 1;
 VK_BACK = 8;
 SC_EDITCOUNT = 1;
 SC_CHARCOUNT = 4;


  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;
WizardForm.NextButton.Enabled := CanContinue;
 end;

 function GetSerialNumber(Param: String): string;
  var
  I: Integer;
  begin
  Result := '';
  for I := 0 to GetArrayLength(SerialEdits) - 1 do
  Result := Result + SerialEdits[I].Text ;
  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 ;

i want to replace the port number which was entered by user in tomcats server.xml using tokens

<Connector port="##portnumber##" protocol="HTTP/1.1"
connectionTimeout="20000"         
redirectPort="8443" />
user2689808
  • 35
  • 2
  • 9
  • Which encoding does your XML file use ? How complex is that XML file ? From where do you want to get the value for that `port` attribute value ? Your Pascal Script code looks quite irrelevant here... – TLama Jan 17 '14 at 10:21
  • user enters a port number and that port number should be raplaced in tomcat server.xml file – user2689808 Jan 17 '14 at 10:27
  • my requirement is user should enter a port number during installation and enterd port number should be replaced in server.xml file(apache tomcat) – user2689808 Jan 17 '14 at 10:28
  • Well, so then I would suggest you to use a real XML parser. In [`this example`](http://stackoverflow.com/a/15719374/960757) I've shown how to change attribute value of an XML attribute by using MSXML. But since you haven't show the path to the `Connector` element, I can't tell you how to call it... – TLama Jan 17 '14 at 10:58
  • Ok, so your question could be shortened to how to create one edit box for entering that port number. Then after you unpack the archive with the XML file you want to take the entered value and replace the `port` attribute value with it. No problem. We just need to know the structure of that XML (specifically the path to the `Connector` element). – TLama Jan 17 '14 at 13:30
  • I would, but it's your turn. Tell us the path to the `Connector` element in that XML. – TLama Jan 17 '14 at 14:36
  • ok i understood what you are asking.//Server/Service/Connector – user2689808 Jan 17 '14 at 14:49

1 Answers1

0

Here's a script I've made for you. I've changed the way of entering port number and shown how to modify attribute values in XML files. Also notice the usage of the AfterInstall function:

#define TomcatDest "{app}\tomcat"
#define TomcatFullPath TomcatDest + "\apache-tomcat-7.0.42"
#define TomcatSrvConfigFile TomcatFullPath + "\conf\server.xml"

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

[Files]
Source: "unzip.exe"; DestDir: "{tmp}\installertemps"
Source: "apache-tomcat-7.0.42.zip"; DestDir: "{tmp}\installertemps"

[Run]
Filename: "{tmp}\installertemps\unzip.exe"; Parameters: " ""{tmp}\installertemps\apache-tomcat-7.0.42.zip"" -d ""{#TomcatDest}"" "; AfterInstall: UpdateConfigFile(ExpandConstant('{#TomcatSrvConfigFile}'))

[Code]
const
  DefaultPort = 8080;
var
  ConfigPage: TInputQueryWizardPage;

procedure SaveAttrValueToXML(const FileName, NodePath, Attribute,
  Value: string);
var
  XMLNode: Variant;
  XMLDocument: Variant;
begin
  XMLDocument := CreateOleObject('Msxml2.DOMDocument');
  try
    XMLDocument.async := False;
    XMLDocument.load(FileName);
    if (XMLDocument.parseError.errorCode <> 0) then
      MsgBox('The XML file could not be parsed. ' +
        XMLDocument.parseError.reason, mbError, MB_OK)
    else
    begin
      XMLDocument.setProperty('SelectionLanguage', 'XPath');
      XMLNode := XMLDocument.selectSingleNode(NodePath);
      XMLNode.setAttribute(Attribute, Value);
      XMLDocument.save(FileName);
    end;
  except
    MsgBox('An error occured!' + #13#10 + GetExceptionMessage,
      mbError, MB_OK);
  end;
end;

procedure InitializeWizard;
begin
  ConfigPage := CreateInputQueryPage(wpSelectDir, 'Tomcat configuration',
    'Description', 'SubCaption');
  ConfigPage.Add('Port:', False);
  ConfigPage.Values[0] := IntToStr(DefaultPort);
end;

function NextButtonClick(CurPageID: Integer): Boolean;
var
  PortNumber: Integer;
begin
  Result := True;
  if CurPageID = ConfigPage.ID then
  begin
    PortNumber := StrToIntDef(ConfigPage.Values[0], -1);
    // modify the statement to allow users enter only valid port numbers;
    // currently the value of -1 means that there is not even a number entered
    // in the edit box
    if (PortNumber = -1) then
    begin
      Result := False;
      MsgBox('You''ve entered invalid port number. The setup cannot continue...', mbError, MB_OK);
    end;
  end;
end;

procedure UpdateConfigFile(const FileName: string);
begin
  SaveAttrValueToXML(FileName, '//Server/Service/Connector', 'port',
    ConfigPage.Values[0]);
end;
TLama
  • 75,147
  • 17
  • 214
  • 392
  • This script doesn't care about cleaning what it extracts from the archive. Doesn't care about checking if Tomcat is not already installed, etc. – TLama Jan 17 '14 at 16:05
  • thank you so much for spending your valuable time for this.please can you suggest any sites for learning inno setup coding. – user2689808 Jan 20 '14 at 05:26
  • You're welcome! About learning sites... There's not much of them, I think. One [`nice site`](http://www.mirality.co.nz/inno/tips.php) was written by [`Miral`](http://stackoverflow.com/users/43534/miral). – TLama Jan 20 '14 at 12:45