Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WIX C++ Custom Action

I have a basic WIX custom action:

        UINT __stdcall MyCustomAction(MSIHANDLE hInstaller)
        {   
            DWORD dwSize=0;
            MsiGetProperty(hInstaller, TEXT("MyProperty"), TEXT(""), &dwSize);
            return ERROR_SUCCESS;
        }

Added to the installer:

   <CustomAction Id="CustomActionId" FileKey="CustomDll" DllEntry="MyCustomAction"/>
   <InstallExecuteSequence>
       <Custom Action="CustomActionId" Before="InstallFinalize" />
   </InstallExecuteSequence>

The problem is that, no matter what i do, the handle hInstaller is not valid. I've set the action to commit, deferred, changed the place in InstallExecute sequence, hInstaller is always not valid.

Any help would be appreciated. Thanks.

like image 334
Adrian Fâciu Avatar asked Jan 25 '10 16:01

Adrian Fâciu


People also ask

How do I create a custom action on WiX?

You need to create a new C# Custom Action Project for WiX v3 in your solution. Change the function name to a name that fits your function. After that right click on the References Folder on your WiX setup project and choose Add Reference... . Click the tab Projects and choose your custom action Project.

What is WiX C#?

InfoQ: For the benefit of our readers who haven't heard of it before, what is WiX#? Oleg: Wix# (WixSharp) is a deployment authoring framework targeting Windows Installer (MSI). Wix# allows building complete MSI setups from a deployment specification expressed with C# syntax.

What are WiX fragments?

The Fragment element is the building block of creating an installer database in WiX. Once defined, the Fragment becomes an immutable, atomic unit which can either be completely included or excluded from a product.


2 Answers

You need to export the called function so MSI can call it using undecorated C style name

Replace your code with this

    extern "C" _declspec(dllexport) UINT __stdcall MyCustomAction(MSIHANDLE hInstall);

    extern "C" UINT __stdcall MyCustomAction(MSIHANDLE hInstall)
    {   
        DWORD dwSize=0;
        MsiGetProperty(hInstaller, TEXT("MyProperty"), TEXT(""), &dwSize);
        return ERROR_SUCCESS;
    }
like image 93
Charles Gargent Avatar answered Sep 24 '22 03:09

Charles Gargent


As mentioned here, the only way to overcome the mangling of a __stdcall is to use:

#pragma comment(linker, "/EXPORT:SomeFunction=_SomeFunction@@@23mangledstuff#@@@@")

This creates a second entry in the DLL export table.

like image 41
Pierre Avatar answered Sep 23 '22 03:09

Pierre