I recently posted about symbolic links available in Windows 7. There I mentioned about how I used it to install PowerBuilder side by side. In this post I will explain the setup and the scripts I used to achieve complete isolation of the 2 PB versions.
When you install PowerBuilder, it normally installs a bunch of EXE and DLL files that are version specific. For e.g., executable for PowerBuilder 10.x is PB100.exe, while it is PB125.exe for PB 12.5. And then there are bunch of DLLs named PB*100.DLL for PB 10.x and PB*125.DLL in PB 12.5. So, really for most part they don’t overlap. And PowerBuilder does install in separate directories. For e.g., we have,
We normally install our PB in C:\Sybase instead of C:\Program Files\Sybase, to avoid problems we faced with path with embedded space.
There ends the isolation. When you install PB, it also creates a shared folder (C:\Sybase\Shared), where it creates a folder named PowerBuilder. This gets overwritten with each new version. Luckily, a lot of PB DLLs have version embedded in them as mentioned above. But, this folder contains other shared DLLs that may be overwritten also.
To be able to keep the current PB 10 environment pristine, while adding on PB 12.5, thus was a challenge. We didn’t want to corrupt PB 10 environment in any way. If only, we can have 2 separate directories. PB needs the shared directory called PowerBuilder.
The other challenge we had was EAServer. We wanted to keep the Repository clearly separate for PB 10 code and PB 12.5 code we deploy. Again, Sybase requires the directory to be called “Repository” no matter what version. There was suggestion to replicate EAServer folder for each separate instance, but it felt like a criminal waste to replicate a huge directory like EAServer.
So, I started looking around for solution. If only I can 2 directories, one for each version of PB, and make it appear as the only (required) directory to PowerBuilder, problem solved. I tried to renaming directories each time I switch. While this worked, it took some time to rename directory. Plus you are messing with the original directory and may end up trashing it, by mistake.
I thought, I could do this with links on Unix and if only Windows offered this. This is when I found out that it did!! Windows 7 (actually Vista had it too) has a command (mklink) to create Symbolic Links! Problem solved.
So, I installed PowerBuider 10.2 and EAS 5.5 first to C:\Sybase. Renamed the offending directories (C:\Sybase\Shared\PowerBuilder) to PowerBuilder_10. Also, created 2 repositories in EAServer – Repository_10 and Repository_125, initially with the same (PB 10.2) content. Now, installed PowerBuilder 12.5, which again created another C:\Sybase\PowerBuilder folder. Renamed this to PowerBuilder_125. I created the symbolic links at this point to point to the right set of directories, bingo, I was able to switch between 2 versions of PB.
One another challenge was the path to PowerBuilder 10.0 or PowerBuilder 12.5 directories. I could have added both of them to PATH environment variable, thus both versions could be run simultaneously. But this could pose a major problem – which repository will be currently active in EAServer – PB 10 version or the 12.5 version? Not all developers were working on PB 12.5 yet, so we have to let them continue using PB 10.2 and when the time comes, they should be able to switch. Also, some developers may be supporting both the versions until PB 12.5 goes live. So, I decided to change the path to the user path and change it on the fly depending on the version developer chose. To adjust the PATH variable easily, I found a utility called PATHED. This lets you edit system path easily from command line. I also found a windows command, SETX to update System environment variables. (SET only applies to current shell you are in).
I put all these in a batch file. Pass the version # to the batch file, you got the environment switched to the corresponding PB version completely.
: -------------------------------------------------------------------------- :: Script: switch_to_pbver.bat :: Project: Win7/Powerbuilder 12.x Upgrade project :: Author: SamV :: Date: 10/08/2013 :: Purpose: Switches path and Sybase dir (Repository, Shared\Powerbuilder) :: to point to PB 10. :: Usage: switch_to_pbver For e.g., switch_to_pbver 10 :: You can create windows shortcut for each version. :: -------------------------------------------------------------------------- @SETLOCAL @ECHO OFF</code> :: This section is common to both normal and elevated levelos :: This will be executed twice, one as normal user :: then again in Admin mode when this script is reloaded by below script. :: You need to pass in the PB version to switch to IF "%1" == "" ( @ECHO Please pass in the version number to switch to - 10, 125 or 15. PAUSE Goto ExitOut ) tasklist /nh /fi "imagename eq jagsrv.exe" | find /i "jagsrv.exe" >nul && ( REM echo EA Server is running. You need to Stop EA Server before switching to another version of PB. CALL :printBright EA Server is running. You need to Stop EA Server before switching to another version of PB. PAUSE GOTO exitOut )|| ( REM Echo EA Server is not running ) tasklist /nh /fi "imagename eq pb*" | findstr /i "pb...\.exe" >nul && ( CALL :printBright Some version of Powerbuilder seems to be running. Please close it, before switching. PAUSE GOTO exitOut )|| ( REM Echo EA Server is not running ) subst /d Z: subst Z: C:\LA_SOURCE_%1 ::::::::::::::::::::::::::::::::::::::::: :: Automatically check & get admin rights ::::::::::::::::::::::::::::::::::::::::: :checkPrivileges NET FILE 1>NUL 2>NUL if '%errorlevel%' == '0' ( goto elevated) else ( goto elevateSelf ) :elevateSelf :: remove the ELEV parameter and goto run script in admin mode. if '%1'=='ELEV' (goto elevated) @ECHO. @ECHO ************************************** @ECHO Invoking UAC for Privilege Escalation @ECHO ************************************** REM create a VBScript that runs this script in elevated mode. setlocal DisableDelayedExpansion set "batchPath=%~0" setlocal EnableDelayedExpansion @ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\elevateSelf.vbs" @ECHO UAC.ShellExecute "!batchPath!", "%1 ELEV", "", "runas", 1 >> "%temp%\elevateSelf.vbs" "%temp%\elevateSelf.vbs" //nologo exit /B :elevated :: End of self-elevation script :: If we are here, then this script has already self-elevated itself. :::::::::::::::::::::::::::: :START :::::::::::::::::::::::::::: PUSHD . REM add an env variable with PB version #; SET is used to show in current shell, REM as SETX update won't be visible until you open a new shell. SET PBVER=%1 SET NEW_PBDIR="" IF "%PBVER%" == "10" ( SET NEW_PBDIR="c:\sybase\PowerBuilder 10.0" ) IF "%PBVER%" == "15" ( SET NEW_PBDIR="c:\sybase\PowerBuilder 15.0" ) IF "%PBVER%" == "125" ( SET NEW_PBDIR="c:\sybase\PowerBuilder 12.5" ) SETX PBVER %PBVER% REM remove the Symlink @ECHO adjusting links to Repository and PowerBuilder folders for the version PUSHD . CD C:\Sybase\shared rmdir Powerbuilder mklink /D Powerbuilder Powerbuilder_%PBVER% POPD PUSHD . CD C:\Sybase\EAServer rmdir Repository mklink /D Repository Repository_%PBVER% POPD @ECHO User Path is adjusted for PB %PBVER% pathed /user /remove "c:\sybase\PowerBuilder 12.5" pathed /user /remove "c:\sybase\PowerBuilder 10.0" pathed /user /remove "c:\sybase\PowerBuilder 15.0" REM pathed /user /slim /remove %OLDPBDIR% /append %NEW_PBDIR% pathed /user /slim /append %NEW_PBDIR% CLS @ECHO. @ECHO. CALL :printBright Here is the Summary @ECHO. CALL :printBright PB Version = %PBVER% dir /b C:\Sybase\EAServer\Repository\THIS* dir /b C:\Sybase\Shared\Powerbuilder\THIS* subst | findstr /I /C:z: @ECHO. @ECHO. @ECHO. CALL :printBright User Path is adjusted for PB %PBVER% pathed /user | findstr /v /I PATHED | findstr /v /I Freeware @ECHO. @ECHO. @ECHO. PAUSE GOTO exitOut :printBright powershell -Command echo Powershell | find /i "Powershell" >nul && ( powershell -Command Write-Host "%*" -foreground "Yellow" ) || ( @echo %* ) goto:eof EXITOUT EXIT
The script encompasses various gems I found on the internet. First, I used tasklist to check if PowerBuilder or EAServer (Jaguar) are running. If so, I tell the user to close it first. We don’t want to run 2 versions simultaneously, even accidentally.
Then comes the checking the privilege part. On Windows 7×64, you need to use “RunasAdministrator” option to be able to run commands that affect the system. In this case, SETX and PATHED affect system environment variables, so we need to run as administrator. Even mklink command needs you to run as Administrator.
A note about “Run As Administrator option: This is like sudo on Unix. Even if you are logged with Administrative rights, you will have to run a program with “RunAsAdministrator” option. Otherwise, program will run in normal mode and thus won’t have admin rights. To do this on command line, I use a utility called Elevate. But, since this whole script needs to be run as Administrator, I didn’t want to elevate each command. Instead, I picked up a scriptlet that self elevates the current batch file.
Once I am in admin mode, then I do the actual work of recreating symbolic links to point to the right version of PowerBuilder related directories. Then I adjust the PATH and we are ready to go with the PB version you chose.
Last part is just to display a nice listing of current settings.
To be able to draw attention, I tried to color the messages/output. To do this, I used a simple PowerShell scriptlet at the end of the script – :printBright. If Powershell exists, it will display message in bright yellow, otherwise, it will simply echo the message to the console. Incidentally this is the way you code functions in Windows Batch files. Anything in between :printBright and goto :eof makes the function called printBright. To execute the function, use CALL: For e.g.,
That’s all folks. Using Symbolic links to install different versions of the software completely isolated from each other. Though I used this to switch PowerBuilder, you could literally use it for any software in similar scenario.