I am using Qt 5.4 on Windows. I encountered a strange issue. I tried to write a file to the program files directory while in non-admin user access level. I expected it not to write. But it wrote! No errors at all. Okay, but what's really strange is that only my program can 'see' that file but explorer doesn't show it neither did it show up when I tried dir
, dir /ah
or ls
.
This is what explorer can see
This is what my program can see
And mind you, my program can see that file every time I start it and browse to that folder.
What on Earth is going on here?
File Virtualization. File virtualization is a technique that Windows Vista+ OSes use to address the situation where an application wants to write to a location which is writable only by the administrators (like C:\Program Files
or C:\Windows
).
When an application writes to such a system location Windows redirects all such file operations to a Virtual Store directory, which is located at %LOCALAPPDATA%\VirtualStore
. Later, when the application reads back this file, the computer will provide the one in the Virtual Store. This way Windows 'fools' the program into believing that it read from and wrote to the protected location whereas actually it is only dealing with a virtual location.
The manifest is an XML file that can be embedded into the application. It tells Windows that the application is UAC-aware, and that it therefore should not do any file virtualization. So, now if the application attempts to access protected resources, then these operations will simply fail but the OS won't virtualize.
When your application includes an application manifest with a requestedExecutionLevel
value specified, Windows's virtualization of the registry and file system will be switched off.
An example manifest file:
<?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>
There are a few different ways to add a manifest file to a Qt app. I'll mention only one - which I feel is the easiest. You may add the other ways to this answer if you know.
requestedExecutionLevel
tag is present (otherwise virtualization won't be turned off).mt.exe -nologo -manifest <your manifest file> -outputresource:<your executable>;#1
*.*I found the mt.exe
file in "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\
, it may be slightly different for you but it will surely be in the Microsoft SDKs\Windows
folder
Sources
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