JNAを使ってWindowsAPIにアクセスしてWindowsのウィンドウ要素を操作します.

7271 ワード

問題の背景:
私の卒業設計にはWindowsプラットフォームの上にプロセス操作ウィンドウを跨ぐ必要があります.実際にブラウザの上のページのテキストボックスの要素を取得して、windows 32フォームの上の編集枠があります.自動記入値などの操作を行います.
私が考えられるのは全部でこのような方法があります.
  • C〓を使ってフォームアプリケーションを作成し、WebBrowserブラウザコントロールを使用したり、他のアプリケーションウィンドウを埋め込んだりします.WebBrowserコントロールを使用すると、ユーザーに強制的にこのC萍アプリを使ってインターネットを利用することができ、ユーザーの体験に影響を与え、非現実的である.他のアプリケーションウィンドウを埋め込む方式を使うと、プロセスをまたいでウィンドウを取得する方法に変わります.
  • は、ブラウザプラグインを使用して、異なるブラウザに対して異なるプラグインを作成し、ユーザにインストールさせる.ブラウザのページが読み込まれたら、常駐プログラムを使ってブラウザにメッセージを送り、ブラウザのプラグインにあるJSコードを使ってウェブページDOM要素を操作します.しかし、多くのプラグインを作成する必要がありますが、デバッグして、本当に実行するのは難しいです.
  • は、まずリモートスレッドを用いてターゲットプロセスのスレッド空間に注入し、仮想スレッドを作成し、この仮想スレッドを実行して、このウィンドウを持つインターフェーススレッドにメッセージを送信する.実はこの方法は上の方法と大同小異です.ただし、プロセス注入行為はユーザーシステムのセキュリティ機構によって検出されます.360のセキュリティガードのような神経質なセキュリティソフトはユーザーに私達のプログラムを削除させます.その他に各種のブラウザーに対応して、各種のプログラムのフォームは特定の分析処理をして、価格は大きすぎて、私はただ1つの完成しただけで、牛刀を使う必要がないでしょう.
  • は、アナログユーザ操作方式を使用する.まず簡単な方法で言ってください.多くのスクリプト言語はWindows上のVBSスクリプト実行時にWScript常駐プロセスを起動します.VBSのsendKeyコマンドを使ってユーザーの入力をシミュレートできます.VBSでもユーザーマウスのクリックをシミュレートできます.Python、JSなども使えます.彼らの核心は実はWindowsシステムのAPIを呼び出して機能を完成させるものです.構造的にはすべてローカルの即時解凍器を実行しています.Windows APIを起動してスクリプトの実行操作を説明します.もう一つの深いレベルは、ターゲットウィンドウのハンドルを先に取得し、フォームのメッセージ処理キューにWM_を送信することです.SET_TEXT,WM_GET_TEXT,WM_EXITなど各種情報.
  • ここでは、卒業にはプラットフォームにまたがる特性が必要であり、様々な異なるバージョンのWindowsと互換できるようにすることが望ましい.したがって、Java言語のJNAパッケージを使用して提供される便利な機能はWindows APIを呼び出します.JNIを使ってもいいです.DLLを作成して、コンパイルしてデバッグするだけで、時間がかかります.特定の問題に対応していないなら、成熟したJNAを使って、さらに低いレベルの呼び出しの問題を解決してくれるはずです.
  • いくつかのJNAの紹介を抜粋します.
    JNAはJavaプログラムを提供しています.Javaコードを作成する必要はありません.JNIまたは本マシンコードは必要ありません.この機能はWindowsのPlatform/InvokeやPythonのctypesに似ています.JNAはJavaのメソッドを使って、直接に本関数を呼び出すことを許可します.コールは本マシンのコードの呼び出しのように見えます.ほとんどの方法の呼び出しは、特別な処理または構成を必要としない.JNAは小さいJNI在庫の根を使ってローカルコードを動的に呼び出します.開発者はJavaインターフェースを使ってターゲットライブラリの関数と構造を説明します.これは、複数のプラットフォームの構成と構築のためのJNIコードの高いオーバーヘッドをもたらさずに、本機のプラットフォーム機能を容易に利用することを可能にする.したがって、JNAは、プラットフォームの適応と利便性に関心を持つ比較性能を提供し、使用者が多バージョン、マルチプラットフォーム開発プログラムに直面する時間を節約する.
    Windows以外にも、JNAは様々な他のプラットフォームをサポートしています.例えばARM、Android、Linuxなどです.JNAはMavenパッケージ管理でダウンロードできます.
    もしMaven管理パッケージが適用されていないなら、下記の二つのカバンを自分でダウンロードしてプロジェクトに入れることができます.
    http://repo1.maven.org/maven2/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jarhttp://repo1.maven.org/maven2/net/java/dev/jna/jna-plotform/4.4.4.4/jna-plotform-4.4.jar
    これは必須の参考文書です.
    http://java-native-access.github.io/jna/4.4.0/javadoc/
    JNAのGitHubアドレス:
    https://github.com/java-native-access/jna#readme
    その単純性を示すために、次のコードを見ます.
    
    import com.sun.jna.platform.win32.User32;
    import com.sun.jna.platform.win32.WinDef.HWND;
    import com.sun.jna.platform.win32.WinUser;
    /**
     * Created by lenovo on 2017/4/27.
     *   winID           ,            
     *
     */
    public class jnaTest {
        public static void main(String[] args) {
    
            HWND hwnd = User32.INSTANCE.FindWindow
                    (null, "QQ"); //       Windows      ,           。   windows         Windows            ,  windows      ,          。
            if (hwnd == null) {
                System.out.println("QQ is not running");
            }
            else{
                User32.INSTANCE.ShowWindow(hwnd, 9 );        // SW_RESTORE
                User32.INSTANCE.SetForegroundWindow(hwnd);   // bring to front
    
                //User32.INSTANCE.GetForegroundWindow() //        
                WinDef.RECT qqwin_rect = new  WinDef.RECT();
                User32.INSTANCE.GetWindowRect(hwnd, qqwin_rect);
                int qqwin_width = qqwin_rect.right-qqwin_rect.left;
                int qqwin_height = qqwin_rect.bottom-qqwin_rect.top;
    
                User32.INSTANCE.MoveWindow(hwnd, 700, 100, qqwin_width, qqwin_height, true);
                for(int i = 700; i > 100; i -=10) {
                    User32.INSTANCE.MoveWindow(hwnd, i, 100, qqwin_width, qqwin_height, true);   // bring to front
                    try {
                        Thread.sleep(80);
                    }catch(Exception e){}
                }
                //User32.INSTANCE.PostMessage(hwnd, WinUser.WM_CLOSE, null, null);  // can be WM_QUIT in some occasio
            }
    
    // Windows ,User32.dll              API。    JNA         DLL     。
    もし私達は事前にQQプログラムの登録画面を開けて、上のプログラムを実行すると、QQ登録フォームをフロントに置いて表示しながら画面の右から画面の左に移動します.また、windowsプログラミングを学んだことがある人は知っています.一つのwindows 32プログラムは一般的に自分だけのフォーム種類があります.Window Classといいます.例えばwindows下の画像ビューアのメインウィンドウは「Photosheweight View」です.メモ帳ウィンドウのフォーム類は「Notepad」です.ウィンドウクラスはフォームスタイルで、複数のフォームクラスを定義できます.もちろん、Windows 32プログラムは他のプログラムのフォーム類も使用できます.上記のFindWindow関数の最初のパラメータは、低レベルJNA呼び出しFindWindowEXの関数検索の範囲を縮小することができるフォームクラス名に入ることができる.Windowsフォームの情報は、WinIDというソフトウェアで照会することができます.VSプログラミングのクラスメートはSpy++ツールで見ることができます.
    上で述べた主な問題を解決します.
    
    import com.sun.jna.platform.win32.BaseTSD;
    import com.sun.jna.platform.win32.User32;
    import com.sun.jna.platform.win32.WinDef;
    import com.sun.jna.platform.win32.WinUser;
    
    /**
     * Created by lenovo on 2017/4/27.
     *   winID           ,            
     *
     */
    public class jnaTest {
        public static void main(String[] args) {
    
            WinDef.HWND hwnd = User32.INSTANCE.FindWindow
                    (null, "QQ"); //       Windows      ,           。   windows         Windows            ,  windows      ,          。
            if (hwnd == null) {
                System.out.println("Excel is not running");
            }
            else{
                User32.INSTANCE.ShowWindow(hwnd, 9 );        // SW_RESTORE
                User32.INSTANCE.SetForegroundWindow(hwnd);   // bring to front
    
                String username = "yourQQnumber";
                for(Character c: username.toCharArray())
                sendChar(c);
            }
        }
    
        static WinUser.INPUT input = new WinUser.INPUT(  );
        static void  sendChar(char ch){
    
            input.type = new WinDef.DWORD( WinUser.INPUT.INPUT_KEYBOARD );
            input.input.setType("ki"); // Because setting INPUT_INPUT_KEYBOARD is not enough: https://groups.google.com/d/msg/jna-users/NDBGwC1VZbU/cjYCQ1CjBwAJ
            input.input.ki.wScan = new WinDef.WORD( 0 );
            input.input.ki.time = new WinDef.DWORD( 0 );
            input.input.ki.dwExtraInfo = new BaseTSD.ULONG_PTR( 0 );
            // Press
            input.input.ki.wVk = new WinDef.WORD( Character.toUpperCase(ch) ); // 0x41
            input.input.ki.dwFlags = new WinDef.DWORD( 0 );  // keydown
    
            User32.INSTANCE.SendInput( new WinDef.DWORD( 1 ), ( WinUser.INPUT[] ) input.toArray( 1 ), input.size() );
    
            // Release
            input.input.ki.wVk = new WinDef.WORD( Character.toUpperCase(ch) ); // 0x41
            input.input.ki.dwFlags = new WinDef.DWORD( 2 );  // keyup
    
            User32.INSTANCE.SendInput( new WinDef.DWORD( 1 ), ( WinUser.INPUT[] ) input.toArray( 1 ), input.size() );
    
        }
    }
    
    使用前にターゲットフォーカスを選択する必要があります.
    参考サイト:http://www.rgagnon.com/topics/java-jni.html このサイトにはいくつかのJNAの実例があります.Windowsフォームのプログラミングに詳しい友達は簡単に見えるはずです.https://github.com/java-native-access/jna#readmehttp://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html これはシンガポール理工大学のウェブサイトです.JNIに入門したいのですが、行ってみてもいいです.http://stackoverflow.com/questions/28538234/sending-a-keyboard-input-with-java-jna-and-sendinput sendkey方法を含む使用https://coderanch.com/t/635463/java/JNA-SendInput-function sendkey方法を含む使用
    強いGoogleに感謝します.
    転載先:https://www.cnblogs.com/yumingle/p/6776258.html