title: Unknown identifier and wpSelectDir
body: <p>I have an error that's occuring during the compliation of my Inno Setup script.</p>
  
  <blockquote>
    <p>Unknown identifier 'PathOfDir2'</p>
  </blockquote>
  
  <p>I know I can set <code>var PathOfDir2: String;</code> but i don't know where and if it will receive the value from my <code>wpSelectDir</code>.</p>
  
  <p>Dooes anyone know what's going wrong?</p>
  
  <pre><code>[code]
  // Variables Globales
  var
      TimeZone: String;
      type
          SERVICE_STATUS = record
              dwServiceType               : cardinal;
              dwCurrentState              : cardinal;
              dwControlsAccepted          : cardinal;
              dwWin32ExitCode             : cardinal;
              dwServiceSpecificExitCode   : cardinal;
              dwCheckPoint                : cardinal;
              dwWaitHint                  : cardinal;
      end;
      HANDLE = cardinal;
  
  const
      SERVICE_QUERY_CONFIG        = $1;
      SERVICE_CHANGE_CONFIG       = $2;
      SERVICE_QUERY_STATUS        = $4;
      SERVICE_START               = $10;
      SERVICE_STOP                = $20;
      SERVICE_ALL_ACCESS          = $f01ff;
      SC_MANAGER_ALL_ACCESS       = $f003f;
      SERVICE_WIN32_OWN_PROCESS   = $10;
      SERVICE_WIN32_SHARE_PROCESS = $20;
      SERVICE_WIN32               = $30;
      SERVICE_INTERACTIVE_PROCESS = $100;
      SERVICE_BOOT_START          = $0;
      SERVICE_SYSTEM_START        = $1;
      SERVICE_AUTO_START          = $2;
      SERVICE_DEMAND_START        = $3;
      SERVICE_DISABLED            = $4;
      SERVICE_DELETE              = $10000;
      SERVICE_CONTROL_STOP        = $1;
      SERVICE_CONTROL_PAUSE       = $2;
      SERVICE_CONTROL_CONTINUE    = $3;
      SERVICE_CONTROL_INTERROGATE = $4;
      SERVICE_STOPPED             = $1;
      SERVICE_START_PENDING       = $2;
      SERVICE_STOP_PENDING        = $3;
      SERVICE_RUNNING             = $4;
      SERVICE_CONTINUE_PENDING    = $5;
      SERVICE_PAUSE_PENDING       = $6;
      SERVICE_PAUSED              = $7;
  
  // #######################################################################################
  // nt based service utilities
  // #######################################################################################
  
  function OpenSCManager(lpMachineName, lpDatabaseName: string; dwDesiredAccess :cardinal): HANDLE;
  external 'OpenSCManagerA@advapi32.dll stdcall';
  
  function OpenService(hSCManager :HANDLE;lpServiceName: string; dwDesiredAccess :cardinal): HANDLE;
  external 'OpenServiceA@advapi32.dll stdcall';
  
  function CloseServiceHandle(hSCObject :HANDLE): boolean;
  external 'CloseServiceHandle@advapi32.dll stdcall';
  
  function CreateService(hSCManager :HANDLE;lpServiceName, lpDisplayName: string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl: cardinal;lpBinaryPathName,lpLoadOrderGroup: String; lpdwTagId : cardinal;lpDependencies,lpServiceStartName,lpPassword :string): cardinal;
  external 'CreateServiceA@advapi32.dll stdcall';
  
  function DeleteService(hService :HANDLE): boolean;
  external 'DeleteService@advapi32.dll stdcall';
  
  function StartNTService(hService :HANDLE;dwNumServiceArgs : cardinal;lpServiceArgVectors : cardinal) : boolean;
  external 'StartServiceA@advapi32.dll stdcall';
  
  function ControlService(hService :HANDLE; dwControl :cardinal;var ServiceStatus :SERVICE_STATUS) : boolean;
  external 'ControlService@advapi32.dll stdcall';
  
  function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean;
  external 'QueryServiceStatus@advapi32.dll stdcall';
  
  function QueryServiceStatusEx(hService :HANDLE;ServiceStatus :SERVICE_STATUS) : boolean;
  external 'QueryServiceStatus@advapi32.dll stdcall';
  
  function OpenServiceManager() : HANDLE;
  begin
      if UsingWinNT() = true then
      begin
          Result := OpenSCManager('','ServicesActive',SC_MANAGER_ALL_ACCESS);
          if Result = 0 then
              MsgBox('the servicemanager is not available', mbError, MB_OK)
      end
      else
      begin
          MsgBox('only nt based systems support services', mbError, MB_OK)
          Result := 0;
      end
  end;
  
  function IsServiceInstalled(ServiceName: string) : boolean;
  var
      hSCM    : HANDLE;
      hService: HANDLE;
  begin
      hSCM := OpenServiceManager();
      Result := false;
      if hSCM &lt;&gt; 0 then begin
          hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_CONFIG);
          if hService &lt;&gt; 0 then begin
              Result := true;
              CloseServiceHandle(hService)
          end;
          CloseServiceHandle(hSCM)
      end
  end;
  
  function InstallService(FileName, ServiceName, DisplayName, Description : string;ServiceType,StartType :cardinal) : boolean;
  var
      hSCM    : HANDLE;
      hService: HANDLE;
  begin
      hSCM := OpenServiceManager();
      Result := false;
      if hSCM &lt;&gt; 0 then begin
          hService := CreateService(hSCM,ServiceName,DisplayName,SERVICE_ALL_ACCESS,ServiceType,StartType,0,FileName,'',0,'','','');
          if hService &lt;&gt; 0 then begin
              Result := true;
              // Win2K &amp; WinXP supports aditional description text for services
              if Description&lt;&gt; '' then
                  RegWriteStringValue(HKLM,'System\CurrentControlSet\Services' + ServiceName,'Description',Description);
              CloseServiceHandle(hService)
          end;
          CloseServiceHandle(hSCM)
      end
  end;
  
  function RemoveService(ServiceName: string) : boolean;
  var
      hSCM    : HANDLE;
      hService: HANDLE;
  begin
      hSCM := OpenServiceManager();
      Result := false;
      if hSCM &lt;&gt; 0 then begin
          hService := OpenService(hSCM,ServiceName,SERVICE_DELETE);
          if hService &lt;&gt; 0 then begin
              Result := DeleteService(hService);
              CloseServiceHandle(hService)
          end;
          CloseServiceHandle(hSCM)
      end
  end;
  
  function StartService(ServiceName: string) : boolean;
  var
      hSCM    : HANDLE;
      hService: HANDLE;
  begin
      hSCM := OpenServiceManager();
      Result := false;
      if hSCM &lt;&gt; 0 then begin
          hService := OpenService(hSCM,ServiceName,SERVICE_START);
          if hService &lt;&gt; 0 then begin
              Result := StartNTService(hService,0,0);
              CloseServiceHandle(hService)
          end;
          CloseServiceHandle(hSCM)
      end;
  end;
  
  function StopService(ServiceName: string) : boolean;
  var
      hSCM    : HANDLE;
      hService: HANDLE;
      Status  : SERVICE_STATUS;
  begin
      hSCM := OpenServiceManager();
      Result := false;
      if hSCM &lt;&gt; 0 then begin
          hService := OpenService(hSCM,ServiceName,SERVICE_STOP);
          if hService &lt;&gt; 0 then begin
              Result := ControlService(hService,SERVICE_CONTROL_STOP,Status);
              CloseServiceHandle(hService)
          end;
          CloseServiceHandle(hSCM)
      end;
  end;
  
  function IsServiceRunning(ServiceName: string) : boolean;
  var
      hSCM    : HANDLE;
      hService: HANDLE;
      Status  : SERVICE_STATUS;
  begin
      hSCM := OpenServiceManager();
      Result := false;
      if hSCM &lt;&gt; 0 then begin
          hService := OpenService(hSCM,ServiceName,SERVICE_QUERY_STATUS);
          if hService &lt;&gt; 0 then begin
              if QueryServiceStatus(hService,Status) then begin
                  Result :=(Status.dwCurrentState = SERVICE_RUNNING)
              end;
              CloseServiceHandle(hService)
              end;
          CloseServiceHandle(hSCM)
      end
  end;
  
  // #######################################################################################
  // create an entry in the services file
  // #######################################################################################
  function SetupService(service, port, comment: string) : boolean;
  var
      filename    : string;
      s           : string;
      lines       : TArrayOfString;
      n           : longint;
      i           : longint;
      errcode     : integer;
      servnamlen  : integer;
      error       : boolean;
  begin
      if UsingWinNT() = true then
          filename := ExpandConstant('{sys}\drivers\etc\services')
      else
          filename := ExpandConstant('{win}\services');
  
      if LoadStringsFromFile(filename,lines) = true then begin
          Result      := true;
          n           := GetArrayLength(lines) - 1;
          servnamlen  := Length(service);
          error       := false;
  
          for i:=0 to n do begin
              if Copy(lines[i],1,1) &lt;&gt; '#' then begin
                  s := Copy(lines[i],1,servnamlen);
                  if CompareText(s,service) = 0 then
                      exit; // found service-entry
  
                  if Pos(port,lines[i]) &gt; 0 then begin
                      error := true;
                      lines[i] := '#' + lines[i] + '   # disabled because collision with  ' + service + ' service';
                  end;
              end
              else if CompareText(Copy(lines[i],2,servnamlen),service) = 0 then begin
                  // service-entry was disabled
                  Delete(lines[i],1,1);
                  Result := SaveStringsToFile(filename,lines,false);
                  exit;
              end;
          end;
  
          if error = true then begin
              // save disabled entries
              if SaveStringsToFile(filename,lines,false) = false then begin
                  Result := false;
                  exit;
              end;
          end;
  
          // create new service entry
          s := service + '       ' + port + '           # ' + comment + #13#10;
          if SaveStringToFile(filename,s,true) = false then begin
              Result := false;
              exit;
          end;
  
          if error = true then begin
              MsgBox('the ' + service + ' port was already used. The old service is disabled now. You should check the services file manually now.',mbInformation,MB_OK);
              //InstExec('notepad.exe',filename,GetCurrentDir(),true,false,SW_SHOWNORMAL,errcode);
          end;
      end
      else
          Result := false;
  end;
  
  // #######################################################################################
  // version functions
  // #######################################################################################
  function CheckVersion(Filename : string;hh,hl,lh,ll : integer) : boolean;
  var
      VersionMS   : cardinal;
      VersionLS   : cardinal;
      CheckMS     : cardinal;
      CheckLS     : cardinal;
  begin
      if GetVersionNumbers(Filename,VersionMS,VersionLS) = false then
          Result := false
      else begin
          CheckMS := (hh shl $10) or hl;
          CheckLS := (lh shl $10) or ll;
          Result := (VersionMS &gt; CheckMS) or ((VersionMS = CheckMS) and (VersionLS &gt;= CheckLS));
      end;
  end;
  
  // Some examples for version checking
  function NeedShellFolderUpdate() : boolean;
  begin
      Result := CheckVersion('ShFolder.dll',5,50,4027,300) = false;
  end;
  
  function NeedVCRedistUpdate() : boolean;
  begin
      Result := (CheckVersion('mfc42.dll',6,0,8665,0) = false)
          or (CheckVersion('msvcrt.dll',6,0,8797,0) = false)
          or (CheckVersion('comctl32.dll',5,80,2614,3600) = false);
  end;
  
  function NeedHTMLHelpUpdate() : boolean;
  begin
      Result := CheckVersion('hh.exe',4,72,0,0) = false;
  end;
  
  function NeedWinsockUpdate() : boolean;
  begin
      Result := (UsingWinNT() = false) and (CheckVersion('mswsock.dll',4,10,0,1656) = false);
  end;
  
  function NeedDCOMUpdate() : boolean;
  begin
      Result := (UsingWinNT() = false) and (CheckVersion('oleaut32.dll',2,30,0,0) = false);
  end;
  
  // #######################################################################################
  // Replace substring in a string functions
  // #######################################################################################
  procedure FileReplace(SrcFile, sFrom, sTo: String);
  var
      FileContent: String;
  begin
      //Load srcfile to a string
      LoadStringFromFile(SrcFile, FileContent);
      //Replace Fraomstring by toString in file string content
      StringChange (sTo,'/', '\');
      StringChange (FileContent, sFrom, sTo);
      //Replace old content srcfile by the new content
      DeleteFile(SrcFile);
      SaveStringToFile(SrcFile,FileContent, True);
  end;
  
  // #######################################################################################
  // Replace in file functions
  // #######################################################################################
  procedure FileWrite(SrcFile, sFrom, sTo: String);
  var
      FileContent: String;
  begin
      //Load srcfile to a string
      LoadStringFromFile(SrcFile, FileContent);
      //Replace Fraomstring by toString in file string content
      //StringChange (sTo,'/', '\');
      StringChange (FileContent, sFrom, sTo);
      //Replace old content srcfile by the new content
      DeleteFile(SrcFile);
      SaveStringToFile(SrcFile,FileContent, True);
  end;
  
  // #######################################################################################
  // Custumized page for apache config
  // #######################################################################################
  procedure CreateTheWizardPages;
  // variables locales
  var
      Lbl: TLabel;
      Page: TWizardPage;
      Edit: TEdit;
      PortNbr: String;
  // boites
  begin
      Page := CreateCustomPage(wpSelectComponents, 'Apache configuration', 'Please enter your parameter for the apache server (Default is 80)');
      Lbl := TLabel.Create(Page);
      Lbl.Top := ScaleY(11);
      Lbl.Caption := 'Apache server port :';
      Lbl.AutoSize := True;
      Lbl.Parent := Page.Surface;
  
      Edit := TEdit.Create(Page);
      Edit.Top := ScaleY(8);
      Edit.Left := Lbl.Left + ScaleX(70);
      Edit.Width := Page.SurfaceWidth div 2 - ScaleX(8);
      Edit.Text := PortNbr;
      Edit.Text := '80';
      Edit.Parent := Page.Surface;
  end;
  
  // #######################################################################################
  // Custumized page for Password enter
  // #######################################################################################
  procedure CreateTheWizardPagesPwd;
  // variables locales
  var
      PasWd: TLabel;
      PagePwd: TWizardPage;
      EditPw: TEdit;
      //MailHostName: String;
  // boites
  begin
      PagePwd := CreateCustomPage(wpSelectComponents, 'Password for the data base user', 'Please enter the password for the data base');
      PasWd := TLabel.Create(PagePwd);
      PasWd.Top := ScaleY(11);
      PasWd.Caption := 'PassWord : ';
      PasWd.AutoSize := True;
      PasWd.Parent := PagePwd.Surface;
  
      EditPw := TEdit.Create(PagePwd);
      EditPw.Top := ScaleY(8);
      EditPw.Left := PasWd.Left + ScaleX(70);
      EditPw.Width := PagePwd.SurfaceWidth div 2 - ScaleX(8);
      EditPw.Parent := PagePwd.Surface;
  end;
  
  // #######################################################################################
  // Custumized page for Enter the path of the backup file
  // #######################################################################################
  procedure CreateTheWizardPagesBkpDir;
  var
      PageBkpDir: TInputDirWizardPage;
  // boites
  begin
      PageBkpDir := CreateInputDirPage(wpSelectDir,'Select Backup Data Directory','Where should Backup data files be installed?','Select the folder in which Setup should copy backup data files, then click Next.', False, '');
      PageBkpDir.Add('');
      PageBkpDir.Values[0] := ExpandConstant('{userdesktop}\dbBackup');
  end;
  
  // #######################################################################################
  // Custumized page for Time zone enter
  // #######################################################################################
  procedure CreateTheWizardPagesTimeZone;
  // variables locales
  var
      Panel: TPanel;
      PageTimeZone: TWizardPage;
      ListBTimeZone: TNewListBox;
  // boites
  begin
      PageTimeZone := CreateCustomPage(wpWelcome, 'Time zone of your location', 'Please choose your time zone');
      Panel := TPanel.Create(PageTimeZone);
      Panel.Width := PageTimeZone.SurfaceWidth div 2 - ScaleX(8);
      Panel.Left :=  PageTimeZone.SurfaceWidth - Panel.Width;
      Panel.Caption := 'TPanel';
      Panel.Color := clWindow;
      Panel.ParentBackground := False;
      Panel.Parent := PageTimeZone.Surface;
  
      ListBTimeZone := TNewListBox.Create(PageTimeZone);
      ListBTimeZone.Width := PageTimeZone.SurfaceWidth;
      ListBTimeZone.Height := ScaleY(200);
      ListBTimeZone.Parent := PageTimeZone.Surface;
      ListBTimeZone.Items.Add('Etc/UTC');
      ListBTimeZone.Items.Add('Europe/Paris');
      ListBTimeZone.ItemIndex := 2;
  end;
  
  // Initialisation
  procedure InitializeWizard();
  begin
      CreateTheWizardPages;
      CreateTheWizardPagesTimeZone;
      CreateTheWizardPagesPwd;
      CreateTheWizardPagesBkpDir;
  end;
  
  // #######################################################################################
  // Function to stop and delete de service by uninstallation procedur
  // #######################################################################################
  procedure CurUninstallStepChanged(CurStep: TUninstallStep);
  var
      ErrorCode: Integer;
  begin
      if CurStep = usUninstall then
      begin
          //Uninstall process
          ShellExec('open','taskkill.exe','/f /im MyApplicationService.exe','',SW_HIDE,ewNoWait,ErrorCode);
          ShellExec('open','taskkill.exe','/f /im httpd.exe','',SW_HIDE,ewNoWait,ErrorCode);
          ShellExec('open','taskkill.exe','/f /im mysqld.exe','',SW_HIDE,ewNoWait,ErrorCode);
  
          // stop all affected services
          StopService('MyApplicationService');
          StopService('MySqld');
          StopService('Apache');
  
          // remove all affected services
          RemoveService('MyApplicationService');
          RemoveService('MySqld');
          RemoveService('Apache');
      end;
  end;
  
  // #######################################################################################
  // Function to check and replace the string in the file at the end of the installation
  // #######################################################################################
  procedure CurStepChanged(CurStep: TSetupStep);
  var
      ErrorCode: Integer;
      WorkingDir:   String;
      PathOfDir: String;
  begin
      //juste aprés installation
      if CurStep = ssPostInstall then
      begin
          PathOfDir := GetShortName(PathOfDir2);
          FileReplace(ExpandConstant('{app}\create_db.sql'), '@@Pwd@@', EditPw.Text);
  
          FileReplace(ExpandConstant('{app}\webserver\bin\apache\Apache2.2.22\conf\httpd.conf'), '@@Port@@', PortNbr);
          FileReplace(ExpandConstant('{app}\webserver\bin\apache\Apache2.2.22\conf\httpd.conf'), '@@Path@@', PathOfDir+'\webserver');
          FileReplace(ExpandConstant('{app}\webserver\bin\apache\Apache2.2.22\bin\php.ini'), '@@Path@@', PathOfDir+'\webserver');
          FileWrite(ExpandConstant('{app}\webserver\bin\apache\Apache2.2.22\bin\php.ini'), '@@TimeZone@@', TimeZone);
  
          FileReplace(ExpandConstant('{app}\webserver\bin\mysql\mysql5.5.24\my.ini'), '@@Path@@', PathOfDir+'\webserver');
          FileReplace(ExpandConstant('{app}\webserver\bin\mysql\mysql5.5.24\bin\dbexport.bat'), '@@Path@@', PathOfBackupDir);
          FileReplace(ExpandConstant('{app}\webserver\bin\mysql\mysql5.5.24\bin\create_db.bat'), '@@Path@@', PathOfDir + '\webserver\bin\mysql\mysql5.5.24');
          FileReplace(ExpandConstant('{app}\webserver\bin\mysql\mysql5.5.24\bin\create_db.bat'), '@@PathOfDir@@', PathOfDir);
  
          FileReplace(ExpandConstant('{app}\webserver\bin\php\php5.4.3\php.ini'), '@@Path@@', PathOfDir+'\webserver');
          FileReplace(ExpandConstant('{app}\webserver\bin\php\php5.4.3\phpForApache.ini'), '@@Path@@', PathOfDir+'\webserver');
  
          if InstallService(ExpandConstant('"{app}\webserver\bin\mysql\mysql5.5.24\bin\mysqld.exe" MySqld'),'MySqld','MySqld','The mysql service',SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START) = true then
          begin
              StartService('MySqld');
              Sleep(8000);
          end
          else
              MsgBox('MySqld service could not be installed',mbInformation, MB_OK);
  
          if InstallService(ExpandConstant('"{app}\webserver\bin\apache\apache2.2.22\bin\httpd.exe" -k runservice'),'Apache','Apache','The apache service',SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START) = true then
          begin
              StartService('Apache');
              Sleep(5000);
          end
          else
              MsgBox('Apache service could not be installed',mbInformation, MB_OK);
  
          if InstallService(ExpandConstant('"{app}\MyApplicationService.exe"'),'MyApplicationService','MyApplicationService','The server',SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START) = true then
          begin
              StartService('MyApplicationService');
              Sleep(5000);
          end
          else
              MsgBox('The MyApplicationService service could not be installed',mbInformation, MB_OK);
  
      end;
  
      if CurStep = ssInstall then
      begin
          //Uninstall process
          ShellExec('open','taskkill.exe','/f /im MyApplicationService.exe','',SW_HIDE,ewNoWait,ErrorCode);
          ShellExec('open','taskkill.exe','/f /im httpd.exe','',SW_HIDE,ewNoWait,ErrorCode);
          ShellExec('open','taskkill.exe','/f /im mysqld.exe','',SW_HIDE,ewNoWait,ErrorCode);
  
          // stop all affected services
          StopService('MyApplicationService');
          StopService('MySqld');
          StopService('Apache');  
  
          // remove all affected services
          RemoveService('MyApplicationService');
          RemoveService('MySqld');
          RemoveService('Apache');
      end;
  
      if CurStep = ssDone then
      begin
          Exec(ExpandConstant('{app}\webserver\bin\mysql\mysql5.5.24\bin\create_db.bat'),'','', SW_SHOW, ewWaitUntilTerminated, ErrorCode);
      end;
  end;
  
  // #######################################################################################
  // Function to check the values entered
  // #######################################################################################
  function NextButtonClick(CurPageID: Integer): Boolean;
  var
      ErrorCode: Integer;
  begin
      Result := True;
      case CurPageID of
          Page.ID:
          begin
              if (Edit.Text = '') then
              begin
                  MsgBox('Port number check:'#13#13 'The port number is empty. The default port &lt;&lt; 80 &gt;&gt; will be applied. Please click on the back button to change if needed ', mbError, MB_OK);
                  Edit.Text := '80';
              end
              else
              begin
                  Result := True;
                  PortNbr := Edit.Text;
              end
          end;
          //End page.id
  
          PagesEmailSt.ID:
          begin
              if (EditPwd.Text = EditPwd2.Text) then
              begin
                  MailHostName := EditMailHostName.Text;
                  MailUserName := EditUserName.Text;
                  MailPwd := EditPwd.Text;
                  MailFrom := EditFromMail.Text;
                  MailSmtpPort := EditSmtpPort.Text;
              end
              else
              begin
                  MsgBox('Password check:'#13#13 'The password entered is not the same. Please click on back and check ', mbError, MB_OK);
                  Result := false;
              end
          end;
          //End PagesEmailSt.id
  
          //Time zone add beginn
          PageTimeZone.ID:
          begin
              Result := false;
              TimeZone := ListBTimeZone.Items.Strings[ListBTimeZone.ItemIndex];
          end;
          //End time zone add
  
          //Beginn dir selector
          PageBkpDir.ID:
          begin
              //PageBkpDir.Values[0] := ExpandConstant('{userdesktop}\dbBackup');
              PathOfBackupDir := PageBkpDir.Values[0];
          end;
  
          wpSelectDir:
          begin
              PathOfDir2 := WizardDirValue;
              //MsgBox('NextButtonClick:' #13#13 'You selected: ''' + PathOfDir + '''.', mbInformation, MB_OK);
          end;
          //End dir selector
      end; //End case
      Result := True;
  end;
  
  function GetDataDir(Param: String): String;
  begin
      //Return the selected DataDir
      Result := PageBkpDir.Values[0];
  end;
  </code></pre>