问题描述
我当前正在编写一个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; }
}
我认为这是出于保护目的,但并非如此。如果是这样,我的问题是:解决此问题的方法是什么?好像我没有尝试检索很多信息,只是控件的类名。如果不是故意的,那么我的问题是为什么这不起作用?
解决方法
您正在传递缓冲区大小14,但是name0
变量为空。
您必须预先分配内存,传递正确的缓冲区大小并检查函数的返回值:
-
确保您的PInvoke签名对于GetClassName是正确的。
[DllImport("user32.dll",SetLastError = true,EntryPoint = "GetClassNameW",CharSet = CharSet.Unicode)] static extern int GetClassName(IntPtr hWnd,StringBuilder lpClassName,int nMaxCount);
-
如文档中所述,如果失败,该函数将返回零。
var className = new StringBuilder(256); if(GetClassName(ptr,className,className.Capacity)>0) { // do more processing }