4

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

日志文件位于:

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

C# 认为它在这里:

C:\Program 文件 (x86)\我的应用程序\logs

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

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

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

4

3 回答 3

7

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

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

来自为 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>

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

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

默认安装到正确的文件夹

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


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

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

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

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

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

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

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

在此处输入图像描述

总之

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

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

于 2013-12-31T21:14:15.043 回答
1

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

如果您尝试过此操作,您会注意到该应用程序不会创建扩展名为:\AppData\Local\VirtualStore.. 的虚拟商店文件夹。

于 2017-04-06T05:08:42.153 回答
0

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

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

于 2013-12-17T11:56:47.483 回答