2015-04-08 4 views
0

Я хочу, чтобы имитировать VK_ENTER в консольной программе.Можно отправить сообщение VM_CHAR на запуск программы консоли ProcessBuilder? (windows platform)

Я могу отправить сообщение VK_ENTER сообщение успешно, когда я запускаю программу на cmd.exe вручную.

Он не находит hwnd консольной программы, которая запускается ProcessBuilder.

@Test 
public void testGetPid(){ 
    ProcessBuilder pb = new ProcessBuilder("test.exe"); // not work 
    // ProcessBuilder pb = new ProcessBuilder("notepad.exe"); // work 
    Process p = null; 
    try { 
     p = pb.start(); 

     //"handle" 

     System.out.println(p); 

     Field f = p.getClass().getDeclaredField("handle"); 
     f.setAccessible(true); 
     long procHandle = f.getLong(p); 

     System.out.println("Handle: " + procHandle); 

     //Kernel32.INSTANCE. 

     HANDLE handle = new HANDLE(); 
     handle.setPointer(Pointer.createConstant(procHandle)); 

     final int pid = Kernel32.INSTANCE.GetProcessId(handle); 
     System.out.println("Pid: " + pid); 

     ThreadUtil.sleep(5*1000); 

     sendKeyToProcess(pid); 

    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } finally { 
     ThreadUtil.sleep(60*1000); 
     if(p != null) 
      p.destroy(); 
    } 

} 

     private void sendKeyToProcess(final int pid) { 
    final User32 user32Lib = User32.INSTANCE; 

    final int WM_KEYDOWN = 0x0100; 
    final int WM_KEYUP = 0x0101; 
    final int WM_CHAR = 0x0102; 


    user32Lib.EnumWindows(new WinUser.WNDENUMPROC() { 
     @Override 
     public boolean callback(HWND paramHWND, Pointer paramPointer) { 

      IntByReference intRef = new IntByReference(); 
      user32Lib.GetWindowThreadProcessId(paramHWND, intRef); 

      if(pid == intRef.getValue()){ 
       // final WPARAM wPARAM = new WPARAM(13); // enter 
       final WPARAM wPARAM = new WPARAM(48); // '0' 
       final LPARAM lPARAM = new LPARAM(0); 

       System.out.println("Match hwnd: " + paramHWND.toString()); 
       user32Lib.PostMessage(paramHWND, 
         WM_KEYDOWN, wPARAM, lPARAM); 
       User32.INSTANCE.EnumChildWindows(paramHWND, 
         new WinUser.WNDENUMPROC() { 
          @Override 
          public boolean callback(HWND childParamHWND, 
            Pointer paramPointer) { 
           System.out.println("send"); 
           user32Lib.PostMessage(childParamHWND, 
             WM_KEYDOWN, wPARAM, lPARAM); 
           return true; 
          } 
         }, null); 

       //return false; 
      } 

      return true; 
     } 
    }, null); 
} 
+0

можете ли вы отправить любой существующий код, который у вас есть, и ошибку, которую вы получите с помощью этого кода? – BMac

+0

Вы имеете в виду 'WM_CHAR'? – EJP

+0

Я использовал JNA для EnumWindows, и я также использовал spy ++ для поиска окна процесса. Я не могу найти идентификатор окна для консольной программы. Кстати, я также попытался использовать выходной поток для записи '\ n' и '\ r'. – user1283035

ответ

0

Это работа для меня: (Все решения ЮНА)

  1. CreateProcess с STARTF_USESHOWWINDOW и CREATE_NEW_CONSOLE флаг
  2. EnumWindows с PROCESS_INFORMATION dwProcessId найти окно идентификатор процесса (GetWindowThreadProcessId)
  3. PostMessage с идентификатором окна процесса для отправки введите