I was talking last week with someone about how difficult it is to truly get progress indication UI right in setup (time remaining estimates, completion percentage, etc). In the extreme cases, you end up with something like my all-time favorite screenshot, but in mainstream cases it can be anywhere ranging from mildly difficult to impossible to get the estimated time correct (depending on the size and complexity of your setup, the number of custom actions, along with several other factors).
To illustrate how tricky this can be, let me describe how we implement the progress UI in setup for Visual Studio .NET 2002 and 2003. There are 2 distinct phases to the setup for these products - the prerequisites (or Windows Component Update) and the main Visual Studio feature installation UI.
For the main VS setup, we implemented a Windows Installer external UI handler, and we interpret the progress messages passed back to us by Windows Installer and then update the time remaining and the progress bar. That sounds nice in theory, but what really happens is that each phase of the setup (generating script, installing, cleaning up rollback files, etc) is interpreted separately, so then the progress bar will fill up and then start over, and the time remaining will decrease close to zero, then increase again as the next phase starts. In fact, we removed the estimated time remaining string from the progress UI between VS 2002 and VS 2003 because it was so flaky and very frustrating to users to have it jump forward and backwards throughout the installation process.
For the VS prerequisites setup, we could not use a Windows Installer external UI handler because we were chaining together several setup packages, some of which were not MSIs. Because we were simply calling CreateProcess to spawn each package, there was also not a way to receive a callback from each of the individual packages with progress messages that we could use to update setup UI for the user. Instead, what we did is find a really slow machine in our test lab (one that was below our published minimums for both RAM and processor speed), and ran an installation on that machine. Then we parsed the log files to determine the amount of time required for each prerequisite component and put that value in one of the setup data files (baseline.dat to be exact - if you look in that file in notepad you will see a value EstInstallTime for each component). The setup UI code then started a timer when it called CreateProcess, and filled in the progress bar using this estimated time value and the current elapsed time to create a completed percentage. If something bad happened and it took longer, we just left the progress bar full and put a simple message saying "setup is still installing...." above the progress bar (in my experience this rarely happens though unless one of the components hangs when we call it). Because we used a super-slow machine, the components often completed before the progress bar filled up - and it generally gives a better impression to finish sooner than predicted instead of later.
Based on feedback we've heard for both the VS 2002 and VS 2003 product families, it appears that our old-fashioned method of "calculating" progress of the prerequisite components seems much more accurate than the more correct way of calling into Windows Installer.