C++:MsiOpenDatabase 失败并出现错误 110 0x6e ERROR_OPEN_FAILED 仅当提升/管理时

标签 c++ mfc windows-installer

当我选择“以管理员身份运行”时,我在从程序内部调用函数 MsiOpenDatabase ( https://msdn.microsoft.com/en-us/library/aa370338(v=vs.85).aspx) 时遇到问题。当我在管理员帐户下运行它但没有明确启动可执行文件时,它一切正常。这表明 MSI 文件等的路径应该是正确的。

因此,当运行提升的 MsiOpenDatabase() 时,我得到错误代码 110 (0x6e)。 我已尝试按照此处 (https://msdn.microsoft.com/en-us/library/aa370124(v=vs.85).aspx) 的说明调用 MsiGetLastErrorRecord,但是当我尝试在消息框中打印代码时没有任何反应。它根本无法到达那里。 我没有用于在目标机器上调试的 Visual Studio,因此调试有点痛苦。

目标机器是 Windows 7 x64。应用程序是 32 位的。 但纯粹的事实是它在未提升的情况下工作但在以管理员身份运行时失败......感觉应该对此有某种答案,也许可以从这个事实中得出?

感谢任何帮助!

编辑: 我终于解决了! 显然我不得不去 MSI 文件所在的网络共享(我试图在上面调用 MsiOpenDatabase)并右键单击那里的文件并选择“以管理员身份运行”,因为那时我才得到一个 UAC 对话框询问凭据的框(我的意思是我能够以管理员身份打开 Windows 资源管理器并毫无问题地导航到网络共享,所以我从没想过这会给我带来这些问题)。完成后,我能够运行我的应用程序,并且它在任何 MsiOpenDatabase 调用上都不再失败。

但是,为什么我必须执行此过程才能访问网络共享上的运行文件,因为我已经拥有同一用户的访问权限(执行权限)但没有提升权限?如果 Windows 已经在已经可以访问网络共享的同一帐户上以提升的方式运行,那么 Windows 为什么需要向同一用户询问凭据?我觉得很奇怪,但我想我错过了一些关键部分?

示例代码

LPCTSTR szPersist = MSIDBOPEN_READONLY;
MSIHANDLE handleDB;
UINT result = MsiOpenDatabase(strPath, szPersist, &handleDB); // strPath is something like _T("\\server\MSI\Setup.msi");

当出现上述错误时,结果变量的值为 110,请记住更新部分中的部分。我觉得这很奇怪,但也许有人比我更了解 UAC 以及为什么我必须通过转到网络共享上的文件并选择以管理员身份运行以使其正常工作来再次提供凭据(因为我已经提供了非admin 之前在同一个网络共享位置使用同一个帐户)?

最佳答案

这是自 Windows Vista 以来的标准 UAC 行为,与 MSI 完全无关。在谷歌上搜索“uac 网络驱动器”。

尽管正如我在上面评论的那样,您应该关闭您的 MSI 句柄。使用 PMSIHANDLE 而不是 MSIHANDLE。

关于C++:MsiOpenDatabase 失败并出现错误 110 0x6e ERROR_OPEN_FAILED 仅当提升/管理时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34151098/

相关文章:

c++ - 来自 MFC 的调用 Access 2007 报告

c++ - MFC DLL 调用 AfxWinInit 并使应用程序崩溃

c++ - 使列表控件中的单个项目可编辑(C++、MFC)

wix - Wix Installer:在命令行执行MSIEXEC管理员安装时设置组件条件属性

c++ - 如何从 C++ <random> 获得一致的行为

c++ - 结构中的奇数字段? C++

c++ - recv() 字符数组大小

c++ - Automake 变量整理 Makefile.am

windows - 使用 NVIDIA 显卡运行 ".exe"文件的命令

.net - 在 docker 容器上安装 msi