为什么我的 Qt 应用程序即使在 non-admin 访问权限下也会写入受保护的位置?
Why does my Qt application write to protected locations even in non-admin access privilege?
我在 Windows 上使用 Qt 5.4。我遇到了一个奇怪的问题。我试图在 non-admin 用户访问级别下将文件写入程序文件目录。我预计它不会写。但是写了!完全没有错误。好的,但真正奇怪的是,只有我的程序可以 'see' 该文件,但资源管理器不显示它,当我尝试 dir
、dir /ah
或 [=13= 时它也没有显示].
这是资源管理器可以看到的
这是我的程序能看到的
请注意,每次我启动程序并浏览到该文件夹时,我的程序都可以看到该文件。
这到底是怎么回事?
为什么会这样?
文件虚拟化。文件虚拟化是 WindowsVista+ OSes 用来解决应用程序想要写入某个位置的情况的技术只能由管理员写入(如 C:\Program Files
或 C:\Windows
)。
当应用程序写入此类系统位置时 Windows 会将所有此类文件操作重定向到位于 %LOCALAPPDATA%\VirtualStore
的虚拟存储目录。稍后,当应用程序读回该文件时,计算机将在虚拟存储中提供该文件。这样 Windows 'fools' 程序相信它从受保护的位置读取和写入,而实际上它只处理虚拟位置。
如何解决这个'problem'?
清单。
清单是一个可以嵌入到应用程序中的 XML 文件。它告诉 Windows 该应用程序是 UAC 感知的,因此它不应该进行任何文件虚拟化。所以,现在如果应用程序试图访问受保护的资源,那么这些操作将简单地失败,但 OS 不会虚拟化。
当您的应用程序包含指定了 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 应用程序。我只会提到一个——我觉得这是最简单的。如果您知道,可以将其他方法添加到此答案中。
- 创建清单文件(您甚至可以使用上面给出的文件)。
- 确保
requestedExecutionLevel
标签存在(否则虚拟化不会被关闭)。
- 执行
mt.exe -nologo -manifest <your manifest file> -outputresource:<your executable>;#1
*.
- 完成。
*我在 "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\
中找到了 mt.exe
文件,它对你来说可能略有不同,但肯定会在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
我在 Windows 上使用 Qt 5.4。我遇到了一个奇怪的问题。我试图在 non-admin 用户访问级别下将文件写入程序文件目录。我预计它不会写。但是写了!完全没有错误。好的,但真正奇怪的是,只有我的程序可以 'see' 该文件,但资源管理器不显示它,当我尝试 dir
、dir /ah
或 [=13= 时它也没有显示].
这是资源管理器可以看到的
这是我的程序能看到的
这到底是怎么回事?
为什么会这样?
文件虚拟化。文件虚拟化是 WindowsVista+ OSes 用来解决应用程序想要写入某个位置的情况的技术只能由管理员写入(如 C:\Program Files
或 C:\Windows
)。
当应用程序写入此类系统位置时 Windows 会将所有此类文件操作重定向到位于 %LOCALAPPDATA%\VirtualStore
的虚拟存储目录。稍后,当应用程序读回该文件时,计算机将在虚拟存储中提供该文件。这样 Windows 'fools' 程序相信它从受保护的位置读取和写入,而实际上它只处理虚拟位置。
如何解决这个'problem'?
清单。
清单是一个可以嵌入到应用程序中的 XML 文件。它告诉 Windows 该应用程序是 UAC 感知的,因此它不应该进行任何文件虚拟化。所以,现在如果应用程序试图访问受保护的资源,那么这些操作将简单地失败,但 OS 不会虚拟化。
当您的应用程序包含指定了 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 应用程序。我只会提到一个——我觉得这是最简单的。如果您知道,可以将其他方法添加到此答案中。
- 创建清单文件(您甚至可以使用上面给出的文件)。
- 确保
requestedExecutionLevel
标签存在(否则虚拟化不会被关闭)。 - 执行
mt.exe -nologo -manifest <your manifest file> -outputresource:<your executable>;#1
*. - 完成。
*我在 "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\
中找到了 mt.exe
文件,它对你来说可能略有不同,但肯定会在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