当前位置: 代码迷 >> C# >> API函数GetWindowText调用报错
  详细解决方案

API函数GetWindowText调用报错

热度:62   发布时间:2016-05-05 04:20:30.0
API函数GetWindowText调用出错
企图调用GetWindowText但是出错,或者取得为null!
 见如下代码(注释的代码是我试验过的),环境为vs2010 win7
       #region GetWindowText
        [DllImport("user32.dll", EntryPoint = "GetWindowText")]
        //static extern int GetWindowText(IntPtr hwnd, ref string lpString, int cch);
        //static extern int GetWindowText(IntPtr hwnd, out string lpString, int cch);
        //static extern int GetWindowText(IntPtr hwnd, out StringBuilder lpString, int cch);
        static extern int GetWindowText(IntPtr hwnd, out char[] lpString, int cch);
        [DllImport("user32.dll", EntryPoint = "GetWindowTextLength")]
        static extern int GetWindowTextLength(IntPtr hwnd);
        #endregion

        private void tvAll_DoubleClick(object sender, EventArgs e)
        {
            if (tvAll.SelectedNode != null)
            {
                window.Window w = tvAll.SelectedNode.Tag as window.Window;
                string szWndTitle = new string('0',64);
                string szClsName;
                #region string
                //try
                //{
                //    int i = GetWindowTextLength(w.Hwnd);
                //    //StringBuilder s = new StringBuilder(512);
                //    //int i = GetWindowText(win, s, s.Capacity)
                //    GetWindowText(w.Hwnd, out szClsName, i*10);
                //    //GetWindowText(w.Hwnd, out szWndTitle, i);
                //    w.Text = szWndTitle;
                //}
                //catch
                //{
                //}
                #endregion
                #region StringBuilder
                //try
                //{
                //    StringBuilder windowname = new StringBuilder(5000);
                //    if (GetWindowText(w.Hwnd, out windowname, 5000) > 0)
                //    {
                //        w.Text  = windowname.ToString();
                //    }

                //}
                //catch(AccessViolationException ee)
                //{
                //    MessageBox.Show(ee.Message);
                //}
                #endregion
                #region StringBuilder
                //try
                //{
                //    int ii = GetWindowTextLength(w.Hwnd);
                //    StringBuilder windowname = new StringBuilder(ii);
                //    if (GetWindowText(w.Hwnd, out windowname, ii) > 0)
                //    {
                //        w.Text = windowname.ToString();
                //    }

                //}
                //catch (AccessViolationException ee)
                //{
                //    MessageBox.Show(ee.Message);
                //}
                #endregion
                #region char
                try
                {
                    //GC.Collect();
                    int ii = GetWindowTextLength(w.Hwnd);
                    //ii = 5000;
                    char[] windowname = new char[ii];
                    GetWindowText(w.Hwnd, out windowname, ii);
                    //尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
                    //运行时遇到了错误。此错误的地址为 0x674c89dc,在线程 0x16f0 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。
                    //if (GetWindowText(w.Hwnd, out windowname, ii) > 0)
                    {
                        if(windowname != null)
                            w.Text = windowname.ToString();
                    }

                }
                catch (AccessViolationException ee)
                {
                    MessageBox.Show(ee.Message);
                }
                #endregion
                //}
                //try
                //{
                //    GetClassName(win, out szClsName, 64);
                //    w.ClassName = szClsName;
                //}
                //catch
                //{
                //}
                //string text;
                //GetWindowText(win,out text,256);
                tvAll.SelectedNode.Text = string.Format("{0}~{1}~{2}", w.Hwnd, w.Text, w.ClassName);
            }
        }

------解决思路----------------------
首先out不能用char[],

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

    int length       = GetWindowTextLength(hWnd);
     StringBuilder sb = new StringBuilder(length + 1);
     GetWindowText(hWnd, sb, sb.Capacity);
     return sb.ToString();


其次,你的windows对象是托管对象,为什么要用Win32API去取Title?!直接取不好么?
  相关解决方案