どろどろの手動GUI作業を少しでもスマートにできないかコードで戦ってみた話


アウトプット強化週間!(第5版)

昨日はターミナル作業の話、今日はGUI作業をなんとかしたかったの話


あるある

寝食削ってその世界にハマった。ちょまどさんが語る、プログラミングへの尽きせぬ「愛」とは

エビデンス自動化の部分があるある過ぎる・・・

この世には自分にそっくりな人が3人はいるそうだが、たぶん、SIerでこのケースでは何千人かいそうな気がする。自作自動化ツール展とかやったら超絶楽しそうだけど、開発エピソード聞いたら涙が止まらなくなりそうだ。

愚痴コーナー

どうもAnsibleやらRPAやらを「楽して楽ができるツール」(よくわからない日本語のようで経験者はわかりますよね)みたいに扱っているフシがあるんだけど、そもそもコンピューターの作業を手動で行う事自体に品質の問題があって自動化=高速化=楽ではないんだ。

自動化には誤作動しないようにデバックしたりの下準備が必要で、実は手を動かすのは準備が無いのでトータルでは手動の方が短時間だったりするけどSIerの仕事だとそれが分かっていないのか自動化エライみたいになってしまうし、有名なOSSでお墨付きがあると余計にそっちに勾配降下していく。

僕はスクラッチでも良いと思ってて繰り返す作業の品質を担保するように局所的に最適化したツールをメンテナンスし続けるのも一つの手だと思う。手になじむものを大事にするの大工の道具とおんなじ気がする。チームで共有言語化しているのが大事なんだよね。

というような前口上からあんたのツールは?

少なくとも操作してからのエビデンス取得の手動繰り返しは避けたい。ツール配布を考えてgolangで作ろうとすると

ってのがあるんだけどCrossCompilingって項目があるのに実際にLinuxからコンパイルするとエラーで通らない。色々試したけどだめ

# github.com/robotn/gohook
/tmp/go-build114241532/b042/_x003.o: In function `eb_port_create':
/root/pkg/mod/github.com/robotn/[email protected]/event/../chan/eb_chan.h:382: undefined reference to `sched_yield'
/tmp/go-build114241532/b042/_x003.o: In function `eb_port_free':
/root/pkg/mod/github.com/robotn/[email protected]/event/../chan/eb_chan.h:350: undefined reference to `sched_yield'
/root/pkg/mod/github.com/robotn/[email protected]/event/../chan/eb_chan.h:341: undefined reference to `sched_yield'
/tmp/go-build114241532/b042/_x003.o: In function `cleanup_ops':
/root/pkg/mod/github.com/robotn/[email protected]/event/../chan/eb_chan.h:858: undefined reference to `sched_yield'
/tmp/go-build114241532/b042/_x003.o: In function `port_list_signal_first':
/root/pkg/mod/github.com/robotn/[email protected]/event/../chan/eb_chan.h:643: undefined reference to `sched_yield'
/tmp/go-build114241532/b042/_x003.o:/root/pkg/mod/github.com/robotn/[email protected]/event/../chan/eb_chan.h:643: more undefined references to `sched_yield' follow
collect2: error: ld returned 1 exit status

(これ解決できた人いますかね?)

クロスコンパイルはあきらめて、WSL+msys2の構成でWindows上でのコンパイルは実行できたものの、zlib1.dllが必要なようでそのせいでgolangのワンバイナリのメリットが死んでしまう。

(htmlとかcsvみたいな静的なファイルをワンバイナリに組み込むツールはあるが、そもそも起動に影響するDLLをパッケージ化する方法は無い)

よってgolangの良さを活かしつつツール化してみた。

https://github.com/yasutakatou/guicast/releases
(バイナリも置いてみました。64bit windowsで動きます。)

動かすとプロンプトが出てくる。昨日のとおんなじですねーシェルのライブラリおなじですからね。

>>>

基本動作は 文字列 or キー操作のエミュレートと指定したウィンドゥ名のキャプチャ採取 の繰り返し。以下動作画像のようにあらかじめChromeをターゲットに設定してある。

>>> config
wait:1
count:1
changeWindow:ctrl,\t
targetWindow:Chrome
autoCapture mode: false
captureWait:1
captureHang:10
capturePath:

ウィンドゥ名[Chrome]をターゲットに操作/文字列を投げ込んだら1秒待ってCtrl+Tabでタブを切り替える。繰り返しは1回。

特徴として繰り返し回数とか柔軟に変更できるので操作端末のスペックが早ければ同時に何十窓でも開いて繰り返し可能。キャプチャが画像なので保存に時間がかかる点はSSDとか早いディスクで解消できる

操作/文字列は[ ]でくくると操作をなげます。ctrl,\tならCtrl+Tab、alt,\aならAlt+Aです。[ ]が無いと文字列が投げられます。また | で一行でまとめて投げられます。test|\nならtestを入力してリターンになります。オプションは

>>> count 3

みたいに使います。以下があります。(helpみたいな説明いらなそうなのははしょりました)

Commands:
  !                自動キャプチャ設定しててもキャプチャしないで投げ込みします
  autoCapture      投げ込み後に自動キャプチャします。タブ数+日時でpngが作られます
  captureHang      キャプチャに時間がかかりすぎるときに処理を止めます
  capturePath      キャプチャの保存パス。デフォはバイナリと同じところ
  captureWait      キャプチャ一回毎に待ちを入れます。僕のPCが激遅なので用意しましたがSSDならゼロでもいいのかも
  change           タブを切り替えるコマンドです。
  count            タブを繰り返す回数です
  list             起動させているウィンドゥ名を一覧で表示します
  onlyCapture      キャプチャだけします。投げ込みはしません。
  target           操作したウィンドゥ名を指定します
  wait             投げ込み後の待ち時間です。これも早いPCなら一秒も待たなくて良いかもしれないです。

これで一人3多重程度だった、ぽちぽち作業を15~20多重で作業する事が出来た。キャプチャも取り漏れなし。作業端末が遅いのでたっぷりウェイトかけてるのでもち手打ちの方が早いけど、もっと早い端末ならウェイト減らしても平気なはず。昨日のみたくJupyterのkernel作ったら実行できる手順書になるので手順書を眺めつつ作業が無くなるので、さらに作業者は楽だし作業品質も高まるよね。

RPAも良いんだけど、古い人間なのでターミナルに寄ってしまいました。ぽちぽちを避けるのに別のぽちぽちを産むのが嫌だったもので。

まあ案の定、黒画面見た事が無いような人が使えるわけも無く、闇に葬られたわけなんですけど。。(オチ)

同じ作業を何百回と繰り返すとなると・・おわかりですよね。腱鞘炎ですね。
ぽちぽち100万回/年にも耐えられるようにエンジニアには筋肉が必要だ!というのもわからんでもないな。