Windows launcher improvement - starting is still done via smalltalk.bat jv
authorPatrik Svestka <patrik.svestka@gmail.com>
Wed, 12 Jul 2017 10:25:43 +0200
branchjv
changeset 1514 4bdcdc52e55a
parent 1508 b2b32caf589e
child 1515 919fad4de40f
Windows launcher improvement - starting is still done via smalltalk.bat Part of this release is: smalltalk.bat - main script logging needs a powershell (still possible to run completely without powershell but some features will not be avilable) smalltalk.ps1 - powershell filed called from the smalltalk.bat file to better control log file logging and all the powershell environment smalltalk.cfg - contains configuration for smalltalk.bat and smalltalk.ps1 smalltalk_close_shell.lnk & smalltalk_shell_remains_open.lnk - provided for running withing the project\smalltalk directory, contains custom icon. create_shortcut_on_desktop_via_hardlink.txt - contains guide how to create a desktop shortcut to .lnk files for users via hardlink. ====================================== The features of this advanced script = ====================================== Quick start (with close or leave open the shell after Smalltalk start) Starting with default image on defined path Starting with any image (user is prompted to select one via menu) on defined path Logging into a file - either overwrite or append at start start (minimal PowerShell 2.0 is required) - User can change the log file encoding to ASCII, UTF8 (default), UTF16, UTF32 - User can decide if he wants a date and/or time part added to the log file The script automatically detects PowerShell version and based on that decides which functionality will be available. Error handling on the batch and PowerShell level - user is informed about the details of error Batch file tries to exit gracefully, if possible The advanced features: A warning limit is in place for the log file size. If it gets too large as it may slowdown the Smalltalk. User can decide if there will be a shell opened for error messages or if Smalltalk will for from shell and will not display any messages on the command prompt. User can choose if the validation process is active and if the successful message is shown. User can choose which redirect will be used in PowerShell - if the native one or cmd.exe one (little bit faster in most cases). version 1.4.5 [Batch] Fixed issue with batch string error message (strip the reserved characters. + changed the :exit_sequence function - %~1 to %1 (same with %~2) when calling powershell
create_shortcut_on_desktop_via_hardlink.txt
smalltalk.bat
smalltalk.cfg
smalltalk.ps1
smalltalk_close_shell.lnk
smalltalk_shell_remains_open.lnk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/create_shortcut_on_desktop_via_hardlink.txt	Wed Jul 12 10:25:43 2017 +0200
@@ -0,0 +1,5 @@
+Warning:
+All link files must be created with absolute path to the executable & the working path (no variables permitted!)
+
+This is probably the best way:
+mklink /H C:\users\<user_id>\desktop\smalltalk.lnk C:\prg_sdk\Stx_stable\stx-jv\build\stx\projects\smalltalk\smalltalk_close_shell.lnk
\ No newline at end of file
--- a/smalltalk.bat	Fri Jun 02 22:26:06 2017 +0100
+++ b/smalltalk.bat	Wed Jul 12 10:25:43 2017 +0200
@@ -1,41 +1,1717 @@
-@echo off
-: $Header$
-: startup script for smalltalk
-: actually, simply calls stx, passing all arguments.
-
-: In previous versions, smalltalk used to be the executable itself.
-: This lead to problems on systems, where things like the PATH
-: or STX_LIBDIR should be set in advance.
-: Now, here is a place to do such things ...
-
-if {%1}=={--help} goto usage
-
+@ECHO OFF
+
+::  _____                 _ _ _        _ _         ____   __               
+:: /  ___|               | | | |      | | |       / /\ \ / /               
+:: \ `--. _ __ ___   __ _| | | |_ __ _| | | __   / /  \ V /                
+::  `--. \ '_ ` _ \ / _` | | | __/ _` | | |/ /  / /   /   \                
+:: /\__/ / | | | | | (_| | | | || (_| | |   <  / /   / /^\ \               
+:: \____/|_| |_| |_|\__,_|_|_|\__\__,_|_|_|\_\/_/    \/   \/               
+::                                                                         
+::  _    _ _                  _                            _               
+:: | |  | (_)                | |                          | |              
+:: | |  | |_ _ __    ______  | |     __ _ _   _ _ __   ___| |__   ___ _ __ 
+:: | |/\| | | '_ \  |______| | |    / _` | | | | '_ \ / __| '_ \ / _ \ '__|
+:: \  /\  / | | | |          | |___| (_| | |_| | | | | (__| | | |  __/ |   
+::  \/  \/|_|_| |_|          \_____/\__,_|\__,_|_| |_|\___|_| |_|\___|_|
+
+:: ==================================
+:: The startup script for smalltalk =
+:: ==================================
+:: This script is vastly improved previous smalltalk.bat.
+:: In previous versions, smalltalk used to be the executable itself.
+:: This lead to problems on systems, where things like the PATH or STX_LIBDIR should be set in advance.
+:: Now, here is a place to do such things ...
+
+:: ==========
+:: Contents =
+:: ==========
+:: Every section is separated by these words: Next section follows =
+
+:: 1 - Versions; batch files switches; setting on ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
+:: 2 - Configuration
+:: 3 - PowerShell detection
+:: 4 - Timer section
+:: 5 - Adjusting according to the configuration
+:: 6 - Checking variable and logic consistency
+:: 7 - Verify existence of paths and files from configuration
+:: 8 - A work-flow based on the configuration
+:: 9 - Running the command
+:: 10 - User defined functions
+:: 11 - Support information (like help, about, version)
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: Beginning                                                                                 *
+:: *******************************************************************************************
+
+:: ==========
+:: Versions =
+:: ==========
+:: This script
+SET batch_script_version=1.4.5
+:: Smalltalk/X
+SET stx_version=6.2.6
+
+:: ====================
+:: Comments and style =
+:: ====================
+:: USING :: instead of REM is a hack for now supported and it makes the bat execution much faster
+:: The reason is: REM is a command that has to be processed by cmd.exe, but the :: is a sign followed
+:: by :.  The first : makes the interpreter ignore the line altogether.
+
+:: If Microsoft should drop support of :: hack. Change you have to change all :: back to REM
+
+:: =========================================
+:: Batch file accepts following parameters =
+:: =========================================
+:: Enclosing the input parameter with double quotes is a correct way how to do it
+
+IF "%~1" EQU "--help" ECHO: & ECHO "stx.com help, for the laucher use --help-launcher." & ECHO: & GOTO stx_help
+IF "%~1" EQU "-h" ECHO: & ECHO "stx.com help, for the laucher use --help-launcher." & ECHO: & GOTO stx_help
+IF "%~1" EQU "/h" ECHO: & ECHO "stx.com help, for the laucher use --help-launcher." & GOTO stx_help
+IF "%~1" EQU "/?" ECHO: & ECHO "stx.com help, for the laucher use --help-launcher." & GOTO stx_help
+
+IF "%~1" EQU "--help-launcher" ECHO: & GOTO stx_help_launcher
+IF "%~1" EQU "-h-l" ECHO: & GOTO stx_help_launcher
+IF "%~1" EQU "/h-l" ECHO: & GOTO stx_help_launcher
+
+IF "%~1" EQU "--about" (
+    ECHO: & CALL :stx_about %batch_script_version% %stx_version%
+    GOTO :EOF
+)
+IF "%~1" EQU "-a" (
+    ECHO: & CALL :stx_about %batch_script_version% %stx_version%
+    GOTO :EOF
+)
+IF "%~1" EQU "/a" (
+    ECHO: & CALL :stx_about %batch_script_version% %stx_version%
+    GOTO :EOF
+)
+
+IF "%~1" EQU "--version" (
+    ECHO: & CALL :stx_version %batch_script_version% %stx_version%
+    GOTO :EOF
+)
+IF "%~1" EQU "-v" (
+    ECHO: & CALL :stx_version %batch_script_version% %stx_version%
+    GOTO :EOF
+)
+IF "%~1" EQU "/v" (
+    ECHO: & CALL :stx_version %batch_script_version% %stx_version%
+    GOTO :EOF
+)
+
+:: ==================
+:: Batch file flags =
+:: ==================
+:: Here for the correct deletion of the filled variables when script finishes
+:: ENABLEEXTENSIONS - enable or disable command processor extensions. These
+:: arguments takes precedence over the CMD /E:ON or /E:OFF
+:: ENABLEDELAYEDEXPANSION - enable or disable delayed environment variable
+:: expansion. These arguments takes precedence over the CMD /V:ON or /V:OFF switches.
+VERIFY OTHER 2>nul
+SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
+IF ERRORLEVEL 1 (
+    REM No color as expansion is not yet enabled
+    ECHO "Unable to enable extensions.  Fix it."
+    SET exit_value=1
+    GOTO exit_sequence 
+)
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: Configuration                                                                             *
+:: *******************************************************************************************
+:: Now all the variables except the for configuration file are in the configuration file.
+:: For more see variable configuration_file_path
+
+:: ==================================
+:: Clearing the shell prior the run =
+:: ==================================
+::CLS
+
+:: ===========================================
+:: Reading variables from external .cfg file =
+:: ===========================================
+:: The only variable that can not be validated (be careful when changing it^!)
+:: The reason is that it is before the validation process
+SET "configuration_file_path=%~dp0"
+SET "configuration_file=smalltalk.cfg"
+IF NOT EXIST !configuration_file_path!!configuration_file! (
+    SET "message="Smalltalk configuration file: !configuration_file! not found. Fix it.""
+    SET __numeric.exit_value=1
+    CALL :exit_sequence !message!
+    GOTO :EOF
+)
+
+:: EOL stops comments from being parsed
+:: otherwise split lines at the = char into two tokens
+FOR /F "EOL=# delims== tokens=1,*" %%A IN (!configuration_file!) DO (
+    REM proper lines have both a and b set
+    REM if okay, assign property to some kind of namespace
+    REM so some.property becomes test.some.property in batch-land
+    IF NOT "%%A"=="" IF NOT "%%B"=="" SET stx.%%A=%%B
+)
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:: =============
+:: Start timer =
+:: =============
+IF "!stx.__binary.use_timer!" EQU "TRUE" (
+    CALL :time_in_seconds __start
+    ECHO:
+    ECHO "[INFO] Start timer. START at: !__start! [seconds]"
+    ECHO:
+    
+)
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:: To see stx. namespace uncomment below
+:: SET stx.
+
+:: =================================================
+:: Expanding variables from the configuration file =
+:: =================================================
+:: Variable needs expanding if shell pseudo-variable is used e.g. ...dp0
+
+:: ===================
+:: Stx bin directory =
+:: ===================
+IF "!stx.stx_bin_dir!" NEQ "" (
+    CALL :expand !stx.stx_bin_dir! stx_bin_dir
+)
+
+:: ===================================
+:: Stx quick start and image details =
+:: ===================================
+IF "!stx.image_path!" NEQ "" (
+    CALL :expand !stx.image_path! stx.image_path
+)
+
+:: =============
+:: Stx logging =
+:: =============
+IF "!stx.log_directory!" NEQ "" (
+    CALL :expand !stx.log_directory! stx.log_directory
+)
+
+:: ==================================================================================
+:: Script's internal variables                                                      =
+:: WARNING: DO NOT TOUCH THE SET VALUES BELOW UNLESS YOU KNOW WHAT YOU ARE DOING!!! =
+:: ==================================================================================
+:: minimal powershell version, otherwise fall-back is triggered
+:: The path for powershell contains v1.0 for all powershell versions!!!!
+SET minimal_powershell_version=2.0
+:: this variable is directly accessed also in powershell file
+SET "powershell_version_all_functionality=3.0"
+SET PowerShellVersion=""
+SET RuntimeVersion=""
+
+:: Setting powershell script path and filename
+SET "powershell_script_path=%~dp0"
+SET "powershell_file=smalltalk.ps1"
+SET "powershell_script_file=!powershell_script_path!!powershell_file!"
+
+:: Fallback option must be always active
+SET "__binary.powershell_detected=FALSE"
+
+:: Default value is not to use stx command-line switches
+SET "stx_manual_switch_detected=FALSE"
+
+:: default script exit value ^(^=0 - everything OK, ^<^>0 - not OK^)
+SET __numeric.exit_value=0
+
+:: Make sure variable is undefined
+SET internal_runtime_options=
+
+:: Used for switches enter by user at command-line,
+:: making sure variable is undefined at the beginning
+:: This variable is accessed directly from powershell file
+SET stx_switch=
+
+:: Make sure variable is undefined
+SET stx_date_time=
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: PowerShell detection                                                                      *
+:: *******************************************************************************************
+
+:: =============================================
+:: Calling user function :powershell_detection =
+:: =============================================
+CALL :powershell_detection __binary.powershell_detected PowerShellVersion RuntimeVersion
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: Adjusting according to the configuration                                                  *
+:: *******************************************************************************************
+
+:: =============
+:: Shell Color =
+:: =============
+IF "!stx.__binary.colored_stdout!" EQU "TRUE" (
+    IF "!__binary.powershell_detected!" EQU "TRUE" (
+        SET "use_color=TRUE"
+    ) ELSE (
+        SET "use_color=FALSE"
+    )
+) ELSE (
+    SET "use_color=FALSE"
+)
+
+:: ============
+:: Image name =
+:: ============
+SET default_image_name="!stx.image_name:"=!!stx.image_suffix:"=!"
+
+:: ============================
+:: Add encoding to the suffix =
+:: ============================
+:: Allowed values ASCII, UTF8 (default), UTF16 (in Microsoft world that is called Unicode), UTF32
+:: Note: If UTF16 is used you can view log file while StX is running, in all other cases you have to close StX before viewing the file
+IF "!stx.log_file_encoding!" EQU "ASCII" (
+    SET "stx.log_suffix=_ascii!stx.log_suffix!"
+) ELSE IF "!stx.log_file_encoding!" EQU "UTF8" (
+    SET "stx.log_suffix=_utf8!stx.log_suffix!"
+) ELSE IF "!stx.log_file_encoding!" EQU "UTF16" (
+    SET "stx.log_suffix=_utf16!stx.log_suffix!"
+) ELSE IF "!stx.log_file_encoding!" EQU "UTF32" (
+    SET "stx.log_suffix=_utf32!stx.log_suffix!"
+) ELSE (
+    SET "message="Invalid log file encoding: !stx.log_file_encoding!. Fix it and run the script again.""
+    SET __numeric.exit_value=1
+    CALL :exit_sequence !message!
+    GOTO :EOF
+)
+
+:: =================================================
+:: UTF16 alias Microsoft's Unicode name conversion =
+:: =================================================
+IF "!stx.log_file_encoding!" EQU "UTF16" (
+    SET stx.log_file_encoding=Unicode
+)
+
+:: =================
+:: Log file format =
+:: =================
+:: Using wmic os get as it is probably the only locales independent way to get time on Windows
+:: Date: Using date ISO 8601 format YYYY-MM-DD with time part
+:: Time: Using time and date format independent of locales
+:: Note: back ticks are there for powershell compatibility
+IF "!stx.__binary.log_add_datepart!" EQU "TRUE" (
+    FOR /F %%A IN ('wmic os get LocalDateTime ^| find "."') DO SET dts=%%A
+    SET stx_date_time=!dts:~0,4!-!dts:~4,2!-!dts:~6,2!
+    IF "!stx.__binary.log_add_timepart!" EQU "TRUE" (
+        SET stx_date_time=!stx_date_time!_!dts:~8,2!"`;"!dts:~10,2!"`;"!dts:~12,2!
+    )
+    SET log_filename="!stx.log_name:"=!_!stx_date_time!!stx.log_suffix:"=!"
+) ELSE (
+    FOR /F %%A IN ('wmic os get LocalDateTime ^| find "."') DO SET dts=%%A
+    IF "!stx.__binary.log_add_timepart!" EQU "TRUE" (
+        SET stx_date_time=!dts:~8,2!"`;"!dts:~10,2!"`;"!dts:~12,2!
+        SET log_filename="!stx.log_name:"=!_!stx_date_time!!stx.log_suffix:"=!"
+    ) ELSE (
+        SET log_filename="!stx.log_name:"=!!stx.log_suffix:"=!"
+    )
+)
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: Checking variable and logic consistency                                                   *
+:: *******************************************************************************************
+
+:: ==============================================
+:: Checking the PowerShell file (.ps1) presence =
+:: ==============================================
+
+IF NOT EXIST "!powershell_script_file!" (
+    SET "message="PowerShell file missing: !powershell_script_path!smalltalk.ps1.  Fix it.""
+    SET __numeric.exit_value=1
+    CALL :exit_sequence !message!
+    GOTO :EOF
+)
+
+:: =====================================================================
+:: Validate __binary for TRUE^/FALSE and if it does not contain spaces =
+:: =====================================================================
+:: Checks if the variable contains correctly written TRUE^/FALSE
+:: additionally it also checks if additional space was not added by mistake
+:: var -7 extracts the last 7 characters from var
+IF "!stx.verify_variables_syntax!" EQU "TRUE" (
+    FOR /F "tokens=3 delims=^." %%A IN ('SET stx.__binary.') DO (
+        SET temp_test=%%A
+        IF "!temp_test:~-5!" EQU "=TRUE" (
+            IF "!temp_test!" NEQ "!temp_test: =!" (
+                SET __numeric.exit_value=1
+                SET "first_message="Incorrect configuration additional space detected.""
+                SET "first_message="Correct the variable: __binary.!temp_test!""
+                CALL :exit_sequence !first_message! !second_message!
+                GOTO :EOF
+            )
+        ) ELSE IF "!temp_test:~-6!" EQU "=FALSE" (
+            IF "!temp_test!" NEQ "!temp_test: =!" (
+                SET __numeric.exit_value=1
+                SET "first_message="Incorrect configuration additional space detected.""
+                SET "second_message="Correct the variable: __binary.!temp_test!""
+                CALL :exit_sequence !first_message! !second_message!
+                GOTO :EOF
+            )
+        ) ELSE (
+            IF "!temp_test!" NEQ "!temp_test: =!" (
+                SET __numeric.exit_value=1
+                SET "first_message="Incorrect configuration additional space detected.""
+                SET "second_message="Correct the variable: __binary.!temp_test!""
+                CALL :exit_sequence !first_message! !second_message!
+                GOTO :EOF
+            ) ELSE (
+                SET "first_message="Incorrect configuration mistake in TRUE^/FALSE detected.""
+                SET "second_message="Correct the variable: __binary.!temp_test!""
+                SET __numeric.exit_value=1
+                CALL :exit_sequence !first_message! !second_message!
+                GOTO :EOF
+            )
+        )
+    )
+    REM must be used (inside IF^!)
+    REM  ===================================================================
+    REM  Validate if __binary values are numeric and do not contain spaces =
+    REM  ===================================================================
+    REM 1. FOR - variable extraction bla value
+    REM 2. FOR - extracting integer value
+    REM 3. FOR - testing integer
+    FOR /F "tokens=3 delims=^." %%A IN ('SET stx.__numeric.') DO (
+        SET temp_test=%%A
+        FOR /F "tokens=2 delims==" %%B IN ("!temp_test!") DO SET "test_integer=%%B"
+        SET "ugh="&FOR /F "delims=0123456789" %%C IN ("!test_integer!") DO SET "ugh=%%~C"
+        IF defined ugh (
+            IF "!temp_test!" NEQ "!temp_test: =!" (
+                SET __numeric.exit_value=1
+                SET "first_message="Incorrect configuration additional space detected.""
+                SET "second_message="Correct the variable: __binary.!temp_test!""
+                CALL :exit_sequence !first_message! !second_message!
+                GOTO :EOF
+            ) ELSE (
+                SET __numeric.exit_value=1
+                SET "message="Incorrect configuration detected - integer value is not an integer.""
+                CALL :exit_sequence !message!
+                GOTO :EOF
+            )
+        ) ELSE (
+              IF "!temp_test!" NEQ "!temp_test: =!" (
+                  SET __numeric.exit_value=1
+                  SET "first_message="Incorrect configuration additional space detected.""
+                  SET "second_message="Correct the variable: __binary.!temp_test!""
+                  CALL :exit_sequence !first_message! !second_message!
+                  GOTO :EOF
+              )
+        )
+    )
+    IF "!stx.verify_print_message!" EQU "TRUE" (
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "==============================="
+            CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "Variable syntax validated.    ="
+            CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "==============================="
+            ECHO:
+        ) ELSE (
+            ECHO "==============================="
+            ECHO "Variable syntax validated.    ="
+            ECHO "==============================="
+            ECHO:
+        )
+    )
+)
+
+:: =============
+:: Quick start =
+:: =============
+:: Note: quick start should not be used with image functionality
+:: If there is a mistake in image functionality (start_with_image=FALSE and list_available_images=TRUE)
+:: THEN quick start is used
+IF "!stx.__binary.stx_quick_start!" EQU "TRUE" (
+    IF "!stx.__binary.start_with_image!" EQU "TRUE" (
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Your configuration flawed - compensating."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] stx_quick_start=TRUE AND start_with_image=TRUE which makes no sense."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Using only image functionality. start_with_image=TRUE and stx_quick_start=FALSE"
+        ) ELSE (
+            ECHO "[WARN] Your configuration flawed - compensating."
+            ECHO "[WARN] stx_quick_start=TRUE AND start_with_image=TRUE which makes no sense."
+            ECHO "[WARN] Using only image functionality. start_with_image=TRUE and stx_quick_start=FALSE"
+        )
+        ECHO:
+        SET "stx.__binary.stx_quick_start=FALSE"
+    ) ELSE IF "!stx.__binary.list_available_images!" EQU "TRUE" (
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Your configuration flawed - compensating."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] start_with_image=FALSE, list_available_images=TRUE, AND stx_quick_start=TRUE which makes no sense."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Using only stx_quick_start=TRUE"
+        ) ELSE (
+            ECHO "[WARN] Your configuration flawed - compensating."
+            ECHO "[WARN] start_with_image=FALSE, list_available_images=TRUE, AND stx_quick_start=TRUE which makes no sense."
+            ECHO "[WARN] Using only stx_quick_start=TRUE"
+        )
+        ECHO:
+        SET "stx.__binary.list_available_images=FALSE"
+    )
+)
+
+:: ==========================================================================
+:: Pair stx.__binary.start_with_image ^& stx.__binary.list_available_images =
+:: ==========================================================================
+IF "!stx.__binary.start_with_image!" EQU "FALSE" (
+    IF "!stx.__binary.list_available_images!" EQU "TRUE" (
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Your configuration flawed - compensating."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] start_with_image=FALSE AND list_available_images=TRUE which makes no sense."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Setting list_available_images=FALSE."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] To fix it either set start_with_image=TRUE or list_available_images=FALSE"
+        ) ELSE (
+            ECHO "[WARN] Your configuration flawed - compensating."
+            ECHO "[WARN] start_with_image=FALSE AND list_available_images=TRUE which makes no sense."
+            ECHO "[WARN] Setting list_available_images=FALSE."
+            ECHO "[WARN] To fix it either set start_with_image=TRUE or list_available_images=FALSE"
+        )
+        ECHO:
+        SET "stx.__binary.list_available_images=FALSE"
+    )
+)
+
+:: ============================================================================================
+:: Pair variables (work together) stx.__binary.record_log_file and stx.__binary.append_to_log =
+:: ============================================================================================
+IF "!stx.__binary.record_log_file!" EQU "FALSE" (
+    IF "!stx.__binary.append_to_log!" EQU "TRUE" (
+        ECHO:
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Your configuration flawed - compensating."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] record_log_file=FALSE AND append_to_log=TRUE which makes no sense."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Setting append_to_log=FALSE."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] To fix it either set record_log_file=TRUE or append_to_log=FALSE"
+        ) ELSE (
+            ECHO "[WARN] Your configuration flawed - compensating."
+            ECHO "[WARN] record_log_file=FALSE AND append_to_log=TRUE which makes no sense."
+            ECHO "[WARN] Setting append_to_log=FALSE."
+            ECHO "[WARN] To fix it either set record_log_file=TRUE or append_to_log=FALSE"
+        )
+        ECHO:
+        SET "stx.__binary.append_to_log=FALSE"
+    )
+)
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: Verify existence of paths and files from configuration                                    *
+:: *******************************************************************************************
+
+:: ===================================================
+:: Selecting an executable                           =
+:: Checking for a presence of %smalltalk_executable% =
+:: ===================================================
+:: Your path to smalltalk & and exec (bat,cmd,com,exe, etc.)
+:: change the line below, if the support stuff is not found in the
+:: directory where stx-bin.com / stx.com resides.  (exe is for GUI only)
+:: STX_LIB_DIR=<path_to_support_files>
+
+:: Change to the specified bin directory
+pushd "!stx_bin_dir!"
+IF EXIST "stx-bin.com" (
+    IF "!stx.__binary.run_via_shell!" EQU "TRUE" (
+        SET "selected_executable=stx-bin.com"
+     ) ELSE (
+        SET "selected_executable=stx-bin.exe"
+     )
+    SET "stx_home=!stx_bin_dir:"=!.."
+    SET "stx_topdir=!stx_bin_dir:"=!..\lib\smalltalkx\!stx_version!"
+    SET "stx_libdir=!stx_bin_dir:"=!..\lib\smalltalkx\!stx_version!\lib"
+    SET "smalltalk_executable=!stx_bin_dir:"=!!selected_executable!"
+) ELSE IF EXIST "stx.com" (
+     IF "!stx.__binary.run_via_shell!" EQU "TRUE" (
+        SET "selected_executable=stx.com"
+     ) ELSE (
+        SET "selected_executable=stx.exe"
+     )
+    SET smalltalk_executable="!stx_bin_dir:"=!!selected_executable!"
+) ELSE (
+
+    SET "message="The executable stx-bin^.com;exe perhaps stx^.com;exe NOT found.""
+    SET __numeric.exit_value=1
+    CALL :exit_sequence !message!
+    GOTO :EOF
+)
+:: return back
+popd
+
+:: ==========================================================================================
+:: Checking if the image at the path really exists.                                         =
+:: using temporary variable due to the fact that NOT exists needs already expanded variable =
+:: ==========================================================================================
+SET "temp_stx.image_path=!stx.image_path:"=!!default_image_name:"=!"
+
+IF "!stx.__binary.start_with_image!" EQU "TRUE" (
+    IF "!stx.__binary.list_available_images!" EQU "FALSE" (
+        IF NOT EXIST "!temp_stx.image_path!" (
+            REM TOO DEEP MUST FIX
+            REM CALL :colorEcho stx.stdout_cmd_warning "[WARN] The default image: !stx.image_path:"=!!default_image_name:"=! was not found."
+            REM CALL :colorEcho stx.stdout_cmd_warning "[WARN] No image will loaded. If you want to load from image fix your path or image name."
+            ECHO:
+            SET "stx.__binary.start_with_image=FALSE"
+        )
+    )
+)
+
+:: clearing temp variable
+SET temp_stx.image_path=
+
+:: ===============================================================================
+:: Checking existence of logging directory, if not found all logging is disabled =
+:: ===============================================================================
+IF NOT EXIST "!stx.log_directory!" (
+    IF "!use_color" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] The logging path: !stx.log_directory! NOT found."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Logging will be DISABLED."
+        ) ELSE (
+            ECHO "[WARN] The logging path: !stx.log_directory! NOT found."
+            ECHO "[WARN] Logging will be DISABLED."
+        )
+    ECHO:
+    SET stx.__binary.start_with_image=FALSE
+    SET stx.__binary.append_to_log=FALSE
+)
+
+:: ================================================================
+:: Checking existence of log file if not found append is disabled =
+:: ================================================================
+IF NOT EXIST "!log_filename!" (
+    IF "!use_color!" EQU "TRUE" (
+        CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "[INFO] No log file found turning off the append mode."
+    ) ELSE (
+        ECHO "[INFO] No log file found turning off the append mode."
+    )
+    ECHO:
+    SET stx.__binary.append_to_log=FALSE
+)
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: A work-flow based on the configuration                                                    *
+:: *******************************************************************************************
+
+:: =================================================================
+:: If powershell detected, get powershell executable from registry =
+:: =================================================================
+:: FINDSTR is there for Windows XP compatibility
+IF "!__binary.powershell_detected!" EQU "TRUE" (
+    (FOR /F "tokens=3" %%A IN ('REG QUERY "HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" /v path ^| FINDSTR "^.*\.exe$"') DO (
+         SET "powershell_exec=%%A"
+    )) || REM
+    IF ERRORLEVEL 1 (
+        SET "first_message="[ERROR] Powershell detected, but executable !powershell_exec! not found.""
+        SET "second_message="Fix your system.""
+        SET __numeric.exit_value=1
+        CALL :exit_sequence !first_message! !second_message!
+        GOTO :EOF
+    )
+)
+
+:: ===================================================
+:: Powershell detected? (so we can log into a file?) =
+:: ===================================================
+IF "!stx.__binary.record_log_file!" EQU "TRUE" (
+    IF "!__binary.powershell_detected!" EQU "FALSE" (
+        SET "stx.__binary.record_log_file=FALSE"
+        SET "stx.__binary.append_to_log=FALSE"
+    )
+)
+
+
+:: =====================================================
+:: Adding all parameters available to the %stx_switch% =
+:: Making sure previous switches are taken in account  =
+:: =====================================================
+:: Cycle all command-line switches entered in the shell by the user
+:: Encircle all switches (both - and --) by double-quotes
+:: Ignore the command-line switches already with double quotes
+:: Replace single quotes with double quotes if such switch is found
+IF "%~1" NEQ "" (
+    SET "stx_manual_switch_detected=TRUE"
+    SET "detect_double_switch=--"
+    SET "detect_single_switch=-"
+    SET "detect_double_quote="-"
+    SET "detect_single_quote='-"
+
+    FOR %%A IN (%*) DO (
+        SET "temp_string=%%~A"
+        IF DEFINED stx_switch (
+            REM Detect if "" around a switch are used and leave the switch alone
+            IF "!temp_string:~0,2!" EQU "!detect_double_quote!" (
+                SET stx_switch=!stx_switch! %%A
+            REM Detect if '' around a switch are used and convert them to ""
+            ) ELSE IF "!temp_string:~0,2!" EQU "!detect_single_quote!" (
+                SET "changed_string=!temp_string:'="!"
+                SET stx_switch=!stx_switch! !changed_string!
+            REM if -- found encircle it with double quotes
+            ) ELSE IF "!temp_string:~0,2!" EQU "!detect_double_switch!" (
+                SET stx_switch=!stx_switch! ^"%%~A^"
+            REM checks a string for "-" if it contains it it will add double-quotes
+            ) ELSE IF "!temp_string:~0,1!" EQU "!detect_single_switch!" (
+                SET stx_switch=!stx_switch! ^"%%~A^"
+            ) ELSE (
+                SET "stx_switch=!stx_switch! %%A"
+            )
+        REM stx_switch is not yet defined - first run
+        ) ELSE (
+            REM Detect if "" around a switch are used
+            IF "!temp_string:~0,2!" EQU "!detect_double_quote!" (
+                SET stx_switch=!stx_switch! %%A
+            REM Detect if '' around a switch are used and convert them to ""
+            ) ELSE IF "!temp_string:~0,2!" EQU "!detect_single_quote!" (
+                SET "changed_string=!temp_string:'="!"
+                SET stx_switch=!stx_switch! !changed_string!
+            REM All other options
+            ) ELSE (
+                SET stx_switch=^"%%A^"
+            )
+        )
+    )
+    REM clearing used variables
+    SET detect_switch_double=
+    SET detect_single_switch=
+    SET detect_double_quote=
+    SET detect_single_quote=
+)
+
+:: ======================================================
+:: Block CMD PowerShell mode from using manual Switches =
+:: ======================================================
+IF "!stx_manual_switch_detected!" EQU "TRUE" (
+    IF "!stx.__binary.cmd_in_powershell!" EQU "TRUE" (
+        ECHO:
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] You can not simultaneously pass command-line switches to stx.com and log using CMD PowerShell mode - __binary.cmd_in_powershell=TRUE"
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] Switching off LOGGING and executing only via cmd.exe."
+        ) ELSE (
+            ECHO "[WARN] You can not simultaneously pass command-line switches to stx.com and log using CMD PowerShell mode - __binary.cmd_in_powershell=TRUE"
+            ECHO "[WARN] Switching off LOGGING and executing only via cmd.exe."
+        )
+        ECHO:
+        SET stx.__binary.record_log_file=FALSE
+        SET stx.__binary.append_to_log=FALSE
+    )
+)
+
+:: =================================
+:: Three ways to start Smalltalk/X =
+:: =================================
+:: TRUE;TRUE   - User will be asked for input; with which image to start
+:: TRUE;FALSE  - Stx will start with the default image configured
+:: FALSE;FALSE - Quick start - StX will start without an image
+IF "!stx.__binary.start_with_image!" EQU "TRUE" (
+    IF "!stx.__binary.list_available_images!" EQU "TRUE" (
+        REM USER INPUT
+        CALL :user_input !stx.image_path! stx.image_name !stx.image_suffix!
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "[INFO] Loading image =>!stx.image_name:"=!"<= selected by the user."
+        ) ELSE (
+            ECHO "[INFO] Loading image =>!stx.image_name:"=!"<= selected by the user."
+        )
+        SET user_selected_image="!stx.image_name:"=!"
+        IF DEFINED internal_runtime_options (
+            SET stx_switch=!stx_switch! !internal_runtime_options! "--image" !user_selected_image!
+        ) ELSE (
+            SET stx_switch=!stx_switch! "--image" !user_selected_image!
+        )
+        SET user_selected_image=
+    ) ELSE (
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "[INFO] DEFAULT IMAGE: !stx.image_path:"=!!default_image_name:"=! starts"
+        ) ELSE (
+            ECHO "[INFO] DEFAULT IMAGE: !stx.image_path:"=!!default_image_name:"=! starts"
+        )
+        IF DEFINED internal_runtime_options (
+            SET stx_switch="--image" !default_image_name! !internal_runtime_options! !stx_switch!
+        ) ELSE (
+            SET stx_switch="--image" !default_image_name! !stx_switch!
+        )
+    )
+) ELSE (
+    IF "!stx.__binary.stx_quick_start!" EQU "TRUE" (
+        IF DEFINED internal_runtime_options (
+            SET stx_switch="--ignoreImage" !stx_switch! !internal_runtime_options! "--quick"
+        ) ELSE (
+            SET stx_switch="--ignoreImage" !stx_switch! "--quick"
+        )
+        REM clearing configured values
+        SET stx.image_path=
+        SET default_image_name=
+    )
+)
+
+:: =======================================
+:: Check if user wants to command prompt =
+:: =======================================
+:: note: cmd /U causes the output to pipes or file to be Unicode
+IF "!stx.__binary.close_shell!" EQU "TRUE" (
+    SET "cmd_close=/U /C"
+) ELSE (
+    SET "cmd_close=/U /K"
+)
+
+:: =============================================================================
+:: Check if the log file is not too big (with jumping into log file directory) =
+:: =============================================================================
+:: Changing to log directory
+pushd "!stx.log_directory!"
+IF "!stx.__binary.append_to_log!" EQU "TRUE" (
+    (FOR %%A IN (!log_filename!) DO (
+        SET file_size=%%~zA
+    )) || REM
+    IF ERRORLEVEL 1 (
+        SET "message="Error checking size of the file: !log_filename:"=!.""
+        SET __numeric.exit_value=1
+        CALL :exit_sequence !message!
+        GOTO :EOF
+    )
+    IF !file_size! GEQ !stx.__numeric.warning_logfile_size! (
+        ECHO:
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "==================================================================================================================="
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] BIG_FAT_WARNING: your log file !log_filename:"=! is larger than !stx.__numeric.warning_logfile_size! Bytes. "
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] This can slow down your StX."
+            CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "==================================================================================================================="
+        ) ELSE (
+            ECHO "====================================================================================================================="
+            ECHO "[WARN] BIG_FAT_WARNING: your log file !log_filename:"=! is larger than !stx.__numeric.warning_logfile_size! Bytes. "
+            ECHO "[WARN] This can slow down your StX."
+            ECHO "====================================================================================================================="
+        )
+        ECHO:
+        PAUSE
+    )
+)
+:: Return back from the log directory
+popd
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: Running the command                                                                       *
+:: *******************************************************************************************
+
+:: =================================
+:: Preparing command for execution =
+:: =================================
+IF "!stx.__binary.record_log_file!" EQU "TRUE" (
+    REM -WindowStyle Normal Sets the window style to Normal, Minimized, Maximized or Hidden.
+    REM -NoProfile - launches without a profile
+    REM -ExecutionPolicy Bypass - does not ask for passwords if used privileged command.
+    SET exec_command$=CALL !powershell_exec! -WindowStyle Normal -nologo -noninteractive -NoProfile -ExecutionPolicy Bypass -Command "& {!powershell_script_file! -executable '!smalltalk_executable:"=!' -log_file '!stx.log_directory:"=!!log_filename:"=!' -log_file_encoding '!stx.log_file_encoding!' -append_to_log '!stx.__binary.append_to_log!' -cmd_close '!cmd_close!' -PowerShellVersion '!PowerShellVersion!' -cmd_in_powershell '!stx.__binary.cmd_in_powershell!' -stx_manual_switch_detected '!stx_manual_switch_detected!'};"
+) ELSE (
+    ECHO:
+    IF "!use_color!" EQU "TRUE" (
+        CALL :printInColor !stx.stdout_WarningBackgroundColor! !stx.stdout_WarningForegroundColor! "[WARN] NO LOGGING"
+        ECHO:
+        CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "[INFO] User disabled or limitation applies."
+        CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "[INFO] Executing: cmd.exe !cmd_close:"=! CALL !smalltalk_executable:"=! !stx_switch!"
+    ) ELSE (
+        ECHO "[WARN] NO LOGGING."
+        ECHO:
+        ECHO "[INFO] User disabled or limitation applies."
+        ECHO "[INFO] Executing: cmd.exe !cmd_close:"=! CALL !smalltalk_executable:"=! !stx_switch!"
+    )
+    SET "exec_command$=cmd.exe !cmd_close! CALL !smalltalk_executable:"=! !stx_switch!"
+)
+
+:: ===========
+:: Execution =
+:: ===========
+:: An alternative working too
+REM START /B /W !exec_command$!
+
+:: An alternatives NOT working properly (for unknown reason) - as a warning 
+REM ECHO " "exec: !%exec_command%!"
+REM CALL %%exec_command%%
+
+:: Calling the dynamic variable exec_command$ this way works 100%
+:: The suffix $ at the variable is to make sure there is no variable collision with the current environment
+CALL !exec_command$!
+:: To view error level even from PowerShell
+:: ECHO "Errorlevel: !errorlevel!"
+:: PAUSE
+IF "%ERRORLEVEL%" NEQ "0" (
+    SET "message="The command !exec_command$! was executed incorrectly.""
+    SET __numeric.exit_value=1
+    CALL :exit_sequence !message!
+    GOTO :EOF
+)
+
+:: ==================================
+:: Correctly ending the application =
+:: ==================================
+IF "__binary.close_shell" EQU "FALSE" (
+    ECHO:
+    IF "!use_color!" EQU "TRUE" (
+        CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "[INFO] End. Waiting till final exit."
+    ) ELSE (
+        ECHO "[INFO] End. Waiting till final exit."
+    )
+    PAUSE
+) ELSE (
+    ECHO:
+    IF "!use_color!" EQU "TRUE" (
+        CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "[INFO] End. Exiting correctly."
+    ) ELSE (
+        ECHO "[INFO] End. Exiting correctly."
+    )
+    IF "!stx.__binary.use_timer!" EQU "TRUE" (
+        REM ===========================
+        REM End timer and show result =
+        REM ===========================
+        CALL :time_in_seconds __end
+        ECHO "[INFO] timer end. Duration: !__end! [seconds]"
+        ECHO:
+        SET /A _elapsed=!__end!-!__start!
+        ECHO "[INFO] Timer: !_elapsed! seconds."
+    )
+)
+ENDLOCAL
+EXIT /B 0
+
+
+
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+:: Next section follows 
+:: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: User defined functions                                                                    *
+:: *******************************************************************************************
+
+:exit_sequence
+IF "!__numeric.exit_value!" NEQ "0" (
+    IF "%~1" NEQ "" (
+        ECHO:
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_ErrorForegroundColor! !stx.stdout_ErrorBackgroundColor! "[ERROR] "%1""
+        ) ELSE (
+            ECHO "%~1"
+        )
+    )
+    IF "%~2" NEQ "" (
+        IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_ErrorForegroundColor! !stx.stdout_ErrorBackgroundColor! "[ERROR] "%2""
+        ) ELSE (
+            ECHO "%~2"
+        )
+    )
+    ECHO:
+    IF "!use_color!" EQU "TRUE" (
+        CALL :printInColor !stx.stdout_ErrorForegroundColor! !stx.stdout_ErrorBackgroundColor! "[ERROR] Exiting with error. Script __numeric.exit_value: !__numeric.exit_value!."
+        CALL :printInColor !stx.stdout_ErrorForegroundColor! !stx.stdout_ErrorForegroundColor! "[ERROR] Batch errorlevel: !ERRORLEVEL!"
+    ) ELSE (
+        ECHO "[ERROR] Exiting with error. Script __numeric.exit_value: !__numeric.exit_value!."
+        ECHO "[ERROR] Batch errorlevel: !ERRORLEVEL!"
+    )
+    PAUSE
+    REM Cleanup namespace stx.
+    REM nul redirection stops error output if no stx. var is set
+    FOR /F "tokens=1 delims==" %%V IN ('SET stx. 2^>NUL') DO (
+        SET %%V=
+    )
+    REM Deallocate variables
+    ENDLOCAL
+    EXIT /B 1
+) ELSE (
+    ECHO:
+    IF "!use_color!" EQU "TRUE" (
+            CALL :printInColor !stx.stdout_VerboseBackgroundColor! !stx.stdout_VerboseForegroundColor! "[INFO] Exiting correctly."
+    ) ELSE (
+            ECHO "[INFO] Exiting correctly."
+    )
+    REM Cleanup namespace stx.
+    REM nul redirection stops error output if no stx. var is set
+    FOR /F "tokens=1 delims==" %%V IN ('SET stx. 2^>NUL') DO (
+        SET %%V=
+    )
+    
+    call :cleanupColorPrint
+    REM Deallocate variables
+    ENDLOCAL
+    EXIT /B 0
+)
+
+:: =============================
+:: Detect available powershell =
+:: =============================
+:powershell_detection
+
+SET registry_path="HKLM\SOFTWARE\Microsoft\PowerShell"
+SET latest_powershell_version=0
+SET runtime_version=""
+SET /A counter=1
+
+:: Check if registry path to PowerShell exists
+REG QUERY !registry_path!>NUL
+IF /I "!ERRORLEVEL!" NEQ "0" (
+    ECHO:
+    ECHO "[ERROR] Registry path: !registry_path! does not exist."
+    ECHO "[ERROR] Powershell NOT detected."
+    SET powershell_detected=FALSE
+    GOTO end_powershell_detection
+)
+
+:: ~ expands the given variable
+:: The ^ escapes (protects) the pipe during the initial batch parsing.
+:: double %% is there as holder for FOR.
+:: :"= replaces all the double quotes in the variable with nothing
+:: The '\\' in regexp is included for WindowsXP compatibility - req query returns also its version in the query
+(FOR /F "delims=" %%A IN ('REG QUERY "!registry_path!" ^| FINDSTR "^.*\\[0-9]$"') DO (
+    REM "ECHO "DEBUG:__PowerShellRegistryVersion.!counter!=%%~A"
+    SET __PowerShellRegistryVersion.!counter!=%%~A
+    SET /A counter+=1
+)) || REM
+IF ERRORLEVEL 1 (
+    ECHO:
+    ECHO "[ERROR] Query: REG QUERY "!registry_path!" ^| FINDSTR "^.*\\[0-9]$" probably error in registry."
+    SET powershell_detected=FALSE
+    PAUSE
+    GOTO end_powershell_detection
+)
+
+:: Found powershell registry token=2* takes 'counter=registry path'. delims== selects everything right of "="; ending with only registry path.
+(FOR /F "tokens=2* delims==" %%A IN ('SET __PowerShellRegistryVersion.') DO (
+    (FOR /F "tokens=3" %%R IN ('REG QUERY %%~A /v Install ^| FIND "Install"') DO (
+        SET PowerShellInstalled=%%~R
+    )) || REM
+    IF ERRORLEVEL 1 (
+        ECHO:
+        ECHO "[ERROR] Query: REG QUERY "REG QUERY %%~A /v Install ^| FIND "Install" did not find any Install key. probably error in registry."
+        SET powershell_detected=FALSE
+        PAUSE
+        GOTO end_powershell_detection
+    )
+    IF "!PowerShellInstalled!" NEQ "0x1" (
+        ECHO:
+        ECHO "[INFO] The PowerShell PSCompatibleVersion ^(1.0 or 2.0^) is not installed."
+        SET powershell_detected=FALSE
+        GOTO end_powershell_detection
+    )
+
+    (FOR /F "tokens=3" %%P IN ('REG QUERY "%%~A\PowerShellEngine" /v PowerShellVersion ^| FIND "PowerShellVersion"') DO (
+        SET PowerShellVersion=%%~P
+    )) || REM
+    IF ERRORLEVEL 1 (
+        ECHO:
+        ECHO "[ERROR] Query: REG QUERY "REG QUERY "%%~A\PowerShellEngine" /v PowerShellVersion ^| FIND "PowerShellVersion"" did not find any PowerShellVersion key. probably error in registry."
+        SET powershell_detected=FALSE
+        PAUSE
+        GOTO end_powershell_detection
+    )
+    REM GEQ - greater than or equal
+    IF "!PowerShellVersion!" GEQ "!minimal_powershell_version!" (
+        SET powershell_detected=TRUE
+    ) ELSE (
+        SET powershell_detected=FALSE
+    )
+
+    FOR /F "tokens=3" %%V IN ('REG QUERY "%%~A\PowerShellEngine" /v RuntimeVersion ^| FIND "RuntimeVersion"') DO SET RuntimeVersion=%%~V
+    IF "!latest_powershell_version!" LSS "!PowerShellVersion!" (
+        SET latest_powershell_version=!PowerShellVersion!
+        SET runtime_version=!RuntimeVersion!
+    )
+)) || REM
+    IF ERRORLEVEL 1 (
+        ECHO:
+        ECHO "[ERROR] Command SET __PowerShellRegistryVersion.  Something wrong with your shell (command prompt)."
+        SET powershell_detected=FALSE
+        PAUSE
+        GOTO end_powershell_detection
+    )
+
+IF "!powershell_detected!" EQU "TRUE" (
+    ECHO:
+    ECHO "[INFO] PowerShell detected: ->!powershell_detected!<-.
+    ECHO "[INFO] The latest latest_powershell_version found: !latest_powershell_version!."
+    ECHO "[INFO] With the runtime being: !runtime_version!."
+) ELSE (
+    ECHO:
+    ECHO "[INFO] PowerShell NOT detected. Fallback mode activated.
+)
+
+:end_powershell_detection
+
+SET "%~1=!powershell_detected!"
+SET "%~2=!latest_powershell_version!"
+SET "%~3=!runtime_version!"
+
+EXIT /B
+
+:: ============
+:: User input =
+:: ============
+:user_input
+
+:: Normal path can be with or without double quotes.  If the path contains spaces it must be enclosed by double quotes.
+SET input_image_path=%~1
+SET input_image_suffix=%~3
+SET /A counter=1
+
+:: %%A - double %% due to FOR loop and %A as an array
+:: within FOR filename with suffix: %%~nxA
+:: For does not change ERRORLEVEL but uses exit_code for more see: http://stackoverflow.com/questions/34987885/what-are-the-errorlevel-values-set-by-internal-cmd-exe-commands 
+:: However, the '|| REM' trick captures the ERRORLEVEL from the DIR executed as for command.
+ECHO "--------------- User input -------------------------------------"
+ECHO "Select your stx image:"
+ECHO:
+(FOR /F "delims=" %%A IN ('dir !input_image_path!*!input_image_suffix! /B /O /o:gen 2^>NUL') DO (
+    SET "__stx_image_path.!counter!=%%~dpnxA"
+    ECHO "[!counter!]  => !__stx_image_path.%counter%! 
+    SET /A counter+=1
+)) || REM
+IF ERRORLEVEL 1 ECHO "No files with mask !input_image_path:"=!^*^!input_image_suffix:"=!"
+ECHO:
+ECHO "[0]  Exit"
+ECHO:
+ECHO "----------------------------------------------------------------"
+ECHO:
+
+SET /P user_input="Enter a choice: "
+:: -----------------------------
+:: prevent hijacking the input -
+:: -----------------------------
+:: ECHO "DEBUG: .!user_input!.
+:: ECHO "DEBUG: strip quotes: .!user_input:"=!.
+SET user_input=!user_input:"=!
+
+:: If you really want to reject the variable with any quotation mark...
+:: FIND /V-  Displays all lines NOT containing the specified string.
+SET user_input | FIND /V """" >NUL
+IF ERRORLEVEL 1 (
+   SET user_input=
+   ECHO "[ERROR] You are trying to hijack the input. Exiting."
+   ECHO "[ERROR] Batch errorlevel: !ERRORLEVEL!"
+   PAUSE
+   REM This is a "trick" to exit directly the function
+   REM (GOTO) 2^^>NUL behaves nearly same as exit /B but executes the block behind it
+   (GOTO) 2>NUL & ENDLOCAL & EXIT /B 1
+)
+:: ---------------------------------
+:: END prevent hijacking the input -
+:: ---------------------------------
+
+:: User choose to exit
+IF "!user_input!" EQU "0" (
+    ECHO "[INFO] You have selected to exit voluntary. Goodbye."
+    (GOTO) 2>NUL & ENDLOCAL & EXIT /B 0
+)
+
+REM A solution for unknown number of options at the time asking the question
+REM ugh must not be used anywhere else!
+REM Verification that user has entered a number from the given selection
+SET "ugh="&FOR /F "delims=0123456789" %%I IN ("!user_input!") DO SET "ugh=%%~I"
+IF defined ugh (
+    ECHO:
+    ECHO "[INFO] The input -> !user_input! <- was outside the given choices."
+    SET ugh=
+    PAUSE
+    GOTO user_input
+) ELSE (
+    IF "!user_input!" GTR "0" (
+        IF "!user_input!" LSS "!counter!" (
+            REM ECHO "DEBUG: Your answer is: -> %user_input% <-."
+            SET verified_user_input=!user_input!
+        ) ELSE (
+            ECHO:
+            ECHO "[INFO] The input2 -> !user_input! <- was outside the given choices."
+            PAUSE
+            GOTO user_input
+        )
+    ) ELSE (
+        ECHO:
+        ECHO "[INFO] The input3 -> !user_input! <- was outside the given choices."
+        PAUSE
+        GOTO user_input
+    )
+)
+
+SET "%~2=!__stx_image_path.%verified_user_input%!"
+SET !__stx_image_path.%verified_user_input%!=
+SET verified_user_input=
+SET input_image_path=
+SET input_image_suffix=
+
+EXIT /B
+
+
+:: ======================================
+:: Native Shell coloring for Windows 10 =
+:: ======================================
+:: NOT FINISHED!!!
+:printInColorWin10
+
+:: Windows 10 detection
+::FOR /F "tokens=2 delims=[" %%I IN ('ver') DO (
+::   ECHO %%I
+::   FOR /F "tokens=2-3 delims=. " %%V IN ("%%I") DO (
+::       SET version=%%V.%%W
+::       IF "!version!" LSS "10.0" (
+::           ECHO "Older windows than Windows 10"
+::       ) ELSE (
+::           ECHO "Windows 10 or newer"
+::       )
+::   )
+::)
+
+:: ANSI Colors for Windows 10
+REM ECHO [101;93m STYLES [0m
+REM ECHO ^<ESC^>[0m [0mReset[0m
+REM ECHO ^<ESC^>[1m [1mBold[0m
+REM ECHO ^<ESC^>[4m [4mUnderline[0m
+REM ECHO ^<ESC^>[7m [7mInverse[0m
+REM ECHO.
+REM ECHO [101;93m NORMAL FOREGROUND COLORS [0m
+REM ECHO ^<ESC^>[30m [30mBlack[0m (black)
+REM ECHO ^<ESC^>[31m [31mRed[0m
+REM ECHO ^<ESC^>[32m [32mGreen[0m
+REM ECHO ^<ESC^>[33m [33mYellow[0m
+REM ECHO ^<ESC^>[34m [34mBlue[0m
+REM ECHO ^<ESC^>[35m [35mMagenta[0m
+REM ECHO ^<ESC^>[36m [36mCyan[0m
+REM ECHO ^<ESC^>[37m [37mWhite[0m
+REM ECHO.
+REM ECHO [101;93m NORMAL BACKGROUND COLORS [0m
+REM ECHO ^<ESC^>[40m [40mBlack[0m
+REM ECHO ^<ESC^>[41m [41mRed[0m
+REM ECHO ^<ESC^>[42m [42mGreen[0m
+REM ECHO ^<ESC^>[43m [43mYellow[0m
+REM ECHO ^<ESC^>[44m [44mBlue[0m
+REM ECHO ^<ESC^>[45m [45mMagenta[0m
+REM ECHO ^<ESC^>[46m [46mCyan[0m
+REM ECHO ^<ESC^>[47m [47mWhite[0m (white)
+REM ECHO.
+REM ECHO [101;93m STRONG FOREGROUND COLORS [0m
+REM ECHO ^<ESC^>[90m [90mWhite[0m
+REM ECHO ^<ESC^>[91m [91mRed[0m
+REM ECHO ^<ESC^>[92m [92mGreen[0m
+REM ECHO ^<ESC^>[93m [93mYellow[0m
+REM ECHO ^<ESC^>[94m [94mBlue[0m
+REM ECHO ^<ESC^>[95m [95mMagenta[0m
+REM ECHO ^<ESC^>[96m [96mCyan[0m
+REM ECHO ^<ESC^>[97m [97mWhite[0m
+REM ECHO.
+REM ECHO [101;93m STRONG BACKGROUND COLORS [0m
+REM ECHO ^<ESC^>[100m [100mBlack[0m
+REM ECHO ^<ESC^>[101m [101mRed[0m
+REM ECHO ^<ESC^>[102m [102mGreen[0m
+REM ECHO ^<ESC^>[103m [103mYellow[0m
+REM ECHO ^<ESC^>[104m [104mBlue[0m
+REM ECHO ^<ESC^>[105m [105mMagenta[0m
+REM ECHO ^<ESC^>[106m [106mCyan[0m
+REM ECHO ^<ESC^>[107m [107mWhite[0m
+REM ECHO.
+REM ECHO [101;93m COMBINATIONS [0m
+REM ECHO ^<ESC^>[31m                     [31mred foreground color[0m
+REM ECHO ^<ESC^>[7m                      [7minverse foreground ^<-^> background[0m
+REM ECHO ^<ESC^>[7;31m                   [7;31minverse red foreground color[0m
+REM ECHO ^<ESC^>[7m and nested ^<ESC^>[31m [7mbefore [31mnested[0m
+REM ECHO ^<ESC^>[31m and nested ^<ESC^>[7m [31mbefore [7mnested[0m
+GOTO :EOF
+
+:: ============================================
+:: Coloring of information text in Batch file =
+:: ============================================
+:: There is no native support for ANSI colors on the console till Windows 10 (excluded).
+:: It is rather tricky to color only one line just via CMD - any hack does not work properly with this complex batch file
+:: The best way till Windows 10 is actually to use PowerShell!  In Windows 10 the proper use is to use native ANSI colors (not done yet).
+:printInColor
+SET "background=%1"
+SET "foreground=%2"
+SET "message=%3"
+
+REM Message was "'%*'" but now since we are passing colors we have to limit it
+:: Saves original color and then sets the new color for the message
+SET long_command= ^
+$window_private_data = (Get-Host).PrivateData;^
+$saved_background_color = $window_private_data.VerboseBackgroundColor;^
+$saved_foreground_color = $window_private_data.VerboseForegroundColor;^
+$window_private_data.VerboseBackgroundColor = "'%background%'";^
+$window_private_data.VerboseForegroundColor = "'%foreground%'";^
+Write-Verbose -Message "'%message%'" -Verbose;^
+$window_private_data.VerboseBackgroundColor = $saved_background_color;^
+$window_private_data.VerboseForegroundColor = $saved_foreground_color;
+
+CALL powershell -nologo -noninteractive -NoProfile -ExecutionPolicy Bypass -Command %long_command%
+GOTO :EOF
+
+:time_in_seconds
+FOR /F %%A IN ('wmic os get LocalDateTime ^| find "."') DO (
+    SET dts=%%A
+    REM Issue with octal representation (08 and 09 are invalid octal representation and others are too but are accepted)
+    REM Workaround implemented below:
+    IF "!dts:~8,1!" EQU "0" (
+        SET hours=!dts:~9,1!
+    ) ELSE (
+        SET hours=!dts:~8,2!
+    )
+    SET /A _time_in_seconds=!hours!*3600^
+                            +!dts:~10,1!*10*60^
+                            +!dts:~11,1!*60^
+                            +!dts:~12,1!*10^
+                            +!dts:~13,1! >nul
+)
+SET "%~1=!_time_in_seconds!"
+GOTO :EOF
+
+:: =============================================
+:: Expanding variables from configuration file =
+:: =============================================
+:: Must be last in this section
+:expand
+SET "%~2=%~1"
+GOTO :EOF
+
+
+REM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+REM Next section follows 
+REM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+:: *******************************************************************************************
+:: Support information (like help, about, version)
+:: *******************************************************************************************
+
+:: ==============
+:: Help section =
+:: ==============
+:stx_help
+IF EXIST "stx-bin.com" (
+    CALL stx-bin.com --help
+) ELSE IF EXIST "stx.com" (
+    CALL stx.com --help
+) ELSE (
+    ECHO "[WARN] The executable stx-bin.^(com^|exe^) or stx.^(com^|exe^) NOT found.""
+    ECHO "[WARN] Exiting with error. Script __numeric.exit_value: 1."
+    PAUSE
+    GOTO :EOF
+)
+
+GOTO :EOF
+
+:stx_help_launcher
+ECHO ====================
+ECHO The configuration: =
+ECHO ====================
+ECHO Note: The configuration is done via .cfg file.  The only configuration that can be done in the batch file
+ECHO        is for the configuration file itself.  You can change the configuration path via configuration_file_path variable
+ECHO        and the configuration file name via configuration_file variable.
+ECHO:
+ECHO Note2: Notice that Microsoft is using Unicode as an alias for UTF16 (which is wrong but we have to deal with it).
+ECHO:
+ECHO:
+ECHO ======================================
+ECHO The features of this advanced script =
+ECHO ======================================
+ECHO:
+ECHO -- Quick start (with close or leave open the shell after Smalltalk start)
+ECHO -- Starting with default image on defined path
+ECHO -- Starting with any image (user is prompted to select one via menu) on defined path
+ECHO -- Logging into a file - either overwrite or append at start start (minimal PowerShell 2.0 is required)
+ECHO                        - User can change the log file encoding to ASCII, UTF8 (default), UTF16, UTF32
+ECHO                        - User can decide if he wants a date and/or time part added to the log file
+ECHO -- The script automatically detects PowerShell version and based on that decides which functionality will be available.
+ECHO -- Error handling on the batch and PowerShell level - user is informed about the details of error
+ECHO -- Batch file tries to exit gracefully, if possible
+ECHO:
+ECHO The advanced features:
+ECHO -- A warning limit is in place for the log file size.  If it gets too large as it may slowdown the Smalltalk.
+ECHO -- User can decide if there will be a shell opened for error messages or if Smalltalk will for from shell and
+ECHO    will not display any messages on the command prompt.
+ECHO -- User can choose if the validation process is active and if the successful message is shown.
+ECHO -- User can choose which redirect will be used in PowerShell - if the native one or cmd.exe one (little bit faster in most cases).
+ECHO:
+ECHO:
+ECHO:
+ECHO -------------------------------------------------------------------------------------------
+ECHO User settings
+ECHO -------------------------------------------------------------------------------------------
+ECHO: ===================
+ECHO Stx bin directory =
+ECHO ===================
+ECHO Setting: stx_bin_dir - 
+ECHO Impact: defines the directory containing the executable
+ECHO Note: do not forget the last backslash ^(\^) and double quotes when changing to custom path
+ECHO stx_bin_dir="%~dp0"
+ECHO:
+ECHO ===================================
+ECHO Stx quick start and image details =
+ECHO ===================================
+ECHO Setting: __binary.stx_quick_start
+ECHO Impact: Uses flags --ignoreImage and --quick start to start StX as fast as possible
+ECHO TRUE - switches on the quick start
+ECHO FALSE - skips this option
+ECHO __binary.stx_quick_start=FALSE
+ECHO:
+ECHO Setting: image_path, image_name, image_suffix
+ECHO Impact: variables are self-explanatory
+ECHO Note: do not forget the last backslash ^(\^) and double quotes when changing to custom path
+ECHO image_path="%~dp0"
+ECHO Setting: image_name - how should the default image be named
+ECHO image_name="st"
+ECHO image_suffix=".img"
+ECHO:
+ECHO Impact: Pair variables (affect each other):__binary.start_with_image and __binary.list_available_images
+ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ECHO note: Before using image functionality check image path, name, and suffix
+ECHO:
+ECHO Setting: __binary.start_with_image
+ECHO Impact: Stx starts (or not) with image.
+ECHO TRUE - image functionality will be used
+ECHO FALSE - image functionality ignored
+ECHO __binary.start_with_image=FALSE
+ECHO:
+ECHO Setting: __binary.list_available_images
+ECHO Impact: User menu is show when used; it shows all images within the directory (excluding subdirectories) and users selects one.
+ECHO        If switched off only default image (see image_path, image_name, image_suffix) is used.
+ECHO Note: IF start_with_image=FALSE and list_available_images=TRUE then a warning message is shown and append_to_log is set to FALSE automatically)
+ECHO TRUE - Switches on the user menu
+ECHO FALSE - no interaction from user required
+ECHO __binary.list_available_images=FALSE
+ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ECHO:
+ECHO =================
+ECHO Stx logging     =
+ECHO =================
+ECHO Impact: Pair variables (affect each other): __binary.record_log_file and __binary.append_to_log
+ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ECHO Setting: __binary.record_log_file
+ECHO Impact: Both standard output and standard error are redirected to a log file
+ECHO Note: At least PowerShell 2.0 is required (WindowsXP and newer)
+ECHO TRUE - turns on the logging functionality
+ECHO FALSE - turns off the logging
+ECHO __binary.record_log_file=TRUE
+ECHO:
+ECHO Setting: __binary.append_to_log
+ECHO Impact: Appends the log file.  Uses a PowerShell when appending.
+ECHO Note: IF record_log_file=FALSE and append_to_log=TRUE then a warning message is shown and append_to_log is set to FALSE automatically)
+ECHO TRUE - if log file is found it will be appended.  If not a new one will be created 
+ECHO FALSE - the append functionality is turned off (the log file will be overwritten every time StX is executed)
+ECHO __binary.append_to_log=TRUE
+ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ECHO:
+ECHO Setting: log_directory, log_name, log_suffix
+ECHO Impact: Directory sets a log file directory (others are self-explanatory)
+ECHO If a change would be done, double quotes must be present: e.g. "C:\prg_sdk\Stx_stable\"
+ECHO Note: do not forget the last backslash ^(\^) and double quotes when changing to custom path
+ECHO log_directory="%~dp0"
+ECHO Setting: log_name sets name for log file
+ECHO log_name="smalltalk"
+ECHO log_suffix=".log"
+ECHO:
+ECHO Setting: __binary.log_add_datepart
+ECHO Impact: Adds a date part based on ISO 8601 to the log file; format YYYY-MM-DD ('-' as a separator)
+ECHO TRUE - Switch on this option
+ECHO FALSE - Skips this option
+ECHO __binary.log_add_datepart=TRUE
+ECHO:
+ECHO Setting: __binary.log_add_timepart
+ECHO Impact: Adds a time part to the log file; format hh;mm;ss (non-ISO ';' as a separator)
+ECHO Note: the ISO 8601 separator is not compatible with file-system)
+ECHO TRUE - Switch on this option
+ECHO FALSE - Skips this option
+ECHO __binary.log_add_timepart=FALSE
+ECHO:
+ECHO Setting: log_file_encoding
+ECHO Impact: Changes log file encoding
+ECHO Allowed values ASCII, UTF8 (default), UTF16 (in Microsoft world that is called Unicode), UTF32
+ECHO Note: only UTF16 is using Tee-Object which enables you to have all the features the developer envisioned for the logging process
+ECHO       you can simultaneously see the output in shell, view the log file while using StX and have the wished encoding
+ECHO       all other encodings carry some limitation due to the powershell tools limitation
+ECHO log_file_encoding=UTF8
+ECHO:
+ECHO =================
+ECHO Stx shell       =
+ECHO =================
+ECHO Setting: __binary.close_shell
+ECHO Impact: When set to TRUE closes the shell upon StX exit
+ECHO TRUE - Switch on this option
+ECHO FALSE - Skips this option
+ECHO __binary.close_shell=TRUE
+ECHO:
+ECHO Setting: __binary.run_via_shell
+ECHO Impact: start with shell (.com) or just the GUI without shell (.exe)
+ECHO TRUE - uses stx.com executable
+ECHO FALSE - uses stx.exe executable
+ECHO __binary.run_via_shell=TRUE
+ECHO:
+ECHO:
+ECHO -------------------------------------------------------------------------------------------
+ECHO Advanced user settings
+ECHO -------------------------------------------------------------------------------------------
+ECHO ====================
+ECHO Validate variables =
+ECHO ====================
+ECHO: Setting: verify_variables_syntax
+ECHO Impact: Verifies the syntax of the batch file variables - e.g. batch file is very picky on spaces
+ECHO TRUE - active validation
+ECHO FALSE - inactive validation (NOT recommended)
+ECHO verify_variables_syntax=TRUE
+ECHO:
+ECHO Setting: verify_print_message
+ECHO Impact: shows message when the verification is complete
+ECHO TRUE - Switch on this option
+ECHO FALSE - message is not shown
+ECHO verify_print_message=FALSE
+ECHO:
+ECHO =======================
+ECHO Log file size warning =
+ECHO =======================
+ECHO Setting: __numeric.warning_logfile_size - Above what file size should a log file warning be shown?
+ECHO Impact: If the limit is reached a warning message is shown to the user
+ECHO Print user waring if the log file is getting too big - for 32MB in bytes
+ECHO the bigger log-file, the slower the logging process gets
+ECHO __numeric.warning_logfile_size=33554432
+ECHO:
+ECHO ====================
+ECHO Stdout redirection =
+ECHO ====================
+ECHO Setting: cmd_in_powershell
+ECHO Impact: The cmd.exe redirection is faster even when called from powershell
+ECHO         There could be unforeseen issues with it so there is a switch (no manual switches are allowed)
+ECHO         When no colors are used then black background and gray foreground is used (warning messages are still highlighted)
+ECHO         When colors are used then the same color schema is used
+ECHO TRUE - uses cmd.exe for redirecting output
+ECHO FALSE - uses powershell for redirection (default)
+ECHO __binary.cmd_in_powershell=TRUE
+ECHO:
+ECHO =============
+ECHO Start timer =
+ECHO =============
+ECHO Setting: use_timer
+ECHO Impact: Measures time between start of the script and correct ending. Measurement unit are seconds.
+ECHO TRUE - uses timer
+ECHO FALSE - switches off timer
+ECHO __binary.use_timer=FALSE
+ECHO:
+ECHO ==============
+ECHO Colored text =
+ECHO ==============
+ECHO Setting: colored_stdout
+ECHO Impact: Will adjust based on the color setting the stdout output from both batch and powershell
+ECHO        note: in powershell there are default colors used when setting is is turned off (FALSE.
+ECHO TRUE - uses colored output
+ECHO FALSE - uses default colors available
+ECHO __binary.colored_stdout=TRUE
+ECHO:
+ECHO ===================
+ECHO Stdout text color =
+ECHO ===================
+ECHO colors that can be used
+ECHO Black, DarkBlue, DarkGreen, DarkCyan, DarkRedDarkMagenta, DarkYellow,
+ECHO Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
+ECHO:
+ECHO - verbose text (this is color used for normal usually [INFO] messages)
+ECHO stdout_VerboseBackgroundColor=Black
+ECHO stdout_VerboseForegroundColor=DarkGreen
+ECHO:
+ECHO - warning text
+ECHO stdout_WarningBackgroundColor=Black
+ECHO stdout_WarningForegroundColor=Yellow
+ECHO:
+ECHO - error
+ECHO stdout_ErrorBackgroundColor=White
+ECHO stdout_ErrorForegroundColor=Red
+ECHO:
+ECHO:
+ECHO:
+ECHO ===================
+ECHO Known limitations =
+ECHO ===================
+ECHO:
+ECHO 1) For any logging you need to have at least PowerShell 2.0
+ECHO 2) User menu searches only the log_directory.  The subdirectories are excluded from the search (doable but the script is already too complex)
+ECHO 3) When logging user can chose to use colors or not.  If user does not wish to have custom color then no color for batch file and native colors in powershell are used.
+ECHO 4) When using "pure" powershell redirection an error is shown at the start of the log file that is a bug in powershell (produces error: FullyQualifiedErrorId : NativeCommandError ) 
+ECHO    The error can be ignored.
+ECHO 5) The .lnk files are tested on Windows 7 SP1 (known to not work on Windows XP, you have to use the batch file directly.)
+ECHO 6) When using CMD PowerShell mode manual (user) switches can not be used.  When used the batch file forces CMD only mode.
+ECHO:
+ECHO:
+ECHO:
+ECHO usage: (%~nx0) [--help] [--help-launcher] [--about] [--version] [stx shell switches]
+ECHO:
+ECHO args to startup script:
+ECHO       --help or -h or /h or /? ................ displays "stx.com" help
+ECHO       --help-launcher or -h-l or /h-l ......... displays "%~nx0" help
+ECHO       --about or -a or /a      ................ shows about section
+ECHO       --version or -v or /v    ................ version information about %~nx0 and Smalltalk/X
+ECHO:
+ECHO In the future:
+ECHO      --ldd .................. show which shared libraries are used - NOT DONE YET
+ECHO      --gdb .................. run with gdb-Debugger - NOT DONE YET
+ECHO      --cgdb ................. run with cgdb-Debugger - NOT DONE YET
+ECHO:
 
-: change the line below, if
-: the support stuff is not found in the
-: directory where stx.com / stx.exe resides ...
-: STX_LIB_DIR=<path_to_support_files>
-set STX_BIN_DIR=%~dp0
-set VERSION=6.2.6
-if exist %STX_BIN_DIR%\stx-bin.com (	
-	set "STX_HOME=%STX_BIN_DIR%.."	
-	set "STX_TOPDIR=%STX_BIN_DIR%..\lib\smalltalkx\%VERSION%"
-	set "STX_LIBDIR=%STX_BIN_DIR%..\lib\smalltalkx\%VERSION%\lib"
-	set "STX_EXE=%STX_BIN_DIR%stx-bin.com"	
-) else (
-	set "STX_EXE=%STX_BIN_DIR%stx.com"
-)
+:: This section is commented out on purpose - There are tricks for batch files -> does not need to be part of the user help
+
+:: " =================================="
+:: " Batch or Powershell Tip & tricks ="
+:: " =================================="
+
+:: " =============================================="
+:: " Tee-Object, Add-Content, Out-File + encoding ="
+:: " =============================================="
+::The 'Tee-object' and Add-Content was introduced in PowerShell 3.0 -> that the reason why there is such limitation.
+::
+::The reason why the script is using also different logging types than 'Tee-object' is the fact that 'Tee-Object'
+::supports only UTF16 (alias Unicode in Microsoft world) encoding.
+::Note: 'Tee-Object' append flag is '-a' (note: for 'tee' command it is '--append')
+::
+::'Add-content' can change encoding and you can view the messages in the shell but you can not view the file when StX is running (locked even for read)
+::'Out-File' can also change encoding, but you will not see the messages in the shell (only in StX launcher).  On the other hand you can view the file during
+::StX session.
+
+:: " =============================================="
+:: " Empty lines in batch files ="
+:: " =============================================="
+:: NOTE: ECHO: is a reliable and fast way to print empty line.  Other ways are: ECHO( ECHO/
+
+:: " =============="
+:: " Redirections ="
+:: " =============="
+
+REM powershell ... cmd.exe /c command '2>&1' -> Let cmd.exe handle redirection
+REM powershell ... cmd.exe /c command 2>&1 -> Let powershell.exe handle redirection
+
+REM Details
+REM PowerShell:
+REM cmd.exe /c command 2>&1 -> redirect error stream (2) to success stream (1)
+REM fixes it when running from within PS but not the command prompt
+
+REM Batch file:
+REM ...cmd /c "ECHO "Hello from standard error 1>&2" 2>&1 | %{ "$_" } | tee... 
+REM 
+
+:: " ====================="
+:: " Exiting batch files ="
+:: " ====================="
+:: To require pressing ctrl+C from the user (alias force ctrl+C)
+:: cmd /c exit -1073741510
+
+:: To directly exit user function (used via CALL)
+:: This is a "trick" to exit directly the function
+:: (GOTO) 2^^>NUL behaves nearly same as exit /B but executes the block behind it
+:: (GOTO) 2>NUL & ENDLOCAL & EXIT /B 1
+
+:: " ========================"
+:: " Miscellaneous in batch ="
+:: " ========================"
+:: A nice solution for printing out a known number of options:
+:: for %%I in (1 2 3 4 5 x) do if #%user_input%==#%%I goto run%%I
+:: then you have to have label for every number e.g. :run1, :run2
 
-
-
-%STX_EXE% %1 %2 %3 %4 %5 %6 %7 %8 %9 %10
-goto end
+GOTO :EOF
 
-:usage
-echo.
-echo usage: smalltalk stx-args
-echo.
-echo STX args:
-%STX_EXE% --help
+:: ===============
+:: About section =
+:: ===============
+:stx_about
+ECHO " _____                 _ _ _        _ _         ____   __               "
+ECHO "/  ___|               | | | |      | | |       / /\ \ / /               "
+ECHO "\ `--. _ __ ___   __ _| | | |_ __ _| | | __   / /  \ V /                "
+ECHO " `--. \ '_ ` _ \ / _` | | | __/ _` | | |/ /  / /   /   \                "
+ECHO "/\__/ / | | | | | (_| | | | || (_| | |   <  / /   / /^\ \               "
+ECHO "\____/|_| |_| |_|\__,_|_|_|\__\__,_|_|_|\_\/_/    \/   \/               "
+ECHO "                                                                        "
+ECHO " _    _ _                  _                            _               "
+ECHO "| |  | (_)                | |                          | |              "
+ECHO "| |  | |_ _ __    ______  | |     __ _ _   _ _ __   ___| |__   ___ _ __ "
+ECHO "| |/\| | | '_ \  |______| | |    / _` | | | | '_ \ / __| '_ \ / _ \ '__|"
+ECHO "\  /\  / | | | |          | |___| (_| | |_| | | | | (__| | | |  __/ |   "
+ECHO " \/  \/|_|_| |_|          \_____/\__,_|\__,_|_| |_|\___|_| |_|\___|_|   "
+ECHO:
+ECHO Author:   Patrik Svestka
+ECHO Contact: "patrik.svestka|dot|gmail<dot>com"
+ECHO Alias:    tukanos
+ECHO You can find me at: Bitbucket(https://bitbucket.org/-tukanos-/) or github (https://github.com/tukanos/)
+ECHO:
+ECHO License:  MIT License (more at https://opensource.org/licenses/MIT)
+ECHO:
+ECHO Versions: The %~nx0 executed is at version: "=>%~1<="
+ECHO           Smalltalk/X is at version: "=>%~2<="
+ECHO:
+ECHO Special thanks:   Jan Vrany         - for Smalltalk and VM support during writing of this script
+ECHO                   Claus Gittinger   - for creating all Smalltalk/X environment
+ECHO:
+ECHO                   Rob van der Woude - for having great pages about batch files  (http://http://www.robvanderwoude.com)
+ECHO                   Simon Sheppard - for having great catalog at (https://ss64.com/nt/)
+ECHO:
+ECHO This script was tested on: Windows 7 SP1 x64 (enterprise), Windows XP SP3 x86 (stx-bin),
+ECHO                            Windows 10 Pro (10.0.14393), (thanks Jan), Window 2008 R2 SP1 x64 (enterprise)
+ECHO:
+ECHO Short description: This file enables you to run stx(-bin).com(exe) with additional features like:
+ECHO Logging, quick start, starting via image (default or with user interaction), etc.
+ECHO:
+ECHO To find out more on how to run this .bat file with --help-launcher switch
 
-:end
+GOTO :EOF
+
+:: =================
+:: Version section =
+:: =================
+:stx_version
+ECHO The %~nx0 executed is at version: "=>%~1<="
+ECHO:
+ECHO Smalltalk/X is at version: "=>%~2<="
+
+GOTO :EOF
+
+:: *******************************************************************************************
+:: End                                                                                       *
+:: *******************************************************************************************
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smalltalk.cfg	Wed Jul 12 10:25:43 2017 +0200
@@ -0,0 +1,199 @@
+# -------------------------------------------------------------------------------------------
+# User settings
+# -------------------------------------------------------------------------------------------
+# ===================
+# Stx bin directory =
+# ===================
+# Setting: stx_bin_dir - 
+# Impact: defines the directory containing the executable
+# Note: do not forget the last backslash ^(\^) and double quotes when changing to custom path
+stx_bin_dir="%~dp0"
+
+# ===================================
+# Stx quick start and image details =
+# ===================================
+# Setting: __binary.stx_quick_start
+# Impact: Uses flags --ignoreImage and --quick start to start StX as fast as possible
+# TRUE - switches on the quick start
+# FALSE - skips this option
+__binary.stx_quick_start=FALSE
+
+# Setting: image_path, image_name, image_suffix
+# Impact: variables are self-explanatory
+# Note: do not forget the last backslash ^(\^) and double quotes when changing to custom path
+image_path="%~dp0"
+# Setting: image_name - how should the default image be named
+image_name="st"
+image_suffix=".img"
+
+# Impact: Pair variables (affect each other):__binary.start_with_image and __binary.list_available_images
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# note: Before using image functionality check image path, name, and suffix
+
+# Setting: __binary.start_with_image
+# Impact: Stx starts (or not) with image.
+# TRUE - image functionality will be used
+# FALSE - image functionality ignored
+__binary.start_with_image=FALSE
+
+# Setting: __binary.list_available_images
+# Impact: User menu is show when used; it shows all images within the directory (excluding subdirectories) and users selects one.
+#         If switched off only default image (see image_path, image_name, image_suffix) is used.
+# Note: IF start_with_image=FALSE and list_available_images=TRUE then a warning message is shown and append_to_log is set to FALSE automatically)
+# TRUE - Switches on the user menu
+# FALSE - no interaction from user required
+__binary.list_available_images=FALSE
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+# =================
+# Stx logging     =
+# =================
+# Impact: Pair variables (affect each other): __binary.record_log_file and __binary.append_to_log
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Setting: __binary.record_log_file
+# Impact: Both standard output and standard error are redirected to a log file
+# Note: At least PowerShell 2.0 is required (WindowsXP and newer)
+# TRUE - turns on the logging functionality
+# FALSE - turns off the logging
+__binary.record_log_file=TRUE
+
+# Setting: __binary.append_to_log
+# Impact: Appends the log file.  Uses a PowerShell when appending.
+# Note: IF record_log_file=FALSE and append_to_log=TRUE then a warning message is shown and append_to_log is set to FALSE automatically)
+# TRUE - if log file is found it will be appended.  If not a new one will be created 
+# FALSE - the append functionality is turned off (the log file will be overwritten every time StX is executed)
+__binary.append_to_log=TRUE
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+# Setting: log_directory, log_name, log_suffix
+# Impact: Directory sets a log file directory (others are self-explanatory)
+# If a change would be done, double quotes must be present: e.g. "C:\prg_sdk\Stx_stable\"
+# Note: do not forget the last backslash ^(\^) and double quotes when changing to custom path
+log_directory="%~dp0"
+# Setting: log_name sets name for log file
+log_name="smalltalk"
+log_suffix=".log"
+
+# Setting: __binary.log_add_datepart
+# Impact: Adds a date part based on ISO 8601 to the log file; format YYYY-MM-DD ('-' as a separator)
+# TRUE - Switch on this option
+# FALSE - Skips this option
+__binary.log_add_datepart=TRUE
+
+# Setting: __binary.log_add_timepart
+# Impact: Adds a time part to the log file; format hh;mm;ss (non-ISO ';' as a separator)
+# Note: the ISO 8601 separator is not compatible with file-system)
+# TRUE - Switch on this option
+# FALSE - Skips this option
+__binary.log_add_timepart=FALSE
+
+# Setting: log_file_encoding
+# Impact: Changes log file encoding
+# Allowed values ASCII, UTF8 (default), UTF16 (in Microsoft world that is called Unicode), UTF32
+# Note: only UTF16 is using Tee-Object which enables you to have all the features the developer envisioned for the logging process
+#        you can simultaneously see the output in shell, view the log file while using StX and have the wished encoding
+#        all other encodings carry some limitation due to the powershell tools limitation
+log_file_encoding=UTF8
+
+# =====================
+# Log file line width =
+# =====================
+# Setting: log_file_encoding
+# Impact: Sets log file line width when out-file is used (all except UTF16)
+# Allowed values: only numeric
+__numeric.log_file_width=150
+
+# =================
+# Stx shell       =
+# =================
+# Setting: __binary.close_shell
+# Impact: When set to TRUE closes the shell upon StX exit
+# TRUE - Switch on this option
+# FALSE - Skips this option
+__binary.close_shell=TRUE
+
+# Setting: __binary.run_via_shell
+# Impact: start with shell (.com) or just the GUI without shell (.exe)
+# TRUE - uses stx.com executable
+# FALSE - uses stx.exe executable
+__binary.run_via_shell=TRUE
+
+
+# -------------------------------------------------------------------------------------------
+# Advanced user settings
+# -------------------------------------------------------------------------------------------
+# ====================
+# Validate variables =
+# ====================
+# Setting: verify_variables_syntax
+# Impact: Verifies the syntax of the batch file variables - e.g. batch file is very picky on spaces
+# TRUE - active validation
+# FALSE - inactive validation (NOT recommended)
+verify_variables_syntax=TRUE
+
+# Setting: verify_print_message
+# Impact: shows message when the verification is complete
+# TRUE - Switch on this option
+# FALSE - message is not shown
+verify_print_message=FALSE
+
+# =======================
+# Log file size warning =
+# =======================
+# Setting: __numeric.warning_logfile_size - Above what file size should a log file warning be shown?
+# Impact: If the limit is reached a warning message is shown to the user
+# Allowed values: only numeric
+# Print user waring if the log file is getting too big - for 32MB in bytes
+# the bigger log-file, the slower the logging process gets
+__numeric.warning_logfile_size=33554432
+
+# ====================
+# Stdout redirection =
+# ====================
+# Setting: cmd_in_powershell
+# Impact: The cmd.exe redirection is faster even when called from powershell
+#         There could be unforeseen issues with it so there is a switch (no manual switches are allowed)
+#         When no colors are used then black background and gray foreground is used (warning messages are still highlighted)
+#          When colors are used then the same color schema is used
+# TRUE - uses cmd.exe for redirecting output
+# FALSE - uses powershell for redirection (default)
+__binary.cmd_in_powershell=FALSE
+
+# ====================
+# Start timer =
+# ====================
+# Setting: use_timer
+# Impact: Measures time between start of the script and correct ending. Measurement unit are seconds.
+# TRUE - uses timer
+# FALSE - switches off timer
+__binary.use_timer=FALSE
+
+# ==============
+# Colored text =
+# ==============
+# Setting: colored_stdout
+# Impact: Will adjust based on the color setting the stdout output from both batch and powershell
+#        note: in powershell there are default colors used when setting is is turned off (FALSE.
+# TRUE - uses colored output
+# FALSE - uses default colors available
+__binary.colored_stdout=TRUE
+
+# ===================
+# Stdout text color =
+# ===================
+# colors that can be used
+# To find all the colors in powershell: `[enum]::GetValues([System.ConsoleColor]) | Foreach-Object {Write-Host $_ -ForegroundColor $_ }`
+# Black, DarkBlue, DarkGreen, DarkCyan, DarkRedDarkMagenta, DarkYellow,
+# Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
+
+# verbose text (this is color used for normal usually [INFO] messages)
+stdout_VerboseBackgroundColor=Black
+stdout_VerboseForegroundColor=DarkGreen
+
+# warning text
+stdout_WarningBackgroundColor=Black
+stdout_WarningForegroundColor=Yellow
+
+# error
+stdout_ErrorBackgroundColor=White
+stdout_ErrorForegroundColor=Red
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smalltalk.ps1	Wed Jul 12 10:25:43 2017 +0200
@@ -0,0 +1,324 @@
+# This file inherits the licencing from the batch file. (MIT)
+# $executable        ... stx.com or .exe
+# $log_file          ... log file name with path
+# $log_file_encoding ... user defined encoding
+# $append_to_log     ... should the log file be appended? (TRUE/FALSE)
+# $cmd_close         ... sends either cmd /u /c (close cmd) or /u /k (cmd remains open)
+# $PowerShellVersion ... detected powershell version
+# $cmd_in_powershell ... should cmd.exe be used for stdout redirection? (TRUE/FALSE)
+param($executable, $log_file, $log_file_encoding, $append_to_log, $cmd_close, $PowerShellVersion, $cmd_in_powershell, $stx_manual_switch_detected);
+
+
+# ===========================================================================
+# Reading directly from environment - due to the issues with passing quotes =
+# ===========================================================================
+# StX switches which are build during batch file execution $env:stx_switch;
+$stx_switch = [environment]::GetEnvironmentVariable("stx_switch");
+# PowerShell version detected during batch file execution  $env:powershell_version_all_functionality;
+$stx_powershell_version = [environment]::GetEnvironmentVariable("powershell_version_all_functionality");
+# getting line width for the log file
+$log_file_width = [environment]::GetEnvironmentVariable("stx.__numeric.log_file_width");
+
+
+# =======================================================
+# Adjust all variables to PowerShell style $true/$false =
+# =======================================================
+
+If ([environment]::GetEnvironmentVariable("stx.__binary.colored_stdout") -eq 'TRUE') {
+    $use_color = $true;
+} Else {
+    $use_color = $false;
+}
+
+If ($cmd_in_powershell -eq 'TRUE') {
+    $cmd_in_powershell = $true;
+} Else {
+    $cmd_in_powershell = $false;
+}
+
+If ($append_to_log -eq 'TRUE') {
+    $append_to_log = $true;
+} Else {
+    $append_to_log = $false;
+}
+
+If ($stx_manual_switch_detected -eq 'TRUE') {
+    $stx_manual_switch_detected = $true;
+} Else {
+    $stx_manual_switch_detected = $false;
+}
+
+If ($use_color) {
+    # fastest way to init empty Hastable
+    $saved_color = [System.Collections.Hashtable]@{};
+    # save colors for later restore
+    $window_private_data = (Get-Host).PrivateData;
+    $saved_color.Add('VerboseBackgroundColor', "$window_private_data.VerboseBackgroundColor") | Out-null; # Out-null for supressing the natural output
+    $saved_color.Add('VerboseForegroundColor', "$window_private_data.VerboseForegroundColor") | Out-null;
+    $saved_color.Add('WarningBackgroundColor', "$window_private_data.WarningBackgroundColor") | Out-null;
+    $saved_color.Add('WarningForegroundColor', "$window_private_data.WarningForegroundColor") | Out-null;
+    $saved_color.Add('ErrorBackgroundColor', "$window_private_data.ErrorBackgroundColor") | Out-null;
+    $saved_color.Add('ErrorForegroundColor', "$window_private_data.ErrorForegroundColor") | Out-null;
+    #setting the user specified colors
+    $window_private_data.VerboseBackgroundColor = [environment]::GetEnvironmentVariable("stx.stdout_VerboseBackgroundColor");
+    $window_private_data.VerboseForegroundColor = [environment]::GetEnvironmentVariable("stx.stdout_VerboseForegroundColor");
+    $window_private_data.WarningBackgroundColor = [environment]::GetEnvironmentVariable("stx.stdout_WarningBackgroundColor");
+    $window_private_data.WarningForegroundColor = [environment]::GetEnvironmentVariable("stx.stdout_WarningForegroundColor");
+    $window_private_data.ErrorBackgroundColor = [environment]::GetEnvironmentVariable("stx.stdout_ErrorBackgroundColor");
+    $window_private_data.ErrorForegroundColor = [environment]::GetEnvironmentVariable("stx.stdout_ErrorForegroundColor");
+} ElseIf ($cmd_in_powershell) {
+    $window_private_data = (Get-Host).PrivateData;
+    $window_private_data.VerboseBackgroundColor = 'Black';
+    $window_private_data.VerboseForegroundColor = 'Gray';
+}
+
+
+# ===========
+# Functions =
+# ===========
+
+# Function for correct $LASTEXITCODE to ERRORLEVEL passing
+function ExitWithCode {
+    param (
+        $exitcode
+    )
+    $host.SetShouldExit($exitcode);
+    EXIT;
+} # end ExitWithCode
+
+# Print User message using String Array $message
+function PrintMessage {
+    param(
+        [Parameter( `
+            Mandatory=$True, `
+            Valuefrompipeline = $true)]
+        [String]$message
+    )
+    begin {}
+    process {
+        foreach ($Message in $Message) {
+            # Write-Host Considered Harmful - see http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/
+            # first way how to correctly write it
+            #Write-host $message;
+            # highlights warning and error messages from StX VM!
+            If ($message -match '\[ERROR\]') {
+                $host.ui.WriteErrorLine("$message");
+            } ElseIf ($message -match '\[WARN\]') {
+                Write-Warning $message;
+            } Else {
+                Write-Verbose -Message $message -Verbose;
+            } 
+        }
+    }
+    end {}
+} # end PrintMessage
+
+
+# To correctly simultinously write to stdout and log file when using out-file!
+# Colors the output based on string match
+function Tee-Host {
+    Param (
+        [Parameter(Mandatory=$true,
+        ValueFromPipeline=$true,
+        Position=0)]
+        $message
+    )
+    begin {}
+    Process {
+        # first way how to correctly write it
+        # -EV is short (an alias) for -ErrorVariable
+        If ($message -match '\[error\]') {
+            # this is printing error compatible with all PS versions
+            $host.ui.WriteErrorLine("$message");
+        } ElseIf ($message -match '\[warning\]') {
+            Write-Warning "$message";
+        } Else {
+            Write-Verbose -Message "$message" -Verbose;
+        }
+        # second correct way how to write it
+        #$VerbosePreference = "Continue"
+        #Write-Verbose $input_object; 
+        return $message
+    }
+    end {}
+} # end Tee-Host
+
+function ExecuteCommand {
+    param(
+       $execute_command
+    )
+    try {
+       Invoke-Expression -Command:$execute_command
+       If ($lastexitcode -ne 0) {
+           $result = $result -join "`n";
+           throw "$result `n";
+       }
+    }
+    catch {
+        $window_private_data = (Get-Host).PrivateData;
+        # saving the original colors
+        $saved_background_color = $window_private_data.ErrorBackgroundColor
+        $saved_foreground_color = $window_private_data.ErrorForegroundColor
+        # setting the new colors
+        $window_private_data.ErrorBackgroundColor = 'White';
+        $window_private_data.ErrorForegroundColor = 'Red';
+
+        $host.ui.WriteErrorLine("[ERROR] happned in PowerShell (can be also stx.com) - See log file: $log_file.");
+        Write-Error "`n`n[ERROR] Error from PowerShell:`n`n $_" 2>> $log_file;
+
+        $window_private_data.ErrorBackgroundColor = $saved_background_color;
+        $window_private_data.ErrorForegroundColor = $saved_foreground_color;
+    }
+} # end ExecuteCommand
+
+
+# =============================
+# check if log file is locked =
+# =============================
+function Test-FileLock {
+    param (
+      [parameter(Mandatory=$true)][string]$path
+    )
+    $log_file = New-Object System.IO.FileInfo $path
+    If ((Test-Path -Path $path) -eq $false) {
+        return $false
+    }
+
+    try {
+      $log_file_stream = $log_file.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
+      If ($log_file_stream) {
+          $log_file_stream.Close()
+      }
+      $false
+    } catch {
+      # file is locked by a process.
+      return $true
+    }
+}
+
+
+# ========================================================================
+# Check if user did not start the PowerShell file directly - exit if yes =
+# ========================================================================
+If ([string]::IsNullOrEmpty($executable)) {
+    "`n", '[ERROR] You can not run this powershell script directly!', 'Execute batch file (.bat) instead.' | PrintMessage;
+    EXIT 1;
+}
+
+
+# ====================================
+# Checking the state of the log file =
+# ====================================
+# Must be done only once in the file in case 
+# the file is unlocked before the second instance is closed
+$is_logfile_locked = Test-FileLock($log_file)
+
+# ================
+# Stdout logging =
+# ================
+If ($is_logfile_locked){
+    "`n", "[WARN] Log file $log_file in use.`n`n  !!NO LOGGING will be available for this Smalltalk/X instance!!" | PrintMessage;
+    '[INFO] Press any key to continue ...' | PrintMessage;
+    # waits for pressing any key
+    $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-null;
+    $logging_function = "Tee-Host | Out-null";
+} Else {
+    If ($append_to_log) {
+        $logging_function = "Tee-Host | Out-File -Append -Encoding $log_file_encoding -FilePath $log_file -Width $log_file_width";
+    } Else {
+        $logging_function = "Tee-Host | Out-File -Encoding $log_file_encoding -FilePath $log_file -Width $log_file_width";
+    }
+}
+
+
+# ===========
+# Execution =
+# ===========
+# Decide which stdout use - either powershell.exe or cmd.exe
+If ($PowerShellVersion -ge $stx_powershell_version) {
+    # stdout output via powershell.exe
+    If (!$cmd_in_powershell) {
+        # --% was introduced in PowerShell 3.0, forces PowerShell to ignore all code afterwards
+        # redirection from 9 - combined (all output combined into a single - easy to redirect stream) from Powershell
+        # if manual switch detected force powershell to ignore all code afterwards
+        If ($stx_manual_switch_detected) {
+            $stx_switch = "--% $stx_switch";
+        }
+        $command = @"
+$executable $stx_switch 2>&1 | $logging_function;
+"@
+        # Due to the PowerShell bug produces FullyQualifiedErrorId : NativeCommandError in the log file -> you can ignore it.
+        # actual execution
+        ExecuteCommand -execute_command $command;
+    # stdout output via cmd.exe
+    } Else {
+        # check if manual switch detected
+        If ($stx_manual_switch_detected) {
+            # if manual switch detected force powershell to ignore all code afterwards
+            $stx_switch = "--% $stx_switch";
+            $command = @"
+cmd.exe $cmd_close $executable $stx_switch '2^>^&1' ^| $logging_function
+"@
+        } Else {
+            # must replace double quotes in order for the cmd.exe to work correctly - cmd.exe requirement
+            $stx_switch = $stx_switch -replace '"','^"';
+            $command = @"
+cmd.exe $cmd_close $executable $stx_switch '2>&1' | $logging_function
+"@
+        }
+        
+        # Due to the PowerShell bug may produce an error: "FullyQualifiedErrorId : NativeCommandError" in the log file -> you can ignore it.
+        # actual execution
+        Write-verbose -message $command -verbose;
+        ExecuteCommand -execute_command $command;
+    } # end Else
+} Else { # legacy powershell - no manual switches available!
+    # stdout output via powershell.exe
+    If (!$cmd_in_powershell) {
+        $command = @"
+$executable $stx_switch 2>&1 | $logging_function
+"@
+        # Due to the PowerShell bug produces FullyQualifiedErrorId : NativeCommandError in the log file -> you can ignore it.
+        # actual execution
+        ExecuteCommand -execute_command $command;
+    # stdout output via cmd.exe
+    } Else {
+        # must replace double quotes in order for the cmd.exe to work correctly??
+        $stx_switch = $stx_switch -replace '"','^"';
+        $command = @"
+cmd.exe $cmd_close $executable $stx_switch '2>&1' | $logging_function
+"@
+        # Due to the PowerShell bug produces FullyQualifiedErrorId : NativeCommandError in the log file -> you can ignore it.
+        # actual execution
+        ExecuteCommand -execute_command $command;
+    }
+} # end if
+
+
+# =========================================
+# Add Separator when adding into the file =
+# =========================================
+If (!$is_logfile_locked){
+    If ($append_to_log) {
+        Write-Output "`r`n=================================================================================================`r`n" >> $log_file;
+    }
+}
+
+# ===============================
+# Restore original Shell colors =
+# ===============================
+#TODO:
+If ($use_color) {
+    $window_private_data = (Get-Host).PrivateData;
+    ForEach($item in $saved_color.GetEnumerator()) {
+        Set-Variable -name "$window_private_data.$($item.Key)" -Value "$($item.Value)";
+    }
+}
+
+
+# ======
+# Exit =
+# ======
+# Sending exit code to calling batch file
+"`n", "[INFO] Exiting from PowerShell with code $LASTEXITCODE" | PrintMessage;
+ExitWithCode -exitcode $LASTEXITCODE;
\ No newline at end of file
Binary file smalltalk_close_shell.lnk has changed
Binary file smalltalk_shell_remains_open.lnk has changed