如何使用Java Native Access从打开的Windows控制台(命令提示符)读取内容 [英] How do I read the contents from an open Windows Console (Command Prompt) using Java Native Access

查看:111
本文介绍了如何使用Java Native Access从打开的Windows控制台(命令提示符)读取内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想阅读命令提示符窗口的文本内容。假设我打开了一个命令提示符,然后先运行 dir 命令,然后先运行 pwd 命令。因此,问题陈述是,无论在命令提示符下出现什么内容,我都应该能够阅读它们。我正在尝试使用 Java Native Access 库来实现此目的,但是并没有带来任何运气。我试过下面的代码。但是我没有任何输出。

I want to read the text contents of the command prompt window. Let's say, I opened a command prompt, then ran a dir command and then pwd command. So the problem statement is that, what ever is present in the command prompt I should be able to read them. I am trying to use Java Native Access library for achieving this, but didn't get any luck with it. I have tried following code. But I am not getting any output.

import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;

public class NativeExtractor {

    public static void main(String ar[]) throws InterruptedException {
        System.out.println(System.getProperty("sun.arch.data.model"));
        executeNativeCommands();
    }

    public static void executeNativeCommands(){
        User32 user32 = User32.INSTANCE;
        //HWND notePadHwnd = user32.FindWindowA("Notepad",null  );
        HWND consoleHwnd = user32.FindWindowA("ConsoleWindowClass",null  );
        HWND editHwnd = user32.FindWindowExA(consoleHwnd, null, null, null);
        byte[] lParamStr = new byte[512];
        LRESULT resultBool = user32.SendMessageA(editHwnd, User32.WM_GETTEXT, 512, lParamStr);

        System.out.println("The content of the file is : " + Native.toString(lParamStr));
    }

    interface User32 extends StdCallLibrary {
        User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
        int WM_SETTEXT = 0x000c;
        int WM_GETTEXT = 0x000D;
        int GetWindowTextA(HWND hWnd, byte[] lpString, int nMaxCount);
        boolean EnumWindows(WinUser.WNDENUMPROC lpEnumFunc, Pointer arg);
        HWND FindWindowA(String lpClassName, String lpWindowName);
        HWND FindWindowExA(HWND hwndParent, HWND hwndChildAfter, String lpClassName, String lpWindowName);
        LRESULT SendMessageA(HWND paramHWND, int paramInt, WPARAM paramWPARAM, LPARAM paramLPARAM);
        LRESULT SendMessageA(HWND editHwnd, int wmGettext, long l, byte[] lParamStr);
        int GetClassNameA(HWND hWnd, byte[] lpString, int maxCount);

        void EnumChildWindows(HWND hwnd, WNDENUMPROC microsoft_word_document, Object o);
    }
}

不过,我可以使用读取记事本的文本下面。但是对于命令提示符来说,一切都不起作用。请帮我解决这个问题。

Nevertheless, I can read the text of the notepad using below. But things are not working for command prompt . Please help me in resolving this .

public static void executeNativeCommands(){
        User32 user32 = User32.INSTANCE;
        HWND notePadHwnd = user32.FindWindowA("Notepad",null  );
        HWND editHwnd = user32.FindWindowExA(notePadHwnd, null, null, null);
        byte[] lParamStr = new byte[512];
        LRESULT resultBool = user32.SendMessageA(editHwnd, User32.WM_GETTEXT, 512, lParamStr);

        System.out.println("The content of the file is : " + Native.toString(lParamStr));
    }


推荐答案

其他StackOverflow的简要调查像之类的答案表明,并非所有应用程序都响应 SendMessage()函数,Windows控制台(命令提示符窗口)就是其中之一。虽然 SendMessage 提供了标准功能,但是当它不起作用时,您必须对要从中读取文本的程序使用本机API;在这种情况下,使用控制台。

A brief survey of other StackOverflow answers like this one indicate that not all applications respond to the SendMessage() function, and the Windows Console (Command Prompt window) is one of those. While SendMessage provides a standard functionality, when it doesn't work you must use the Native API for the program you're trying to read text from; in this case, the Console.

Windows具有完整的控制台API ,其中包括用于与控制台进行交互的众多功能。 JNA的 WinCon 类,该类由 Kernel32 继承,包括 AttachConsole 方法将另一个PID的控制台链接到您的进程 GetConsoleWindow 获取句柄,然后 FreeConsole 提取完句柄后,但是要读取控制台的内容,您需要扩展 Kernel32 自己的界面c ode以添加更多映射函数:

Windows has a complete Console API that includes numerous functions for interacting with the console. Some console functions are already mapped in JNA's WinCon class which is inherited by Kernel32, including the AttachConsole method to link another PID's console to your process, GetConsoleWindow to obtain the handle, and FreeConsole when you are done fetching the handle, but to read the contents of the console you'll need to extend the Kernel32 interface in your own code in order to add more mapped functions:

public interface MyKernel32 extends Kernel32 {
    MyKernel32 INSTANCE = Native.load("kernel32", MyKernel32.class, W32APIOptions.DEFAULT_OPTIONS);

    // Mapped functions go here
}

完整的解决方案对于这个答案来说有点多,但是在尝试实现这个问题时,可以随时更新您的问题。您将需要映射以下函数:

Writing the full solution is a bit much for this answer, but feel free to update your question as you attempt to implement this. You'll need to map the following functions:

  • GetConsoleScreenBufferInfoEx (Vista+) or GetConsoleScreenBufferInfo (Win2K+) to get the console's buffer coordinates (rows and columns) to know how far back you can read
  • ReadConsoleOutput to actually copy the contents of the console buffer into your own buffer of characters to manipulate

这篇关于如何使用Java Native Access从打开的Windows控制台(命令提示符)读取内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆