【问题标题】:How to get 64-bit "program files" directory in 32-bit Application如何在 32 位应用程序中获取 64 位“程序文件”目录
【发布时间】:2015-07-12 13:32:57
【问题描述】:

我有一个以 x86 模式(在 c# 中)编译的应用程序,我需要从中访问 64 位程序文件文件夹(当然是 64 位 Windows)中存在的某个文件。 我不想在我的应用程序中将C:\Program Files 硬编码为字符串,因为一些目标计算机可能将 Windows 安装在不同的驱动器中,或者可能使用其他语言。

我遇到的问题是使用 Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) 返回 x86 风格而不是所需的目录,除非我在 64 位模式下编译我的程序。出于好奇,我该怎么做才能避免这样做?

【问题讨论】:

  • 将项目的 Build Properties 更改为 Build -Platform target = AnyCpu 如果您不熟悉则 Right click on the project, then select properties, from there click the Build node on the Left and change x86 to AnyCPU
  • @MethodMan 这是我项目中已经选择的选项。还有其他建议吗?
  • Environment.GetEnvironmentVariable("ProgramW6432")怎么样
  • 这是你自己的程序还是别人写的程序?通常,当我同时编写 32 位和 64 位应用程序时,我会将它们之间的所有共享文件存储在 CommonApplicationData 中。
  • 这是来自 MSDN 的 Environment Variables 的完整列表。

标签: c# .net directory


【解决方案1】:

在构建设置中,取消选中选项Prefer 32-bit。 现在Environment.SpecialFolder.ProgramFilesX86 将返回一个 32 位路径,Environment.SpecialFolder.ProgramFiles 将返回一个 64 位路径。

【讨论】:

  • 就是这样!这个答案应该有更多的支持!
  • 不,这不适用于 32 位应用程序。两者都返回 (X86) 文件夹。
【解决方案2】:

项目属性中有一个名为“首选 32 位”的选项。取消选中该选项就可以了。尽管如此,我仍然对代码解决方案感兴趣。

我实际上认为在构建选项上禁用 Prefer 32bit 是更好的方法。如果您不希望您的程序被视为 32 位进程,何不将其设为 64 位进程,这样可以省点麻烦。

另见this article on the subject by Raymond Chen

话虽如此,griddoor 建议的ProgramW6432 环境变量在我尝试时对我来说效果很好。

【讨论】:

  • 注意到他们说“除非我在 64 位模式下编译我的程序”?这意味着他们知道他们可以将其切换为 64 位应用程序,我认为可以安全地假设他们不想或不能这样做。您不只是将 32 位应用程序切换到 64 位应用程序,因此您可以更轻松地找到 64 位 Program Files 目录。这应该是刻意的改变,不应该掉以轻心,也不应该因为这种愚蠢的理由而做。保留 32 位有非常真实的理由,例如需要使用 32 位本机库。
  • @GregCobb 是的,而且我还注意到(几年前,写这篇文章时),在 cmets 中有人建议取消选中 Prefer 32 bit 后,OP 写道“成功了”,但仍然对代码解决方案感兴趣。既然如此,我在回答中说ProgramW6432 环境变量似乎对我有用,所以 OP 或许应该尝试一下。鉴于对提出该建议的评论的支持,我认为它也适用于其他人。
  • @GregCobb 说,我认为在可能的情况下提倡取消选中Prefer 32 bit 对我来说是完全有效的,我通过链接到 Raymond Chen 的帖子阐述了这样做的原因。它应该在所有情况下都使用吗?不,我从来没有另外声明过。我觉得警告,“如果您不希望您的程序被视为 32 位进程”对于大多数人来说应该足够了,包括 OP 和您自己。不过,我感谢您的反馈。
  • @GregCobb 确实这正是我的情况,该项目无法移植到 64 位,因为当时没有替代方案可用的原生 32 位库。感谢 Greg 和 Nacimota 的考虑,他们都非常有帮助。
【解决方案3】:

鉴于您可以放心:

  1. Program Files 目录与系统安装在同一驱动器上。
  2. 它们被命名为适用于 x64 和 x86 的 Program Files,以及适用于 x64 的 Program Files (x86)。

然后你可以这样做:

    public static void Main(string[] args)
    {
        string baseDirectory = Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.System));
        string programFiles = "Program Files";
        string programFilesX86 = "Program Files (x86)";

        Console.WriteLine(Environment.Is64BitProcess ? "64-Bit Process" : "32-Bit Process");

        if (Environment.Is64BitOperatingSystem)
        {
            Console.WriteLine("64-bit operating system");
            Console.WriteLine("Program Files Directory: " + Path.Combine(baseDirectory, programFiles));
            Console.WriteLine("Program Files x86 Directory: " + Path.Combine(baseDirectory, programFilesX86));
        }
        else
        {
            Console.WriteLine("32-bit operating system");
            Console.WriteLine("Program Files Directory: " + Path.Combine(baseDirectory, programFiles));
        }
        
        Console.ReadKey(true);
    }

不过,有一点需要注意:

程序文件目录可以更改,但 Microsoft 不支持,可能会导致其他系统问题。

所以我会用一个好的Directory.Exists 跟进这些,如果你没有找到它们,那么你可以在注册表中查找。您要查找的密钥是:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\

  • ProgramFilesDir
  • ProgramFilesDir(x86)

但同样,对于注册表访问,有一些难以获得的警告,当使用Registry 类时,它将根据请求它的进程的处理器架构选择 64 位或 32 位注册表。您可以指定 64 位目录。不想太深入,那里有很多关于如何读取注册表的教程。

另外请注意,这仅适用于 Windows Vista 及更高版本,我不记得奇怪的 Windows XP-64 或旧版本的 Windows Server 是如何处理它的。

最后一点,Linux/Android/iOS(又名,兼容 Mono 的 OS 或 Micro Framework)没有“Program Files”目录,因此请确保您意识到您在此处编写特定于 OS 的代码。如果您想让它与操作系统无关,请考虑编写一个函数,该函数可以根据当前操作系统为默认安装目录返回字符串数组。

【讨论】:

  • 当您运行非英语版本的 Windows 时,“Program Files”目录不称为“Program Files”。这就是你不能使用硬编码字符串的原因。
【解决方案4】:

恐怕 WinAPI 不支持您的要求。 由于虚拟化,32 位应用程序无法获取 64 位目录的路径。

参考:https://social.msdn.microsoft.com/Forums/vstudio/en-US/37e798f5-1b9b-42ce-89af-486ee3531c0b/32-bit-app-how-to-get-cprogram-files-directory-using-environmentgetfolderpath?forum=csharpgeneral

任何“猜测”正确路径或使用注册表的尝试都可能在未来导致问题...

【讨论】:

  • 幸运的是,“在未来”,大多数软件无论如何都应该打补丁,或者不再是 32 位的,所以对于大多数实际用途来说,对路径进行硬编码就足够了。来自未来的问候!
猜你喜欢
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
相关资源
最近更新 更多