各言語のプログラム雛形の作成条件

    • Visual studio codeや秀丸でプログラミング。

 

    • コンパイルはVisual studioとかは使わずにコマンドで手動。

 

    • 200ミリ秒ごとにループ(繰り返し)する。

 

    • ループを一周する毎に、変数「t」の値を「1」増やす。

 

    • 「←」の矢印ボタンを押した時、反応する。

 

    • GetAsyncKeyStateからの出力は、変数「key37」に格納する。

 

    • 絵文字を使いたいのでファイルはutf-8で保存する。

 

     (C++は日本語や絵文字が文字化けした!)

パソコン環境

    • Windows10 : 22H2

 

    • WindowsTerminal(プレビュー版) : 1.19.2831.0

 

    • c++のコンパイラ g++ : 10.3.0

 

    • C#のコンパイラ csc : 4.8.9037.0

 

    • Go : 1.21.3

 

    Rust : 1. 72.0

プログラミング結果

C++

↓13行・249文字

#include <iostream>
#include <windows.h>

int main(){
    long t = 0;
	while(1){
		int key37 = GetAsyncKeyState(37);
        std::cout << "C++ Left-button " << t << " " << key37  << std::endl;
		Sleep(200);
        t++;
	}
	return 0;
}

C++出力結果

image.png

C#

↓15行・515文字

using System;
using System.Threading;
class hello_GetAsyncKeyState {
	[System.Runtime.InteropServices.DllImport("user32.dll")]
	private static extern short GetAsyncKeyState(int vKey);
	public static void Main() {
		Console.OutputEncoding = System.Text.Encoding.GetEncoding("utf-8");//?の文字化け対策
 		int t = 0;
		while(true){
			short key37 = GetAsyncKeyState(37);
			Console.WriteLine("C#「← 」キーを押したか?? {0} {1} {2}",t,key37,key37&0x1);
			Thread.Sleep(200);
			t++;
		}
	}
}

C#出力結果

image.png

Go言語

↓22行・421文字

package main

import (
	"fmt"
	"time"
	"golang.org/x/sys/windows"
)

var (
	moduser32            = windows.NewLazyDLL("user32.dll")
	procGetAsyncKeyState = moduser32.NewProc("GetAsyncKeyState")
)

func main() {
	t := 0
	for {
		key37, _, _ := procGetAsyncKeyState.Call(uintptr(37))
		fmt.Println("Go「← 」キーを押したか?? ", t, key37, key37&0x1)
		time.Sleep(200 * time.Millisecond)
		t++
	}
}

image.png

Rust

↓7行・164文字

[package]
name = "file_name"
version = "0.1.0"
edition = "2021"

[dependencies]
windows = { version = "0.51.1", features=["Win32_UI_Input_KeyboardAndMouse"] }

↓15行・約406文字

use std::thread;
use std::time::Duration;
use windows::Win32::UI::Input::KeyboardAndMouse::GetAsyncKeyState;
 
fn main() {
    let mut t =0;
    unsafe {
        loop{
            let key37 = GetAsyncKeyState(37);
            println!("Rust 「← 」キーが押したか?? {} {} {}",t,key37,key37&0x1);
            thread::sleep(Duration::from_millis(200));
            t =t+1
        }
    }
}

Rust出力結果

image.png

感想

三つ並べるとロゼッタストーンみたい。
以下は「C」「JavaScript」「VBA」「Go」で趣味で遊んだ経験を踏まえての感想(愚痴ばっかり)です。

「C++」

    • 最もシンプルに書ける。

 

    • 「Sleep(200);」と書くだけで0.2秒待ってくれるのは、すごくない?

 

    • 「while(1)」の「1」や「return 0;」の「0」の意味がわからん。

 

    • 「std::cout」もなんだこれ?という感想。

 

    • 最もシンプルに書けるので、C++を使いたいが以下より私には無理だった。

utf-8や絵文字が絶望的に出力できない。
メモリの扱いにプロ技術が必要。

「C#」

    • C#の内部はutf-16なので、utf-8が直接使えなく、絵文字を表現できないのが致命傷。

 

    • utf-8を使う為には以下の一文が必要になる

 

    • 「Console.OutputEncoding = System.Text.Encoding.GetEncoding(“utf-8”);」

 

    • C#ってなんで「class」から始めんとあかんのだ。

 

    • 「private」「pubclic」「static」「void」も非常に鬱陶しい。プログラムが横に長くなる。

 

    • とボヤキつつ、C#の最大最強の魅力はコンパイラ「csc」が標準でWindowsにインストールされている事。

 

    機械系エンジニアには2023年の昨今、もはや管理者権限ない。 会社のパソコンは、2020年頃から管理者権限は剥奪され、ソフトを自由にインストールできない。出来ても限定されたソフトとなる。追加でインストールしたい時には、管理者権限の一時申請やら上司の許可が必要になる。 私は会社内で中堅になったので、今は比較的、会社内の手続きや説明も楽になったけど、理解のない会社や上司だったら無理だろうなと思う。「Visual Studio」とかも「何それ?」となって、インストールなんで夢のまた夢。なので、Visual Studioを使わない素の「csc」と「メモ帳」での野良プログラムは今後も静かな需要があると思う。

「Go」

    • いつもはシンプルなGo言語なのに、今回はシンプルにあらず。

 

    • 今回の方法をWebから探し出すのが苦労した。

 

    • 「NewLazyDLL」や「NewProc」ってなんやねん。一見さんお断り的な。

予備知識として「DLLファイル=Dynamic Load Library」の存在を知らなきゃならない。
「DLLファイル」内部に「GetAsyncKeyState」が入っていることはVBA作成した際に知っているが、なかなか知らんな。
DLLファイルは「C言語」で書かれている。

「Call」もしっくりこない。
「uintptr」も難しい。やめてよって感じ。出てこないで欲しい。ポインター恐怖症。
要するに普段使わない用語を使うという事で。

「Rust」

    • Webで「Rust GetAsyncKeyState」で検索すると「GetAsyncKeyState」を使う方法は複数あり(winapiとかのライブラリもある)迷った。

 

    • 迷った結果、マイクロソフトの「win32metadata」プロジェクトでの「Windowsのwin32クレート」を使ってます。

 

    • マイクロソフトがRustでwin32を使えるようにする「win32metadata」プロジェクトはネットニュースで知っていたが、「Rust GetAsyncKeyState」でgoogle検索しても一番上に検索候補が挙がってこなかった。

 

    • -「Cargo.toml」の[dependencies] (=依存関係) の記述も注意しなくちゃならない。事前準備が必要。

 

    • Rust本文は短めだが、tomlと合計すると記述量はやや多めとなる。

 

    toml内の「Win32_UI_Input_KeyboardAndMouse」で、途中にアンダーバー「_」で繋ぐのは正直、反則だと思う。「::」や「.」で良いだろう。

補足説明

「Win32」って何?

↓ウィキペディアの説明ページ

 

    • Microsoft社のWindowsは、C言語やC++言語で制作されている。

 

    • 結果的にCやC++をコンパイルすれば、そのままOSと同一の機械語に変換できる。

 

    Win32の「32」は、32ビットパソコン時代に作られた為。64ビットCPUの昨今は「Win64」となるが、慣習的にWin32と言えばWin64も含んでいる。

参考にしたサイト

 

simple windows keylogger using GetAsyncKeyState

windows::Win32::UI::Input::KeyboardAndMouse::GetAsyncKeyState

广告
将在 10 秒后关闭
bannerAds