C# WinApi:获取COM窗体的控件名

C# WinApi:获取COM窗体的控件名,c#,.net,winapi,com,ui-automation,C#,.net,Winapi,Com,Ui Automation,我想用.Net framework替换当前的UI自动化工具(QTP)。 我需要测试VB6(COM)应用程序 框架的基本原理之一是使用表单名称。 到目前为止,我没有找到一种使用WinAPI获取这些数据的方法 解决方案只有一个约束,即解决方案必须依赖.Net代码,这意味着:不允许使用商业广告工具 有人熟悉这门学科吗 这些链接是我的主要参考资料: 他们都建议使用SendMessage来检索表单的数据,但我没有这样做 对于这个问题,我很乐意听取任何意见 多谢各位 C代码 公共静态类VbAdapt

我想用.Net framework替换当前的UI自动化工具(QTP)。 我需要测试VB6(COM)应用程序

框架的基本原理之一是使用表单名称。 到目前为止,我没有找到一种使用WinAPI获取这些数据的方法

解决方案只有一个约束,即解决方案必须依赖.Net代码,这意味着:不允许使用商业广告工具

有人熟悉这门学科吗

这些链接是我的主要参考资料:

  • 他们都建议使用SendMessage来检索表单的数据,但我没有这样做

    对于这个问题,我很乐意听取任何意见

    多谢各位

    C代码

    公共静态类VbAdapter:IAdapter
    {
    /// 
    ///获取窗体内部名称(设计时名称)。
    /// 
    ///形柄
    ///字符串。窗体的内部名称。
    公共静态字符串GetFormInternalName(IntPtr hWnd)
    {
    int _ctrlNameMsg=0;
    //_ctrlNameMsg=NativeMethods.RegisterWindowMessage(“WM_GETCONTROLNAME”);//用于.Net表单
    _ctrlNameMsg=NativeMethods.RegisterWindowMessage(“Get_CONTROLNAME”);//用于vb6表单
    返回GetControlName(hWnd,_-ctrlNameMsg);
    }
    /// 
    ///使用控件的句柄获取控件内部名称。
    /// 
    ///控制手柄
    ///控件名称消息
    ///绳子。
    私有静态字符串GetControlName(IntPtr hWnd,int msg)
    {
    //瓦尔斯
    uint size=65536;//要分配的内存大小
    byte[]byteArray=新字节[size];//win form内部名称缓冲区
    IntPtr bufferMem=IntPtr.Zero;//指向内存缓冲区的指针包含内部名称
    IntPtr writed=IntPtr.Zero;//到目前为止写入的字节数
    IntPtr retHandle=IntPtr.Zero;//返回句柄
    IntPtr hProcess=IntPtr.Zero;//进程句柄
    IntPtr fileHandle=IntPtr.Zero;//文件句柄
    bool-retVal=false;
    //在非Win32Nt操作系统版本的情况下-引发异常
    if(Environment.OSVersion.Platform!=PlatformID.Win32NT)
    抛出新的Win32Exception(“此模块不支持操作系统。\n此模块仅在Win32Nt操作系统上受支持。”);
    尝试
    {
    uint procId=GetProcessIdFromHWnd(hWnd);
    //获取流程详细信息
    HPProcess=NativeMethods.OpenProcess(
    WindowsConsts.PROCESS\u VM\u操作|
    WindowsConsts.PROCESS\u VM\u READ|
    WindowsConsts.PROCESS\u VM\u WRITE,
    假,,
    procId);
    //Todo:导出到本机类中的OpenProcess方法
    如果(hProcess.ToInt64()==0)抛出新的Win32Exception();
    bufferMem=NativeMethods.VirtualAllocEx(HPProcess,
    IntPtr.Zero,
    新UIntPtr(尺寸),
    WindowsConsts.MEM_保留| WindowsConsts.MEM_提交,
    NativeMethods.PageProtection.ReadWrite);
    //Todo:导出到本机类中的OpenProcess方法
    如果(hProcess.ToInt64()==0)抛出新的Win32Exception();
    //向控件发送消息,请求其名称
    retHandle=NativeMethods.SendMessage(hWnd,msg,newintptr(size),bufferMem);
    //从共享内存中获取项目
    if(!NativeMethods.ReadProcessMemory(hProcess、bufferMem、byteArray、新UINTPTTR(大小)、写入))
    抛出新的Win32Exception();
    }
    捕获(例外)
    {
    抛出新的Win32Exception();
    }
    返回byteArray字符串(byteArray);
    }
    /// 
    ///将字节数组转换为字符串。
    /// 
    ///字节数组。
    ///绳子。
    专用静态字符串ByteArrayToString(字节[]byteArray)
    {
    返回Encoding.Unicode.GetString(byteArray.TrimEnd('\0');
    }
    /// 
    ///使用进程的句柄获取进程id。
    /// 
    ///把手
    ///uint。进程Id。
    专用静态uint GetProcessIdFromHWnd(IntPtr hWnd)
    {
    uint-pId;
    GetWindowThreadProcessId(hWnd,输出pId);
    返回pId;
    }
    }
    内部类NativeMethods
    {
    [DllImport(“kernel32.dll”)]
    内部静态外部IntPtr OpenProcess(uint dwDesiredAccess、bool bInheritHandle、,
    uint-dwProcessId);
    [DllImport(“kernel32.dll”)]
    内部静态外部IntPtr VirtualAllocEx(IntPtr hProcess、IntPtr lpAddress、,
    UIntPtr dwSize、uint flAllocationType、页面保护flProtect);
    [DllImport(“user32.dll”,SetLastError=true)]
    内部静态外部单元GetWindowThreadProcessId(IntPtr hWnd,out单元lpdwProcessId);
    [DllImport(“kernel32.dll”)]
    内部静态外部bool VirtualFreeEx(IntPtr hProcess、IntPtr lpAddress、,
    UIntPtr dwSize,uint dwFreeType);
    [DllImport(“kernel32.dll”)]
    内部静态外部布尔闭合手柄(IntPtr hObject);
    [DllImport(“kernel32.dll”)]
    内部静态外部IntPtr MapViewOfFile(IntPtr hFileMappingObject,uint
    dwDesiredAccess、uint dwFileOffsetHigh、uint dwFileOffsetLow、,
    UIntPtr dwNumberOfBytesToMap);
    [DllImport(“kernel32.dll”)]
    内部静态外部bool unmpviewoffile(IntPtr lpBaseAddress);
    [DllImport(“kernel32.dll”,SetLastError=true)]
    内部静态外部IntPtr CreateFileMapping(IntPtr hFile,
    IntPtr lpFileMappingAttributes、PageProtection flProtect、int dwMaximumSizeHigh、,
    int dwMaximumSizeLow,字符串lpName);
    [DllImport(“user32.dll”)]
    内部静态外部IntPtr SendMessage(IntPtr hwnd、int wMsg、IntPtr wParam、IntPtr lParam);
    [DllImport(“kernel32.dll”)]
    内部静态外部bool ReadProcessMemory(IntPtr hProcess、IntPtr lpBaseAddress、,
    [Out]字节[]lpBuffer,uintpttr nSize,IntPtr lpNumberOfBytesRead);
    [DllImport(“Kernel32.dll”,EntryPoint=“rtlmovemory”,SetLastErro
    
     public static class VbAdapter : IAdapter
    {
        /// <summary>
        /// Gets form internal name (design-time name).
        /// </summary>
        /// <param name="hWnd">Form handle</param>
        /// <returns>string. Form's internal name.</returns>
        public static string GetFormInternalName(IntPtr hWnd)
        {
            int _ctrlNameMsg = 0;
            //_ctrlNameMsg = NativeMethods.RegisterWindowMessage("WM_GETCONTROLNAME"); //For .Net forms
            _ctrlNameMsg = NativeMethods.RegisterWindowMessage("Get_CONTROLNAME"); //for vb6 forms
    
            return GetControlName(hWnd, _ctrlNameMsg);
        }
    
        /// <summary>
        /// Get control internal name using its handle.
        /// </summary>
        /// <param name="hWnd">Control handle</param>
        /// <param name="msg">Control Name Message</param>
        /// <returns>string.</returns>
        private static string GetControlName(IntPtr hWnd, int msg)
        {
            //vars
    
            uint size = 65536; //size of memory to be allocated
            byte[] byteArray = new byte[size]; //win form internal name buffer
    
            IntPtr bufferMem = IntPtr.Zero; //pointer to memory buffer contain the internal name
            IntPtr written = IntPtr.Zero;          //number of bytes written so far
            IntPtr retHandle = IntPtr.Zero;         //returned handle
            IntPtr hProcess = IntPtr.Zero;       //Process handle
            IntPtr fileHandle = IntPtr.Zero;          //File handle
    
            bool retVal = false;
    
            //in case non Win32Nt OS version - throw exception
            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
                throw new Win32Exception("Oprating System is not supportted for this module.\nThis module is supportted on Win32Nt OS only.");
            try
            {
                uint procId = GetProcessIdFromHWnd(hWnd);
                //get process deatails
                hProcess = NativeMethods.OpenProcess(
                    WindowsConsts.PROCESS_VM_OPERATION |
                    WindowsConsts.PROCESS_VM_READ |
                    WindowsConsts.PROCESS_VM_WRITE,
                    false,
                    procId);
    
                //Todo: Export to OpenProcess Method in native class
                if (hProcess.ToInt64() == 0) throw new Win32Exception();
    
                bufferMem = NativeMethods.VirtualAllocEx(hProcess,
                    IntPtr.Zero,
                    new UIntPtr(size),
                    WindowsConsts.MEM_RESERVE | WindowsConsts.MEM_COMMIT,
                    NativeMethods.PageProtection.ReadWrite);
    
                //Todo: Export to OpenProcess Method in native class
                if (hProcess.ToInt64() == 0) throw new Win32Exception();
    
                //Send message to the control requesting it's name
                retHandle = NativeMethods.SendMessage(hWnd, msg, new IntPtr(size), bufferMem);
    
                //Get TVITEM from shared memory
                if (!NativeMethods.ReadProcessMemory(hProcess, bufferMem, byteArray, new UIntPtr(size), written))
                    throw new Win32Exception();
            }
            catch (Exception)
            {
                throw new Win32Exception();
            }
    
            return ByteArrayToString(byteArray);
        }
    
        /// <summary>
        /// Converts byte array to string.
        /// </summary>
        /// <param name="byteArray">The byte array.</param>
        /// <returns>string.</returns>
        private static string ByteArrayToString(byte[] byteArray)
        {
            return Encoding.Unicode.GetString(byteArray).TrimEnd('\0');
        }
    
        /// <summary>
        /// Get the process id using its handle.
        /// </summary>
        /// <param name="hWnd">The handle</param>
        /// <returns>uint. The process Id.</returns>
        private static uint GetProcessIdFromHWnd(IntPtr hWnd)
        {
            uint pId;
            NativeMethods.GetWindowThreadProcessId(hWnd, out pId);
    
            return pId;
        }
    }
     internal class NativeMethods
    {
        [DllImport("kernel32.dll")]
        internal static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle,
            uint dwProcessId);
    
        [DllImport("kernel32.dll")]
        internal static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
            UIntPtr dwSize, uint flAllocationType, PageProtection flProtect);
    
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    
        [DllImport("kernel32.dll")]
        internal static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,
            UIntPtr dwSize, uint dwFreeType);
    
        [DllImport("kernel32.dll")]
        internal static extern bool CloseHandle(IntPtr hObject);
    
        [DllImport("kernel32.dll")]
        internal static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint
            dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,
            UIntPtr dwNumberOfBytesToMap);
    
        [DllImport("kernel32.dll")]
        internal static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        internal static extern IntPtr CreateFileMapping(IntPtr hFile,
            IntPtr lpFileMappingAttributes, PageProtection flProtect, int dwMaximumSizeHigh,
            int dwMaximumSizeLow, string lpName);
    
        [DllImport("user32.dll")]
        internal static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
    
        [DllImport("kernel32.dll")]
        internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
            [Out] byte[] lpBuffer, UIntPtr nSize, IntPtr lpNumberOfBytesRead);
    
        [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
        internal static extern void MoveMemoryFromByte(IntPtr dest, ref byte src, int size);
    
        [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
        internal static extern void MoveMemoryToByte(ref byte dest, IntPtr src, int size);
    
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        internal static extern int RegisterWindowMessage(string lpString);
    
        [Flags]
        internal enum PageProtection : uint
        {
            NoAccess = 0x01,
            Readonly = 0x02,
            ReadWrite = 0x04,
            WriteCopy = 0x08,
            Execute = 0x10,
            ExecuteRead = 0x20,
            ExecuteReadWrite = 0x40,
            ExecuteWriteCopy = 0x80,
            Guard = 0x100,
            NoCache = 0x200,
            WriteCombine = 0x400,
        }
    }