11

I have the following CustomAction in my project:

<CustomAction Id="InstallDriver"
                  Return="check"
                  Execute="deferred"
                  Impersonate="no"
                  FileKey="FileDriverInst"
                  ExeCommand="-install" />

<InstallExecuteSequence>
    <Custom Action="InstallDriver" Before="InstallServices" />
</InstallExecuteSequence>

The program that installs the driver produces useful return codes, for example if the installation failed because the system needs to be restarted following a previous driver uninstall.

Currently if anything other than success is returned, I get a dialog saying 'A program run as part of the setup did not finish as expected.' and the installation fails. This is not optimal.

How can I get and handle return codes?

fredley
  • 32,953
  • 42
  • 145
  • 236
  • Your whole design is not optimal. It's out of process to Windows Installer and isn't declarative. There are better patterns for installing drivers. – Christopher Painter Apr 19 '12 at 15:17
  • 2
    @ChristopherPainter The Wix-based installer for this package must use the same tools as our other installation mechanisms, I'm afraid I don't have a say. – fredley Apr 19 '12 at 15:21
  • 1
    Then there's nothing I can do for you. That's simply the way MSI handles EXE calls. You'd have to write your own custom actions to wrap the EXE call and then interpret the failure reason. To me this just adds yet another failure point. – Christopher Painter Apr 19 '12 at 15:44
  • @ChristopherPainter, that should be posted as an answer. – Ed Bayiates Apr 18 '14 at 21:58

3 Answers3

6

Windows Installer doesn't support handling custom action return values.

For an EXE custom action a non-zero return value is interpreted as an error and the installation stops. Only a win32 DLL or VBScript custom action can change the installation behavior through its return code, but it's still very limited.

If you want to reboot the machine after install, you can set the REBOOT property.

Cosmin
  • 21,216
  • 5
  • 45
  • 60
3

Added as an "answer" by request:

Your whole design is not optimal. It's out of process to Windows Installer and isn't declarative. There are better patterns for installing drivers.

That's simply the way MSI handles EXE calls. You'd have to write your own custom actions to wrap the EXE call and then interpret the failure reason. To me this just adds yet another failure point.

Guy Danus
  • 746
  • 2
  • 11
  • 18
Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
2

You can't get a return code from a CustomAction, but in a round about way you can set what that return code would be on a property. That might as well be the same thing as getting the return code.

You have to get it within the script/dll your custom action is performing. Otherwise, the return code only shows up in the log.

For example, if you have property like

<Property="MyCode" Secure="yes">

Then within VBScript (or Jscript) you can get the value of that property like this:

VBScript

Session.Property("MyCode")

Initially, it is null. You can set it in VBScript like this:

If someCondition = 4 Then
  Session.Property("MyCode") = "4" // For a return code of 4
End If

Once back in your WiX .wxs file, if you look at the value of your property, it is now 4. You could even use it in CDATA tags.

For example, only spawn a dialog if MyCode is equal to 4.

<Publish Dialog="SpawnDialog" ...><![CDATA[ MyCode = 4 ]]></Publish>
Giulio Vian
  • 8,248
  • 2
  • 33
  • 41
Holly Harb
  • 21
  • 3