Get real path of a log file stored in VirtualStore

南楼画角 提交于 2019-12-04 14:51:31

The answer to your question is that you cannot.

File and Registry virtualization is a temporary compatibility hack, present in the current version of Windows so that buggy applications will temporarily continue to work. Microsoft provides no capability to cope with redirected files. Applications that do it are in a buggy state and need to be fixed.

From the Developing for Windows blog:

User Account Control Data Redirection

Today, many applications are still designed to write files to the Program Files, Windows directories, or system root (typically the C drive) folders.

Virtualization is intended only to assist in application compatibility with existing programs. New applications designed for Microsoft Windows 7 should NOT perform write operations to sensitive system areas, nor should they rely on virtualization to provide redress for incorrect application behavior. Always develop applications for use with standard user privileges and don’t count on the application running under administrator privileges. Test your application with standard user privileges and not administrator privileges.

If you are experiencing UAC virtualization with applications developed prior to Windows 7, re-design your applications to write files to the appropriate locations.

The ideal way to solve your problem is to disable File and Registry Virtualization of your application. That way your application will no longer be able to save files to sensitive locations - and will get an Access denied error.

You do this by adding an entry to your application's assembly manifest, telling Windows that your application is properly written:

AssemblyManifest.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
   <assemblyIdentity 
      version="1.0.0.0"
      processorArchitecture="X86"
      name="client"
      type="win32"
   /> 

   <description>Sugrue Contoso</description> 

   <!-- Disable file and registry virtualization -->
   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
      <security>
         <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
         </requestedPrivileges>
      </security>
   </trustInfo>
</assembly>

This way any attempts to write a log file to the %ProgramFiles% subtree will correctly fail.

Correctly written Windows applications do not store data in Program Files. From Technical requirements for the Windows 7 Client Software Logo Program, page 8-9:

Install to the correct folders by default

Users should have a consistent and secure experience with the default installation location of files, while maintaining the option to install an application to the location they choose. It is also necessary to store application data in the correct location to allow several people to use the same computer without corrupting or overwriting each other's data and settings.


Windows provides specific locations in the file system to store programs and software components, shared application data, and application data specific to a user:

  • Applications should be installed to the Program Files folder by default. User data or application data must never be stored in this location because of the security permissions configured for this folder (emphasis added)
  • All application data that must be shared among users on the computer should be stored within ProgramData
  • All application data exclusive to a specific user and not to be shared with other users of the computer must be stored in Users\<username>\AppData
  • Never write directly to the "Windows" directory and or subdirectories. Use the correct methods for installing files, such as fonts or drivers
  • In “per-machine” installations, user data must be written at first run and not during the installation. This is because there is no correct user location to store data at time of installation. Attempts by an application to modify default association behaviors at a machine level after installation will be unsuccessful. Instead, defaults must be claimed on a per-user level, which prevents multiple users from overwriting each other's defaults.

In your case, log files should either be stored:

  • in the per-user LocalAppData folder (typically resolves to C:\Users\Sugrue\AppData\Local)
  • in the CommonAppData folder (typically resolves to C:\ProgramData)

The choice is yours. Presumably you want a single log file which multiple users can add to. In which case you want the Common AppData folder. You can retrieve this path using SHGetFolderPath with the CSIDL_COMMON_APPDATA, or the newer SHGetKnownFolderPath:

SHGetFolderPath(0, CSIDL_COMMON_APPDATA, SHGFP_TYPE_CURRENT, out path);

Users are able to write to this folder, because rights to create files and folders are there are granted to Users by default:

In Summary

You can't.
But at the same time: you shouldn't.

Consider what happens if there is no redirection happening. What happens when you run as a standard user on Windows XP?

I have faced similar situation; I was able to solve it by limiting the installation path to something different from Program Files (x86). You can say C:\Program Files\Program

If you tried this, then you will notice the app does not create virtual store folder with the extension : \AppData\Local\VirtualStore..

The solution I tried, which isn't very elegant, is to test to see if the VirtualStore path location exists. If it does, use that.

But there must be a more robust way of doing this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!