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