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

时间:2013-12-13 16:02:28

标签: c# uac virtualstore

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

日志文件位于:

C:\Users\-my username-\AppData\Local\VirtualStore\Program Files (x86)\ *my-application* \logs

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()命令的角度来看,有没有办法将路径转换为正确的位置?

3 个答案:

答案 0 :(得分:4)

你的问题的答案是,你不能。

文件和注册表虚拟化是一种临时兼容性攻击,存在于当前版本的Windows中,因此错误的应用程序将暂时继续工作。 Microsoft没有提供处理重定向文件的功能。执行此操作的应用程序处于错误状态,需要修复。

来自Developing for Windows blog

  

用户帐户控制数据重定向

     

今天,许多应用程序仍设计为将文件写入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>

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

正确编写的Windows应用程序不会在Program Files中存储数据。来自Technical requirements for the Windows 7 Client Software Logo Program,第8-9页:

  

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

     

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

     
     

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

     
      
  • 默认情况下,应将应用程序安装到Program Files文件夹中。 用户数据或应用程序数据绝不能存储在此中   位置,因为为此配置了安全权限   文件夹 强调添加
  •   
  • 必须在计算机上的用户之间共享的所有应用程序数据都应存储在ProgramData
  • 中   
  • 必须存储特定用户专用且不与计算机的其他用户共享的所有应用程序数据   用户\&lt;用户名&GT; \应用程序数据
  •   
  • 永远不要直接写入“Windows”目录和/或子目录。使用正确的方法安装文件,例如   字体或驱动程序
  •   
  • 在“每台机器”安装中,必须在首次运行时写入用户数据,而不是在安装期间写入。这是因为没有   在安装时更正用户位置以存储数据。尝试   通过应用程序修改计算机上的默认关联行为   安装后的级别将失败。相反,默认必须   在每个用户级别上声明,这会阻止多个用户   覆盖彼此的默认值。
  •   

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

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

选择权在你手中。大概你想要一个多个用户可以添加的单个日志文件。在这种情况下,您需要 Common AppData 文件夹。您可以使用SHGetFolderPath使用CSIDL_COMMON_APPDATA或较新的SHGetKnownFolderPath来检索此路径:

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

用户可以写入此文件夹,因为创建文件和文件夹的权限默认授予用户

enter image description here

摘要

你不能。
但与此同时:你不应该。

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

答案 1 :(得分:1)

我遇到过类似的情况;我能够通过将安装路径限制为与Program Files(x86)不同的东西来解决它。你可以说C:\ Program Files \ Program

如果你试过这个,那么你会注意到应用程序没有创建扩展名为:\ AppData \ Local \ VirtualStore的虚拟商店文件夹..

答案 2 :(得分:0)

我尝试的解决方案,不是很优雅,是测试VirtualStore路径位置是否存在。如果是,请使用它。

但必须有更强大的方法来做到这一点。