Scripts in Application Streaming are powerful beasts; powerful – and underutilized. Today’s post provides an introduction to how they work, what a script is and how you can do things in scripts to manipulate the execution of virtualized applications.
Foundations in executing scripts
Scripts can be run INSIDE of isolation, OUTSIDE of isolation, pre-launch and post-exit. Scripts can be in “unlimited” quantity and they can even be disabled.
The part of script design that is “kinda cool” is that all scripts are BINARY. Batch files to VBS and executable programs, they are all treated the same, binary. “Scripts” are anything that can be launched with Windows API ShellExecuteEx(). When you select a script in the profiler, it is “sucked into” the profile/target and then travels with the profile.
Scripts can be defined as profile level or target level. Each execution target has a configuration property that says “use profile level scripts”. This is on/off and is normally on. If “on”, then the when the streaming execution target is loaded into a sandbox, the profile level scripts are utilized. This is handy so that even if a profile has lots of targets, there is only one set of scripts to maintain, but it provides an ability for each target to specify its own scripts if this is needed.
The panel in the streaming profiler where scripts are defined looks like this.
By treating all scripts as binary, executables and batch files are processed the same way. In the above example, the .CMD files could just as easily be .EXE.
Since everything is binary, there is no text edit facility to manipulate scripts. Scripts are read in during profiling and then they are part of the profile. To update a script, the procedure is to delete the script and then re-add.
Unlimited number of scripts
There is “no limit” to the number of scripts. The script data structures are all on linked lists with no effective limit to the quantity. I suppose you could add so many that you’d run out of disk space or RAM for allocating items on a list, but this isn’t likely.
Internal storage of scripts
Inside of the streaming profile data formats, all scripts are stored in a single directory. Pre-Launch and Post-Exit, are described in the GUI as separate sub-panels, but internally, all the scripts are stored in a single directory. You will see this as \Scripts beneath the profile and \Scripts beneath the top directory of a streaming execution target, below the GUID_V directory or same inside the CAB.
Profile level scripts are stored in a profile level scripts directory. Each target has its own scripts directory. These directories are separate.
Observe that since all scripts are stored in the same place, the same named script cannot be used for both pre-launch and post-exit. Well, actually it can. The profiler GUI permits this and we had to leave it enabled because of installed base, but in principle, each named script (file) should be unique. If you use the same name, when you add the second script, it will overwrite the first. Not recommended.
When scripts are run by the streaming client, they are run from a single directory.
You as the script author do not know where that directory will be, but you are promised that all scripts, I mean all of them, will be extracted to that single directory before any of the scripts are executed. This is critical for use of .DLLs or data files as “scripts” where that non-executable content may support the execution of another “script”.
Scripts are ALWAYS run using the USER’s credentials. If the user is a user, then the script is a user so there are limits to the things you can adjust. In general, the script can adjust things in the “top” layer of isolation and can adjust user adjustable things inside of the user profile such as \users\username or HKCU.
Do not update scripts outside of the profiler
On the App Hub, scripts are stored in a directory that is easily accessible with Windows Explorer and the temptation to update scripts without using the streaming profiler is great. Resist the forces of the dark side and do not do this! This will save you much anguish.
At runtime, the streaming system operates like this.
- Wow, a profile I’ve never seen before. Prepare to execute.
- Wow! Scripts. I’ll need those.
- Define a directory beneath “RadeStore” directory, copy all scripts there.
- For each script, if necessary – start a sandbox, run script in sandbox. If script was to be run outside of isolation, skip the sandbox..
- Life is happy – eventually the application terminates.
- How many of those scripts were “post-exit”.
- For each post-exit, same activity of running scripts at pre-launch.
Observe that if you update scripts outside of the profiler, the streaming system won’t know about it. This means that users who already ran the application will have “old” scripts in their RadeStore and users who newly run the application will have “new”. Any time where things differ per user, it is … bad. To avoid this, update the scripts in the profiler and then the profiler has the mission to inform the streaming client that the scripts have been updated.