C++:MsiOpenDatabase失败,错误为110 0x6e error_OPEN_FAILED,仅当提升/adm

C++: MsiOpenDatabase fails with error 110 0x6e ERROR_OPEN_FAILED only when elevated / admin

本文关键字:FAILED OPEN adm error 失败 MsiOpenDatabase 错误 0x6e C++      更新时间:2023-10-16

我在调用函数MsiOpenDatabase时遇到问题(https://msdn.microsoft.com/en-us/library/aa370338(v=vs.85).aspx)。当我在管理员帐户下运行它,但没有明确启动提升的可执行文件时,一切都很好。这表明MSI文件等的路径应该是正确的。

因此,当运行提升的MsiOpenDatabase()时,我得到一个错误代码110(0x6e)。我已尝试调用MsiGetLastErrorRecord,如下所述(https://msdn.microsoft.com/en-us/library/aa370124(v=vs.85).aspx),但当我尝试在消息框中打印代码时,什么也没发生。它根本达不到目的。我没有在目标机器上进行调试的Visual studio,所以调试有点麻烦。

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

感谢您的帮助!

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

但是,既然我已经拥有对同一用户的访问权限(执行权限),但在未提升时,为什么我必须执行此过程才能访问网络共享上的运行文件?如果Windows已经在已经访问网络共享的同一帐户上运行提升,为什么它需要向同一用户请求凭据?对我来说似乎很奇怪,但我想我错过了一些关键的部分?

样本代码

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

如上所述,当发生此错误时,结果变量的值为110,并记住更新部分中的部分。我觉得很奇怪,但也许有人比我更了解UAC,为什么我必须再次提供凭据,方法是转到netowrk共享上的一个文件,并选择以管理员身份运行以使其正常工作(因为我早些时候已经在同一网络共享位置以非管理员身份提供了相同帐户的凭据)?

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

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