C#依据进程名称获取进程的句柄?

时间:2023-03-09 06:37:49
C#依据进程名称获取进程的句柄?

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

      }