yas*_*891 9 c# winapi .net-4.0 windows-7 known-folders
尝试解析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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
预期行为:
输出是D:\TestDocuments
实际行为:
输出为C:\Users\Public\Documents
没有; P/Invoke ==> C:\ Users\Public\Documents
DONT_VERFIY,ALIAS_ONLY; P/Invoke ==>
NOT_PARENT_RELATIVE,DEFAULT_PATH; P /调用==> C:\用户\公共\文件
正确的值存储在Windows注册表(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell文件夹\ Common Documents)中,但不会由SHGetKnownFolderPath
(或Environment.GetFolderPath
)返回
操作系统:Windows 7 Professional x64
.NET Framework v4.0.30319应用程序是针对x86 CPU编译的
到目前为止我尝试了什么:
Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments);
编辑2 重现的步骤:
Properties
D:
名为TestDocuments
tl; dr:行为是设计使然,仅当您在x64 OS上运行针对x86 CPU编译的程序集时才会出现
较长的版本:
Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments)
访问Windows注册表的32位配置单元。
文件夹的实际路径存储在64位配置单元中。该问题已转发给Windows团队,并且可能在Windows的将来版本中得到解决。
有关更多信息,请参阅Microsoft Connect报告。
解决方法 使用以下代码创建控制台应用程序并针对任何CPU对其进行编译
static void Main(string[] args)
{
Console.WriteLine("{0}", Environment.GetFolderPath(System.Environment.SpecialFolder.CommonDocuments));
}
Run Code Online (Sandbox Code Playgroud)
然后从您的主应用程序调用它:
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();
Run Code Online (Sandbox Code Playgroud)
这将启动ANY CPU可执行文件,该文件只会打印出标准输出的所需路径。然后,在主应用程序中读取输出,您将获得真实路径。
归档时间: |
|
查看次数: |
5276 次 |
最近记录: |