Search code examples
windowswixwindows-installer

Display end-user message in case of an error in custom action in MSI with Wix


Say, I have the following WIX markup that instructs the MSI installer to call a custom action from the included DLL:

<CustomAction Id="CA_SetProperties_Finalize" 
        Property="CA_OnInstallFinalize" 
           Value="[Installed],[REINSTALL],[UPGRADINGPRODUCTCODE],[REMOVE]" />

<CustomAction Id='CA_OnInstallFinalize' 
       BinaryKey='CADll' 
        DllEntry='msiOnInstallFinalize' 
         Execute='deferred' Impersonate='no' />

<InstallExecuteSequence>
  <Custom Action='CA_SetProperties_Finalize' 
          Before='InstallFinalize'></Custom>
  <Custom Action='CA_OnInstallFinalize' 
           After='CA_SetProperties_Finalize'></Custom>
</InstallExecuteSequence>

<Binary Id='CADll' SourceFile='Sources\ca-installer.dll' />

And the DLL itself has the following C++ code for the custom action:

#pragma comment(linker, "/EXPORT:msiOnInstallFinalize=_msiOnInstallFinalize@4")

extern "C" UINT __stdcall msiOnInstallFinalize(MSIHANDLE hInstall) 
{
    //Do the work
    if(doWork(hInstall) == FALSE)
    {
        //Error, cannot continue!
        return ERROR_INSTALL_FAILURE;
    }

    return ERROR_SUCCESS;
}

What happens is that when my doWork method fails, the installation should not continue, so I return ERROR_INSTALL_FAILURE. The issue is that in that case the installer simply quits and the installation GUI window goes away.

So I was curious, is there any way to change the Wix markup to be able to show a user message in case my custom action returns an error?


Solution

  • I use this to create message boxes to handle errors from within my dll:

    PMSIHANDLE hRecord = MsiCreateRecord(0);
    MsiRecordSetString(hRecord, 0, TEXT("Enter the text for the error!"));
    MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord);
    return ERROR_INSTALL_USEREXIT;