尝试使用 GetClassName 读取或写入受保护的内存

Attempted to read or write to protected memory with GetClassName

我目前正在编写一个 explorer.exe 包装器(文件夹视图,而不是另一个),并且我有一个来自 User32.dll#EnumChildWindows 的 IntPtr 列表。当我循环遍历 IntPtr 时,无论选择哪个 IntPtr,我都会得到 System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 使用 GetClassName 后:

        string name0;
        foreach (IntPtr ptr in list) {
            
            name0="";
            if (GetClassName(ptr,out name0,(IntPtr)14)!=IntPtr.Zero) //exception here on GetClassName
                if (name0=="SysTreeView32") { this.QuickAccessTreeView=ptr; break; } 
            
        }

我认为这是出于保护目的,但也可能不是。如果是,我的问题是:解决这个问题的方法是什么?这不像我要检索很多信息,只是控件的 class 名称。如果这不是故意的,那么我的问题是为什么这不起作用?

您传递的缓冲区大小为 14,但 name0 变量为空。 您必须 pre-allocate 内存,传递正确的缓冲区大小并检查函数的 return 值:

  1. 确保您的 PInvoke 签名正确 GetClassName

    [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetClassNameW", CharSet = CharSet.Unicode)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
    
  2. 如文档中所述,函数 return 在失败的情况下为零。

    var className = new StringBuilder(256);
    if(GetClassName(ptr, className, className.Capacity)>0)
    {
       // do more processing
    }