【问题标题】:MsiOpenDatabaseW throws access violation when executed within an msi custom action在 msi 自定义操作中执行时,MsiOpenDatabaseW 引发访问冲突
【发布时间】:2022-01-11 18:18:39
【问题描述】:

我有一个代码可以修改 缓存的(不是正在安装的)msi 安装程序数据库,当在独立的 exe 中执行时,它工作正常。但是当它从一个 msi 自定义操作中运行时,我得到一个非常奇怪的访问冲突。

const auto& msiProductCode = ::GetProductCode(::msiUpgradeCode);
const auto& msiPath = ::GetCachedMSIPath(msiProductCode);

PMSIHANDLE dbHandle{};
const auto res = MsiOpenDatabaseW(msiPath.data(), MSIDBOPEN_TRANSACT, &dbHandle); // access violation here within msi castom aciton

异常信息:

Exception thrown at 0x76246E10 (rpcrt4.dll) in msiexec.exe: 0xC0000005: Access violation reading location 0x00000001.

调用栈:

我无法理解的是它是如何以rpcrt4.dll 结尾的,因为独立的可执行文件没有这种依赖关系:

Dump of file .\disable_custom_action.exe

File Type: EXECUTABLE IMAGE

  Image has the following dependencies:

    msi.dll
    MSVCP140D.dll
    VCRUNTIME140D.dll
    VCRUNTIME140_1D.dll
    ucrtbased.dll
    KERNEL32.dll

然而,用于 msi 自定义操作的 dll 具有这种依赖关系,因为在其他应用中使用了 RPC 自定义操作功能。此自定义操作的In-Script execution 配置为Immediate Execution

1 在 msi 自定义操作中运行时可能导致访问冲突的原因是什么?
2 MsiOpenDatabaseW 能否以某种方式依赖于rpcrt4.dll
3 会不会是C/Cpp Runtime链接可能不一致(不同CRT版本)造成的?


我最初的问题描述为here。我虽然我想通了,但在答案显示在活动安装期间我无法调用MsiOpenDatabaseW 的部分之前。

【问题讨论】:

    标签: c++ debugging windows-installer access-violation


    【解决方案1】:

    You can't use MsiOpenDatabase from a custom action:

    因为 MsiOpenDatabase 启动数据库访问,它不能用于正在运行的安装。

    【讨论】:

    • stackoverflow.com/a/70440925/9363996 这个答案建议了一个修改自定义操作的方法(虽然没有提到我是否可以在安装过程中运行它)。链接中的问题描述了我最初的问题:如何在升级安装期间修改缓存 msi 的自定义操作条件?
    • 如果我在自定义操作启动的子进程中调用它会怎样?
    • 我认为必须澄清您是否不能使用MsiOpenDatabase“正在运行的安装”或者只是不能打开正在安装的msi包的数据库。因为我修改缓存的 msi 数据库的可执行文件在活动安装期间工作正常(并行运行的 Windows 安装程序 + exe 修改了数据库)。
    • 我同意文档含糊不清,但我不会指望能够通过自定义操作打开 any 数据库。
    • 在修改缓存数据库的自定义操作中运行可执行文件工作。当运行打开数据库的 dll 函数时,它不起作用
    猜你喜欢
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多