获取存储在VirtualStore中的日志文件的真实路径

Sug*_*rue 3 c# uac virtualstore

我的应用程序将日志文件存储在一个位置,根据管理员设置,该文件可以重定向到VirtualStore中的文件夹。他们有时最终会出现例如:

日志文件位于:

C:\Users\-my username-\AppData\Local\VirtualStore\Program Files (x86)\ *my-application* \logs
Run Code Online (Sandbox Code Playgroud)

C#认为它在这里:

C:\ Program Files(x86)\ my-application \ logs

这只是代码一部分中的问题-一个试图在记事本中打开日志文件的按钮。它运行Process.Start(path-where-application-thinks-log-files-are);

如果我使用File.Exists(path-where-application-thinks-log-files-are)进行测试;我是对的-因为C#知道要在VirtualStore位置查找。但是,当我尝试启动文件时,它失败了。

所以我的问题是,从Process.Start()命令的角度来看,有没有办法将路径转换为正确的位置?

Ian*_*oyd 6

您的问题的答案是您不能这样做。

文件和注册表虚拟化是暂时的兼容性黑客,当前存在于Windows的当前版本中,因此有漏洞的应用程序将暂时继续运行。Microsoft不提供处理重定向文件的功能。这样做的应用程序处于错误状态,需要进行修复。

Developing for Windows博客中

用户帐户控制数据重定向

时至今日,许多应用程序仍被设计为将文件写入Program Files,Windows目录或系统根目录(通常为C驱动器)文件夹。

虚拟化仅旨在帮助应用程序与现有程序兼容。专为Microsoft Windows 7设计的新应用程序应对敏感系统区域执行写操作,也不应依靠虚拟化来纠正错误的应用程序行为。始终开发具有标准用户权限的应用程序,不要指望以管理员权限运行的应用程序。使用标准用户权限而非管理员权限测试您的应用程序。

如果使用Windows 7之前开发的应用程序进行UAC虚拟化,请重新设计应用程序以将文件写入适当的位置。

解决问题的理想方法是禁用应用程序的文件和注册表虚拟化。这样,您的应用程序将不再能够将文件保存到敏感位置-并会出现Access denied错误。

为此,您可以在应用程序的程序集清单中添加一个条目,告诉Windows应用程序已正确编写:

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>
Run Code Online (Sandbox Code Playgroud)

这样,将日志文件写入%ProgramFiles%子树的任何尝试都将正确失败。

正确编写的Windows应用程序不会在中存储数据Program Files。根据Windows 7客户端软件徽标计划的技术要求,第8-9页:

默认情况下安装到正确的文件夹

用户应该对文件的默认安装位置具有一致和安全的体验,同时保留将应用程序安装到他们选择的位置的选项。还必须将应用程序数据存储在正确的位置,以允许多个人使用同一台计算机而不会破坏或覆盖彼此的数据和设置。


Windows在文件系统中提供了特定的位置来存储程序和软件组件,共享的应用程序数据以及特定于用户的应用程序数据:

  • 默认情况下,应将应用程序安装到Program Files文件夹中。用户数据或应用程序数据绝不能存储在此位置,因为为此文件夹配置了安全权限(已添加重点
  • 必须在计算机上的用户之间共享的所有应用程序数据都应存储在ProgramData中
  • 特定于用户的所有应用程序数据,并且不与计算机的其他用户共享的所有应用程序数据必须存储在Users \ <用户名> \ AppData中
  • 切勿直接写入“ Windows”目录和/或子目录。使用正确的方法来安装文件,例如字体或驱动程序
  • 在“按机器”安装中,必须在首次运行时而不是在安装过程中写入用户数据。这是因为在安装时没有正确的用户位置来存储数据。安装后,应用程序尝试在计算机级别修改默认关联行为将不会成功。相反,必须在每个用户级别声明默认值,以防止多个用户覆盖彼此的默认值。

在您的情况下,应存储以下日志文​​件:

  • 在每个用户LocalAppData文件夹中(通常解析为C:\Users\Sugrue\AppData\Local
  • CommonAppData文件夹中(通常解析为C:\ProgramData

这是你的选择。大概您想要一个可以将多个用户添加到的日志文件。在这种情况下,您需要Common AppData文件夹。您可以检索使用此路径SHGetFolderPathCSIDL_COMMON_APPDATA,或较新的SHGetKnownFolderPath

SHGetFolderPath(0, CSIDL_COMMON_APPDATA, SHGFP_TYPE_CURRENT, out path);
Run Code Online (Sandbox Code Playgroud)

用户能够写入此文件夹,因为默认情况下授予用户创建文件和文件夹的权限:

在此处输入图片说明

综上所述

你不能
但同时:您不应该。

考虑如果没有重定向发生,会发生什么。在Windows XP上以标准用户身份运行时会发生什么?