将程序数据从Program data重定向到AppData\Local\VirtualStore\ProgramData

4

我正在使用带有.net 3.5的C#语言。

我将程序数据保存在文件中:C:\Program Data\MyProgramName\fileName.xml

安装并运行我的应用程序一次后,我卸载了它(在卸载期间,我从“程序数据”中删除了所有文件),然后重新安装应用程序并运行。

奇怪的是,即使数据文件被删除,我的应用程序启动时仍会像“程序数据”中的文件存在一样 - 这意味着我在应用程序中拥有旧数据。

运行以下代码时:

File.Exists("C:\Program Data\MyProgramName\fileName.xml")

我得到了“true”的结果,即使我确定文件不存在。
当我以管理员身份运行应用程序时,事情变得更加奇怪,然后文件不存在。
经过研究,我发现当我使用没有管理员权限的应用程序运行时,而不是获得:“C:\Program Data\MyProgramName\fileName.xml”,我会得到“C:\Users\userName\AppData\Local\VirtualStore\ProgramData\MyProgramName\fileName.xml”,并且确实存在来自以前安装的文件(我显然没有删除,因为我不知道它的存在)。
因此,这个文件在程序数据下有一些虚拟路径。
编辑:
我发现在虚拟存储中删除旧文件后,我的应用程序突然能够找到正确的文件。(我没有在程序数据下的文件中做任何更改。)
我的问题是:
1. 为什么会发生这种情况? 2. 如何防止它发生?
提前谢谢。
2个回答

5
你是否需要写入系统级别的程序数据文件夹而不是每个用户的应用程序数据文件夹?你可以查看 Environment.GetFolderPath 和以下的 Environment.SpecialFolder

  • Environment.SpecialFolder.ApplicationData - 应用程序数据文件夹,如果用户配置文件是漫游的,则会同步到域控制器
  • Environment.SpecialFolder.LocalApplicationData - 应用程序数据文件夹,本地且不同步(例如缓存非常有用)

编辑:

在 Windows 7 x64 上测试,非管理员用户。

var appData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
var myFolder = Path.Combine(appData, "MyApp");
if(!Directory.Exists(myFolder)) Directory.CreateDirectory(myFolder);
File.WriteAllText(Path.Combine(myFolder, "Test.txt"), "Test.");

这段代码实现了预期的功能,即将内容写入到C:\ProgramData\MyApp\Test.txt中。据我所知(管理员模式命令提示符),也没有进行UAC虚拟化。
双重编辑:我想发生的是,在某个时候,管理员用户已将文件写入您的ProgramData文件夹中,因此,UAC文件系统虚拟化会启动,并将非管理员写入重定向到VirtualStore中。
如果您的卸载程序以管理员身份运行,那么您可能需要检查启动卸载的用户的VirtualStore路径和实际的程序数据文件系统路径来进行删除。不过,我不确定是否有官方的方法来执行此操作...

是的。我必须要... 它应该在所有用户之间共享。我正在使用Environment.SpecialFolder.ApplicationData来获取正确的路径。 - user844541
@user844541 -- 检查一下我的编辑。我想知道这是否与此有关。 - AKX
首先,感谢您!事实上,在程序数据下我有不止一个文件,但那是唯一被重定向的文件。关于您的猜测 - 听起来很合理,您指出了一个很好的原因导致这种情况发生..我会进行更多的研究..非常感谢! - user844541

3

我找到了这个bug的原因。

该应用程序试图将文件所有权进行更改,然后另一个文件被创建。

我删除了那一行代码,现在一切正常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接