如何在64位Windows系统的VB.NET中获取Program Files路径
解决64位Windows系统中VB.NET/C#获取Program Files路径异常的问题
问题原因
你的程序被编译成了32位(x86),在64位Windows的WoW64兼容层运行时,系统会自动重定向文件系统访问,导致Environment.SpecialFolder.ProgramFiles和ProgramFilesX86都返回x86路径(即C:\Program Files (x86))。
解决方案
方案1:修改项目编译目标为64位(推荐)
- 打开Visual Studio,右键项目 → 属性 → 生成(VB.NET选“编译”) → 平台目标选择x64,或者选Any CPU并取消勾选“首选32位”
- 重新编译运行后:
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)会返回64位路径C:\Program FilesEnvironment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)返回32位路径C:\Program Files (x86)
方案2:保持32位程序,通过Windows API绕过重定向
如果必须以32位模式运行程序,可以调用SHGetKnownFolderPath API直接获取原生路径:
C# 代码示例
using System; using System.Runtime.InteropServices; public static class ProgramFolderHelper { [DllImport("shell32.dll", CharSet = CharSet.Unicode)] private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath); private static readonly Guid FOLDERID_ProgramFiles = new Guid("905e63b6-c1bf-494e-b29c-65b732d3d21a"); private static readonly Guid FOLDERID_ProgramFilesX86 = new Guid("7c5a40ef-a0fb-4bfc-874a-c0f2e0b9fa8e"); public static string Get64BitProgramFilesPath() { IntPtr pathPtr = IntPtr.Zero; try { SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, IntPtr.Zero, out pathPtr); return Marshal.PtrToStringUni(pathPtr); } finally { if (pathPtr != IntPtr.Zero) Marshal.FreeCoTaskMem(pathPtr); } } public static string Get32BitProgramFilesPath() { IntPtr pathPtr = IntPtr.Zero; try { SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, IntPtr.Zero, out pathPtr); return Marshal.PtrToStringUni(pathPtr); } finally { if (pathPtr != IntPtr.Zero) Marshal.FreeCoTaskMem(pathPtr); } } }
VB.NET 代码示例
Imports System Imports System.Runtime.InteropServices Public Module ProgramFolderHelper <DllImport("shell32.dll", CharSet:=CharSet.Unicode)> Private Function SHGetKnownFolderPath(<MarshalAs(UnmanagedType.LPStruct)> rfid As Guid, dwFlags As UInteger, hToken As IntPtr, ByRef pszPath As IntPtr) As Integer End Function Private ReadOnly FOLDERID_ProgramFiles As New Guid("905e63b6-c1bf-494e-b29c-65b732d3d21a") Private ReadOnly FOLDERID_ProgramFilesX86 As New Guid("7c5a40ef-a0fb-4bfc-874a-c0f2e0b9fa8e") Public Function Get64BitProgramFilesPath() As String Dim pathPtr As IntPtr = IntPtr.Zero Try SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, IntPtr.Zero, pathPtr) Return Marshal.PtrToStringUni(pathPtr) Finally If pathPtr <> IntPtr.Zero Then Marshal.FreeCoTaskMem(pathPtr) End Try End Function Public Function Get32BitProgramFilesPath() As String Dim pathPtr As IntPtr = IntPtr.Zero Try SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, IntPtr.Zero, pathPtr) Return Marshal.PtrToStringUni(pathPtr) Finally If pathPtr <> IntPtr.Zero Then Marshal.FreeCoTaskMem(pathPtr) End Try End Function End Module
方案3:读取注册表(不推荐)
可以从注册表中读取对应路径,但这种方式依赖系统注册表结构,版本变更可能失效:
- 64位路径:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir - 32位路径:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ProgramFilesDir
内容的提问来源于stack exchange,提问作者ElMaGeK MoSaAd
相关产品推荐
相关产品推荐

