C#依据进程名称获取进程的句柄或C#怎样获取其它进程的句柄?
有时候标题名是动态变化的,所以不使用FindWindow方法!
[StructLayout(LayoutKind.Sequential)] public struct ProcessEntry32 { public uint dwSize; public uint cntUsage; public uint th32ProcessID; public IntPtr th32DefaultHeapID; public uint th32ModuleID; public uint cntThreads; public uint th32ParentProcessID; public int pcPriClassBase; public uint dwFlags; [MarshalAs(UnmanagedType.ByValTStr,SizeConst=260)] public string szExeFile; } [DllImport("KERNEL32.DLL ")] public static extern IntPtr CreateToolhelp32Snapshot(uint flags,uint processid); [DllImport("KERNEL32.DLL ")] public static extern int CloseHandle(IntPtr handle); [DllImport("KERNEL32.DLL ")] public static extern int Process32First(IntPtr handle,ref ProcessEntry32 pe); [DllImport("KERNEL32.DLL ")] public static extern int Process32Next(IntPtr handle,ref ProcessEntry32 pe); [DllImport("User32.dll",EntryPoint="SendMessage")] private static extern int SendMessage(int hWnd,int Msg,int wParam,string lParam);
public IntPtr GetHandleByProcessName(string ProcessName) { List<ProcessEntry32> list=new List<ProcessEntry32>(); IntPtr handle=CreateToolhelp32Snapshot(0x2,0); IntPtr hh=IntPtr.Zero; if((int)handle>0) { ProcessEntry32 pe32=new ProcessEntry32(); pe32.dwSize=(uint)Marshal.SizeOf(pe32); int bMore=Process32First(handle,ref pe32); while(bMore==1) { IntPtr temp=Marshal.AllocHGlobal((int)pe32.dwSize); Marshal.StructureToPtr(pe32,temp,true); ProcessEntry32 pe=(ProcessEntry32)Marshal.PtrToStructure(temp,typeof(ProcessEntry32)); Marshal.FreeHGlobal(temp); list.Add(pe); if(pe.szExeFile==ProcessName) { bMore=2; hh=GetCurrentWindowHandle(pe.th32ProcessID); break; } bMore=Process32Next(handle,ref pe32); } } return hh; } public static IntPtr GetCurrentWindowHandle(uint proid) { IntPtr ptrWnd=IntPtr.Zero; uint uiPid=proid; object objWnd=processWnd[uiPid]; if(objWnd!=null) { ptrWnd=(IntPtr)objWnd; if(ptrWnd!=IntPtr.Zero&&IsWindow(ptrWnd)) // 从缓存中获取句柄 { return ptrWnd; } else { ptrWnd=IntPtr.Zero; } } bool bResult=EnumWindows(new WNDENUMPROC(EnumWindowsProc),uiPid); // 枚举窗体返回 false 而且没有错误号时表明获取成功 if(!bResult&&Marshal.GetLastWin32Error()==0) { objWnd=processWnd[uiPid]; if(objWnd!=null) { ptrWnd=(IntPtr)objWnd; } } return ptrWnd; } private static bool EnumWindowsProc(IntPtr hwnd,uint lParam) { uint uiPid=0; if(GetParent(hwnd)==IntPtr.Zero) { GetWindowThreadProcessId(hwnd,ref uiPid); if(uiPid==lParam) // 找到进程相应的主窗体句柄 { processWnd.Add(uiPid,hwnd); // 把句柄缓存起来 SetLastError(0); // 设置无错误 return false; // 返回 false 以终止枚举窗体 } } return true; }
调用:
IntPtr hh=GetHandleByProcessName("notepad.exe"); if(hh!=IntPtr.Zero) { SendMessage((int)hh,0x000C,0,"A"); //打开记事本,发送字母A }