InstallShield users may have noticed that, in all the ‘select folder’ type dialogs, there is no ‘Create New Folder’ button. If the user wants to create one, he can only do it from Windows itself, or (in some dialogs) type it as text. This is because all these dialogs call the SelectDir() function when clicking Browse.
This is of course very inconvenient, I saw several uses complain about it, but the situation remains.
I came up with a solution, inspired by this KB Article (how to browse for files in InstallScript). Basically I created my own version of AskDestPath() dialog, and modified the behavior so when clicking Browse it will call a custom function i wrote, based on Windows API SHBrowseForFolder().
You can find the custom function on my GitHub here.
The only issue I have is that I cannot set the initial folder. This is a known drawback of this specific API function, and there is a known C++ workaround – but it cannot apply to InstallShield since it does not support pointers to functions (it crashes if you try).
Recently I had a situation when I needed the ability to take a list of strings and eliminate duplicates.
Now, in all modern languages, this is a built-in capability or data structure – set() in Python, Distinct() in C#, etc.
But InstallScript is too basic for that. Since we need dynamic arrays, all we have to work with is the LIST object. So, after some trial and error, I came up with this piece of code, which is quite efficient; the only downside is that the order of items is not kept – but in my case it didn’t matter.
InstallScript provides a built in SelectDir() function, allowing the user can select a directory. However there is no equivalent function to allow the user to select a file. Which is a problem if you want to implement custom dialogs that browse for files (e.g. a dialog that asks for a .pfx certificate file and its password).
As it happens, InstallShield provides a very good knowledge-base article about how to add such functionality, but it is very-well hidden; you have to use very specific keywords in order to find it… So, to save you some time – go ahead and use this link.
This is a question that I get asked from time to time, usually after someone who is not familiar with the deployment world encounters problems with a certain installation. “We could just write a script that extracts the files to the right place, what’s the big deal?”
Well, it’s a big deal. Generally speaking, an installation framework (compared to a script) provides a lot of benefits, such as:
- Modelling the application deployment into sub-modules – allowing to add or remove parts of the applications, define dependencies etc.
- Built-in support for many deployment actions – from simple things like copy files, edit text files, or run some OS command, to configuring web servers and databases
- Ability to rollback each action – which gives you the ability to rollback changes in case of installation error, and provide an uninstaller, with (theoretically) no additional effort.
- Built-in detection of files in use, including the ability (in some cases) to replace such files (upon reboot, or by automatically restart the interfering process)
- Various levels of UI (from completely silent deployment to a full user-driven interface)
- Versioning and update management (upgrades/patches)
- Built-in logging
- Integration with the Operating System software management tools (such as the ‘programs and features’ in Windows)
- And more… (your comments are welcomed)
So, it’s so great, so why not everyone love it?
After having to do that a few times recently, I decided to put down a short summary on how msi upgrades work. It’s may not be 100% accurate and doesn’t go into much details, but if you want to explain it to colleagues or managers who know very little of msi, it should satisfy them.
So here it goes:
Recently one of my team members installed InstallShield 2013 SP1 Premier on his desktop. However, each project she tried to build ended up with the ‘incompatible version of CAB file’ error.
Upon further investigation, it turned out that it only happens when the project reside in her ClearCase dynamic view. So the workaround is to use snapshot views, or just the local disk, to build InstallShield projects.
But the real solution was to upgrade her ClearCase version. She was using a fairly old one (22.214.171.124) which is known to have compatibility issues with new software (such as Visual Studio 2013). So once we upgraded it to ClearCase 126.96.36.199, the error disappeared, and she can now happily build InstallShield projects using ClearCase dynamic views.
Since I couldn’t find it documented anywhere, and it took me a bit to figure out, just thought it would be nice to note it here.
The InstallScript character and string data structures are Unicode. Which means, when you want to include special characters in your string (e.g. by using sprintf with %c), you need to use the Unicode numbering (as found here, for example) rather than the ASCII numbering (which is totally different after 128).
In the past I wrote about a possible InstallScript bug which may cause setup.exe to crash.
However we kept encountering the crash message here and there, although this time when you closed it, the installation process continued normally and finished successfully.
This turned out to be a very random problem which makes it difficult to generalize or reproduce.
Recently, one of my team member found a solution for it: Continue reading
This is an issue with InstallShield 2012 and later.
You try to compile your script (Ctrl+F7) and you get an error that ‘in previous builds, the msi was only partially built’. Once you start getting this error it persists.
You can try run a full build again (as the message suggests) but it won’t help you.
The solution? delete the entire Release Folder and then rebuild your project. The next time you try to compile, it should successfully get streamed into the msi.
A colleague of mine raised an interesting question regarding our installation – what’s the difference between ‘Cancel’ (e.g. in ok/cancel message) and ‘Abort’ (e.g. in an ‘abort/retry/ignore’ message)?
Turns out that there is a logic behind this, one I was using without thinking about:
- ‘Abort’ means to stop the process since an error occurred (e.g. inadequate disk space, missing prerequisites, problem registering a DLL etc.)
- ‘Cancel’ means to stop the process since the user wants to (e.g. in the user interview dialogs, during file copying, etc.).
I wonder how many people actually distinguish between these two…