C# Windows 程序将文件写入 "sysWOW64" 和 "Program Files(x86)"。使用 VS 安装项目。 64 位系统上的 32 位应用程序

C# Windows Program writes files to "sysWOW64" and to "Program Files(x86)". Using VS Setup Projects. 32bit App on 64bit System

有人能告诉我,为什么我的程序 writes/reads 文件 to/from 在我使用 VS 安装项目安装后这两个文件夹? 第一次启动时,当我启动程序并将程序中的某些内容保存到文件中时,它会将其写入:

C:\Users\UserName\AppData\Local\VirtualStore\Program 文件 (x86)\公司 Name\Program 名称\"

设置 "run on system start" 后,我重新启动计算机,程序启动,但这次它读写 from/into 这个文件夹:

C:\Users\UserName\AppData\Local\VirtualStore\Windows\SysWOW64

因此它会在第二次启动时加载错误的值或什么都不加载。 看起来这取决于我如何启动程序,通过桌面符号或在系统启动时自动运行。

如何防止这种情况以及如何让程序始终 read/write 来自同一文件夹?我宁愿将文件始终保存在根文件夹中,其中 exe 是 (C:\Program Files(x86)\CompanyName\ProgramName).

我认为问题出在 VS 安装项目中,或者是因为它是 64 位系统上的 32 位应用程序 运行。我已经在其他问题中寻找解决方案,但没有帮助,而是什么也没读到。 希望有人能帮帮我,谢谢!

这就是我写文件的方式:File.WriteAllText(@"mailstate2", "true"); 我不给路径。。。我只想保存在根目录下。。。

你实际上在这里发生了一些不同的事情。所有这些都与 windows 运行 如何编程和保护文件系统的关键部分免受恶意篡改有关。

首先,程序可以从任何目录启动。如果您没有指定将文件写入的特定位置,那么它将相对于程序启动的目录进行写入。您可以通过设置程序的快捷方式并更改快捷方式的 'Start in' 属性 来对此进行测试。因此,桌面快捷方式中的 'Start in' 文件夹与 Auto运行 使用的文件夹不同。

其次,只有提升的用户和进程才能实际修改某些 windows 目录。其中包括 Program FilesProgram Files (x86)Windows 文件夹等。如果未提升的进程试图将文件写入这些目录之一,windows 会自动将它们重定向到 windows VirtualStore directory 下的同一文件夹。这允许过去从这些受保护位置读写的遗留程序继续工作,同时仍然保护可执行文件不被恶意软件覆盖。无论如何,这种静默重定向是您的程序最终写入非常奇怪的位置的原因。

根据您要写入的数据类型,有几个位置适合写入不涉及虚拟商店的数据。

  • 如果您的用户可能想将数据复制到另一台计算机或备份,那么在他的文档文件夹中创建一个文件夹可能是合适的,尽管我个人讨厌有多少程序对我这样做。如果您发现自己这样做,问问自己是否有某种方法可以让用户选择存储这些数据的位置。也许通过首选项页面或第一个 运行 配置。
  • 如果是个人计算机用户可能希望彼此独立自定义的首选项类型数据,但他们不需要查看或注意,则使用用户的 AppData 文件夹 (C:\Users\username\AppData\)是合适的。请注意,AppData 文件夹包含三个不同的子文件夹:Roaming、Local 和 LocalLow。这是一个 excellent SuperUser topic on the differences between them.
  • 如果应用程序数据需要与用户无关地保留,那么 ApplicationData 文件夹 (C:\ProgramData) 是合适的,但您可能需要对您创建的任何 files\directories 设置权限在那里让所有用户访问它们。另请注意,这样做会带来安全问题。

这里有一些有用的链接,可以通过快速 google 搜索得到,它们可能会让您开始朝着正确的方向思考。

Damien 这里有一个要点:您必须被提升(管理员)到 write/update 共享公共文件夹中的文件,例如 AppData 和程序文件(以及许多其他文件夹)。另一个问题是已经完成的虚拟化,这样您的程序在这样做违反安全性时不会简单地崩溃 - 它写入虚拟存储。这是搜索将向您显示的内容:

https://www.curlybrace.com/words/2010/09/09/windows-vista7-file-system-virtualization/

对此的简单解决方案是,如果您的程序需要 运行 提升到 AppData 文件夹中的 write/update 文件,则为您的程序提供一个提升清单。这种事:

https://blogs.msdn.microsoft.com/nikhiln/2007/04/19/using-manifests-to-elevate-an-application-in-vista/

尽管 Visual Studio 应该 IDE 支持清单,以便您的代码具有 requestedExecutionLevel level=“requireAdministrator.它会在启动时请求提升,就像 UAC 系统上所有需要它的程序一样。

清单的存在也会关闭虚拟化,因此您的应用程序将崩溃而不是被重定向到虚拟存储(如果您违反了对受限位置的文件写入)。

如果您要求有限的用户能够 运行 您的应用程序,请为您的文件选择另一个位置,ashbygeek 已经提到了这一点。