C ++:MsiOpenDatabase仅在提升/ admin

时间:2015-12-08 08:23:52

标签: c++ mfc windows-installer

当我选择"以管理员身份运行时,我遇到了从程序内调用函数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资源管理器并导航到网络共享而没有问题所以我从未想过它会给我这些peoblems) 。在完成之后,我能够运行我的应用程序,并且在任何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以及为什么我必须通过访问netowrk共享上的文件再次提供凭据并选择以管理员身份运行以使其正常工作(因为我已经提供了凭证作为非之前在同一个网络共享位置使用相同帐户的管理员)?

1 个答案:

答案 0 :(得分:0)

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

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