比如已知 notepad.exe 如何取得他的句柄?注:不要告诉我找标题! 

解决方案 »

  1.   

    你要获得什么句柄?进程句柄?线程句柄?窗口句柄?...
    可以使用FindWindow先获得窗口句柄,然后使用GetWindowThreadProcessId获得线程和进程句柄.
      

  2.   

    Option Explicit
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Const PROCESS_ALL_ACCESS = &H1F0FFF
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As LongSub Main()
        Dim strFileName As String
        Dim hWnd As Long, pId As Long, hProcess As Long
        
        strFileName = String(128, Chr(0))
        hWnd = FindWindow(vbNullString, "无标题 - 记事本") '以记事本为例
        GetWindowThreadProcessId hWnd, pId
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pId)
        strFileName = Left(strFileName, GetModuleFileNameExA(hProcess, 0, strFileName, Len(strFileName)))
        CloseHandle hProcess
        MsgBox strFileName
    End Sub
      

  3.   

    就找寻 notepad.exe 的窗口句柄而言,可能性和条件都有很多的,有可能在系统中只运行了一个 Windows 系统的 notepad.exe,也有可能在磁盘其他的地方运行了第三方的 notepad.exe,还有可能会同时运行多个notepad.exe,而你要搞清楚哪一个是你想要的?你如何判断那个是你想要的?判断条件是什么?有哪些具体的条件?程序上需不需要完全自动执行?能不能有人工的介入选择的过程?...懒得问了。不知道你到底想做什么,因为你问得很模糊,作为程序开发者,问问题也要会问才行,否则会得到很多反问的问题给你。假设条件如下:
    一个名为 notepad.exe,不管是不是第三方的 notepad.exe,只要名为 notepad.exe 的都可以被认为是目标程序,多个不用管,找到的第一个就被认为是目标。
    如果条件是这样,可以采用这样的方法:
    1、枚举系统进程并得到所有进程的路径地址。
    2、根据进程的路径地址来判断是否要你想要得程序在进程中出现。
    3、如果有了你想要的进程出现开始枚举窗口句柄
    4、取出每个枚举出来的窗口句柄的进程句柄
    5、让枚举出来“窗口进程句柄”与枚举出来的“目标进程句柄”作比对
    6、比对一样的那个“窗口进程句柄”的“窗口句柄”就是你要找的东西了。虽然上面看起来比较复杂,但做起来其实很简单,在不计算API声明的情况下,只要30-40行代码左右就可以搞定了。但如果你的需求不同,当然处理过程也会不同。
      

  4.   

    3 楼的哥们,你写的和我的要求不一样 你那还是在查找标题 然后去的hwnd  我说了 现在的条件是 只知道文件名。 如果文件名是其他 你这代码就废了 不过还是谢谢你4 楼的哥们 谢谢你 能否把代码贴下
      

  5.   

    Option Explicit
    Private Declare Function EnumProcesses Lib "psapi.dll" (lpidProcess As Long, ByVal cb As Long, cbNeeded As Long) As Long
    Private Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Const PROCESS_ALL_ACCESS = &H1F0FFF
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongSub Main()
        Debug.Print FindProcess("notepad.exe")
    End SubFunction FindProcess(ByVal strExeFileName As String) As String
        Dim i As Long
        Dim strFileName As String
        Dim hMod As Long, pId(1024) As Long, hProcess As Long, dwNeeded As Long, dwTemp As Long    strExeFileName = LCase(StrReverse(strExeFileName))
        EnumProcesses pId(0), 1024 * 4, dwNeeded
        For i = 1 To dwNeeded
            If pId(i) = 0 Then Exit For
            hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pId(i))
            If hProcess <> 0 Then
                strFileName = String(1024, vbNullChar)
                strFileName = Left(strFileName, GetModuleFileNameExA(hProcess, 0, strFileName, Len(strFileName)))
                CloseHandle hProcess
                If InStr(LCase(StrReverse(strFileName)), strExeFileName) = 1 Then
                    FindProcess = strFileName
                    Exit For
                End If
            End If
        Next
    End Function
      

  6.   

    7 楼的哥们 谢谢你 你这取到得是 程序的完整运行路径 不是 这个程序的 主窗体的HWND我现在吧这些进程的pid 取出来了 如何从 PID 到 主窗体的 HWND呢?
    从CSDN搜到这个 Function InstanceToWnd(ByVal target_pid As Long) As Long
        Dim test_hwnd As Long, test_pid As Long, test_thread_id As Long
        'Find the first window
        test_hwnd = FindWindow(0&, 0&)
        Do While test_hwnd <> 0
            'Check if the window isn't a child
            If GetParent(test_hwnd) = 0 Then
                'Get the window's thread
                test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
                If test_pid = target_pid Then
                    InstanceToWnd = test_hwnd
                    Exit Do
                End If
            End If
            test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
        Loop
    End Function可是依然用不成 调试过程中我发现 弟一个取到得HWND都是0 
    test_hwnd = FindWindow(0&, 0&) 这句 搜索微软的帮助 解释说是 一个进程ID和 窗体的HWND 无一一对应关系 所以无法从PID直接取到 HWND 解决办法是 通过PID取到 文件名 程序标题等其他属性 然后枚举比对
    哎 头晕
      

  7.   

    9楼的哥们 您帮帮忙 好人做到底 送佛送到西 能帮我把下面的对比写下么?
    API 我学的真的很烂  现在用的大部分都是COPY的...
      

  8.   


    晕死!我要是能写 我也不用上这问了 就是因为API差才来问
    源码是最好的教程 我想你也知道我找人干活??你这话是不是说的有点过了? 没得罪你吧? 反正我给别人回帖都是给源码 并且配上注释哎 无所谓 专家忙 咱自己琢磨琢磨,下次别人问问题 我要是知道我也告诉他 你去那XXX 然后XXX 这样也挺好是吧
      

  9.   

    算了 我也不问了 源码你也别贴了 省的听你JJYY 
    就这么点代码 我自己研究研究 研究不出来 我也不来这问了 (江南春)  谢谢你 专家有专家的苦衷 不像某某某 JJYY 一个代码没有