为什么即使在非管理员访问权限下,我的Qt应用程序也会写入受保护的位置?

时间:2015-01-19 06:33:49

标签: windows qt qfile

我在Windows上使用Qt 5.4。我遇到了一个奇怪的问题。在非管理员用户访问级别,我尝试将文件写入程序文件目录。我希望它不要写。但是它写了!完全没有错误。好的,但真正奇怪的是,只有我的程序才能看到'该文件但资源管理器在我尝试dirdir /ahls时未显示该文件。

这是资源管理器可以看到的This is what explorer can see

这是我的程序可以看到的This is what my program can see 请注意,我的程序每次启动时都可以看到该文件并浏览到该文件夹​​。

这里到底发生了什么?

1 个答案:

答案 0 :(得分:3)

为什么会这样?

文件虚拟化。文件虚拟化是Windows Vista +操作系统用来解决应用程序想要写入只能由管理员写入的位置的情况的技术(如C:\Program FilesC:\Windows)。

当应用程序写入此类系统位置时,Windows会将所有此类文件操作重定向到位于%LOCALAPPDATA%\VirtualStore的虚拟存储目录。稍后,当应用程序回读此文件时,计算机将提供虚拟存储中的文件。通过这种方式,Windows“愚弄”程序,使其相信它从受保护的位置读取并写入,而实际上它只处理虚拟位置。

如何解决这个'问题'?

The Manifest。

清单是一个可以嵌入到应用程序中的XML文件。它告诉Windows应用程序是UAC感知的,因此它不应该执行任何文件虚拟化。因此,现在如果应用程序尝试访问受保护的资源,那么这些操作将会失败但操作系统不会虚拟化。 当您的应用程序包含指定了requestedExecutionLevel值的应用程序清单时,Windows的注册表和文件系统的虚拟化将被关闭。

示例清单文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
            <requestedPrivileges>
                <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
            </requestedPrivileges>
        </security>
    </trustInfo>
</assembly>  

实际做什么?

将清单文件添加到Qt应用程序有几种不同的方法。我只提一个 - 我认为这是最简单的。如果您知道,可以在此答案中添加其他方法。

  1. 创建清单文件(您甚至可以使用上面给出的文件)。
  2. 确保存在requestedExecutionLevel标记(否则虚拟化将不会关闭)。
  3. 执行mt.exe -nologo -manifest <your manifest file> -outputresource:<your executable>;#1 *
  4. 完成。
  5. * 我在mt.exe找到了"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\文件,它可能略有不同,但肯定会在Microsoft SDKs\Windows文件夹中


    <子>来源
    <子> 1。 Qt cannot cannot create/write to C:\
    <子> 2。 http://msdn.microsoft.com/en-us/library/bb756960.aspx
    <子> 3。 http://blog.strixcode.com/2010/08/embedding-application-manifest-and.html
    <子> 4。 http://qt-project.org/forums/viewthread/36726