【问题标题】:Is possible to send VM_CHAR message to a console program launch by ProcessBuilder? (windows platform)是否可以将 VM_CHAR 消息发送到 ProcessBuilder 启动的控制台程序? (视窗平台)
【发布时间】:2015-04-08 14:56:33
【问题描述】:

我想将VK_ENTER 模拟为控制台程序。

当我通过cmd.exe手动启动程序时,我可以成功发布VK_ENTER消息。

找不到ProcessBuilder启动的控制台程序的hwnd。

@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);
}

【问题讨论】:

  • 您能否发布您拥有的任何现有代码以及您收到的代码错误?
  • 你的意思是WM_CHAR
  • 我用JNA到EnumWindows,也用spy++找进程窗口。我找不到控制台程序的窗口 ID。顺便说一下,我也试过用输出流写'\n'和'\r'。
  • WM_CHAR 是 Windows 键盘消息。控制台程序捕获消息以做某事。 msdn.microsoft.com/en-us/library/windows/desktop/…

标签: java windows processbuilder postmessage


【解决方案1】:

这对我有用:(所有 JNA 解决方案)

  1. 带有 STARTF_USESHOWWINDOW 和 CREATE_NEW_CONSOLE 标志的 CreateProcess
  2. 使用 PROCESS_INFORMATION dwProcessId 查找进程窗口 ID 的 EnumWindows (GetWindowThreadProcessId)
  3. 带有要发送的进程窗口 ID 的 PostMessage 进入

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多