【问题标题】:WIX C++ Custom ActionWIX C++ 自定义操作
【发布时间】:2024-05-02 20:50:02
【问题描述】:

我有一个基本的 WIX 自定义操作:

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

添加到安装程序:

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

问题是,无论我做什么,句柄 hInstaller 都无效。我已将操作设置为提交、延迟、更改 InstallExecute 序列中的位置,hInstaller 始终无效。

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 在什么情况下无效?您是否从 API 调用返回错误?
  • 如果我使用句柄进行任何调用,该函数将返回 Invalid_Handle 错误消息。
  • 忽略句柄,函数本身是否被正确调用?
  • 我相信该函数被正确调用。无论如何要解决这个问题,我已经重写了设置和自定义 dll(代码不多),现在可以正常工作了。

标签: c++ wix custom-action name-decoration


【解决方案1】:

您需要导出调用的函数,以便 MSI 可以使用未修饰的 C 样式名称调用它

用这个替换你的代码

    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;
    }

【讨论】:

    【解决方案2】:

    正如here 所提到的,克服__stdcall 混乱的唯一方法是使用:

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

    这会在 DLL 导出表中创建第二个条目。

    【讨论】:

    • 另一种确保未损坏的函数名称包含在 DLL 导出中的方法是将其导出到 DEF 文件中,并将其添加到链接器属性(链接器 -> 输入 -> 模块定义文件)。