Level 2

Install fails to start after reboot

Hello all,

I am debugging an installer that fails to restart after a required reboot.

This is an InstallScript installer (IS 2011 Premiere), running on an
XP Professional 32-bit system.

We are using the Windows registry key:
to force our installer to rerun after the reboot.

The error: After the reboot, and before Windows gives the user control
of the desktop (i.e. when the RunOnce directive is being enforced) an error
dialog pops up saying "Windows cannot find 'C'" and the rest of the
install does not take place.

There might be a problem with our call to the Windows API that should
provide the executable name that needs to be invoked via RunOnce

Here is the routine:
function BOOL RebootAndContinue()
BOOL bReturn;
STRING sFileName[257];
STRING szMsg1;
bReturn = TRUE;
szMsg1 = "Installation will continue after reboot.";

// get full pathname of product
GetModuleFileName(0, sFileName, 256);

// schedule install to run again after reboot
RegDBSetKeyValueEx("Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce", "DBInstall", REGDB_STRING, "\"" + sFileName + "\"", -1);
SdFinishReboot ("" , szMsg1 , SYS_BOOTMACHINE , "" , 0 );
return bReturn;

First of all, is this approach the current standard practice for this situation?

Second, and most damming is that when I add the logging code:
Sprintf(svTemp, "RebootAndContinue: GetModuleFileName loads the name %s", sFileName);

I get the log message:
"RebootAndContinue: GetModuleFileName loads the name C"

So it looks like the call to GetModuleFileName is failing. (i.e. the RunOnce technique
is working fine, but is being asked to run "C" which fails)

I need to confirm first that this approach is "common practice" for how installers
that require reboots are handled, and secondly whether our use of the
GetModuleFileName API call is correct.

Any pointers appreciated,

Labels (1)
0 Kudos
2 Replies
Level 12 Flexeran
Level 12 Flexeran

It sounds like your prototype for GetModuleFileName is incorrect. Make sure you've read the migration notes for all versions across your upgrade; they're linked as stickies at the top of each product's forum. In this case the IS2011 Unicode support is likely the culprit. Instead of STRING in your prototype, you will need WSTRING.

That said, I'm not convinced this is the right approach to register for post-reboot configuration. Instead I would typically recommend setting BATCH_INSTALL; see the BATCH_INSTALL help article, the linked "Understanding When an Installation or Uninstallation Restarts the Target System," and the OnRebooted help article for more information.
0 Kudos
Level 7

In an InstallScript project (both back at IS2011 and with the current version) I simply set the BATCH_INSTALL to signal a need for a reboot, and then I implement the OnReboot handler to call the functions that I need implemented after the reboot. A couple of caveats are that this only works in a project with full maintenance enabled in the project settings. Also if the code to be processed in OnReboot needs any information from the pre-reboot launch (dialog info or even Media states of features) you need to persist that information in OnEnd (to a file or the registry) and then recover the information in your OnReboot. Using this method the InstallShield engine creates the RunOnce keys for you. (To debug your method you could create a demo setup using this method and compare the registry key that InstallShield creates verses the one you are creating, but I would also guess that your call to the Win32 API is being tripped up by the WSTRING change in the prototype of the Win32 API.)

For a non-maintenance project (for a Service pack), since it does not register with the OS (ARP) so it cannot launch the setup after a reboot. If doing a non-maintenance setup and you need to process code in OnReboot, then set the project to full Maintenance and have code the removes the ARP registration after either a normal (no-reboot) installation or after processing your OnReboot code.

Also the IS debugger can be configured to attach to the OnReboot code, but I do not recall the details at this time. I think one needs to pass the -d flag to the args parameter of OnReboot (but that memory may be faulty).

Sorry this is late, and I hope you found another solution, but maybe this will help someone.
0 Kudos