gpt4 book ai didi

c# - SHGetKnownFolderPath/Environment.GetFolderPath() 返回公共(public)文档的错误值

转载 作者:太空狗 更新时间:2023-10-29 17:55:27 29 4
gpt4 key购买 nike

我在尝试解析 CommonDocuments 目录时遇到了一个有点奇怪的错误。在使用 Windows 资源管理器(属性 -> 上下文菜单中的路径)将 CommonDocuments 目录重定向/移动到新位置后,它一直解析到错误的目录。

一个最小的工作代码是:

namespace CommonDocumentsTest
{
class Program
{
private static readonly Guid CommonDocumentsGuid = new Guid("ED4824AF-DCE4-45A8-81E2-FC7965083634");

[Flags]
public enum KnownFolderFlag : uint
{
None = 0x0,
CREATE = 0x8000,
DONT_VERFIY = 0x4000,
DONT_UNEXPAND= 0x2000,
NO_ALIAS = 0x1000,
INIT = 0x800,
DEFAULT_PATH = 0x400,
NOT_PARENT_RELATIVE = 0x200,
SIMPLE_IDLIST = 0x100,
ALIAS_ONLY = 0x80000000
}

[DllImport("shell32.dll")]
static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath);

static void Main(string[] args)
{
KnownFolderFlag[] flags = new KnownFolderFlag[] {
KnownFolderFlag.None,
KnownFolderFlag.ALIAS_ONLY | KnownFolderFlag.DONT_VERFIY,
KnownFolderFlag.DEFAULT_PATH | KnownFolderFlag.NOT_PARENT_RELATIVE,
};


foreach (var flag in flags)
{
Console.WriteLine(string.Format("{0}; P/Invoke==>{1}", flag, pinvokePath(flag)));
}
Console.ReadLine();
}

private static string pinvokePath(KnownFolderFlag flags)
{
IntPtr pPath;
SHGetKnownFolderPath(CommonDocumentsGuid, (uint)flags, IntPtr.Zero, out pPath); // public documents

string path = System.Runtime.InteropServices.Marshal.PtrToStringUni(pPath);
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(pPath);
return path;
}
}
}

预期行为:
输出为 D:\TestDocuments

实际行为:
输出为 C:\Users\Public\Documents

None; P/Invoke==>C:\Users\Public\Documents
DONT_VERFIY, ALIAS_ONLY; P/Invoke==>
NOT_PARENT_RELATIVE, DEFAULT_PATH; P/Invoke==>C:\Users\Public\Documents

正确的值存储在 Windows 注册表 (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Documents) 中,但 SHGetKnownFolderPath(或 环境.GetFolderPath)

操作系统:Windows 7 Professional x64
.NET 框架 v4.0.30319应用程序是为 x86 CPU

编译的

到目前为止我尝试了什么:

  • 重新启动我的应用程序
  • 重启电脑
  • 调用 Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments);
  • 直接调用 Win32-API SHGetKnownFolderPath

编辑 2重现步骤:

  1. 在您的计算机上停用 UAC [并重新启动!]
  2. 转到 C:\Users\Public\
  3. 右键单击“公共(public)文档”文件夹并选择属性
  4. 选择“路径”标签
  5. 单击“移动...”并在驱动器 D: 上选择一个名为 TestDocuments 的(新)文件夹
  6. 点击“应用”
  7. 同意将所有文件移动到新位置开始最小化以上申请

最佳答案

tl;dr:行为是设计使然,仅当您在 x64 操作系统上运行为 x86 CPU 编译的程序集时才会出现


更长的版本:
Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) 访问 Windows 注册表的 32 位配置单元。
文件夹的实际路径存储在 64 位配置单元中。该问题已转发给 Windows 团队,可能会在未来版本的 Windows 中得到修复。

有关更多信息,请参阅 the Microsoft connect report


解决方法使用以下代码创建一个控制台应用程序并为任何 CPU

编译它
static void Main(string[] args)
{
Console.WriteLine("{0}", Environment.GetFolderPath(System.Environment.SpecialFolder.CommonDocuments));
}

然后从您的主应用程序中调用它:

Process proc = new Process();
ProcessStartInfo info = new ProcessStartInfo("myConsoleApp.exe");

// allow output to be read
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.UseShellExecute = false;
proc.StartInfo = info;

proc.Start();
proc.WaitForExit();
string path = proc.StandardOutput.ReadToEnd();

这将启动 ANY CPU 可执行文件,它只会打印出所需的标准输出路径。然后在主应用程序中读取输出并获得真实路径。

关于c# - SHGetKnownFolderPath/Environment.GetFolderPath() 返回公共(public)文档的错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7200679/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com