標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

NYAGOS 4.4.4_0 を公開しました(その1)

記念すべき「令和元年」最初のリリースになります。括目せよ!(しなくてよい)

  • (#233) \\host-name\share-name を補完できるようになった

宿願である2年越し issue の補完を実装しました。

仕事を VMWare 上の Windows で行うことが多いのですが、ソースを置いているホスト側のフォルダーを net use P: \\vmware-host\Shared[TAB] とドライブをアサインする際に補完できないのが非常に苦痛でした。最近でこそ net use P: \\vmware-host\Shared" "Folders と空白の周辺だけ二重引用符で囲むという技を身につけて楽になっていましたが、以前は \\ までカーソルを戻して二重引用符を挿入していたのです。

無論なんとかしたかったのですが、WNetEnumResourceW をはじめとする mpr.dllAPI の使い方が分からなかった。最近になってようやく解決したのは、先日、記事に書いたとおりです。最終的な実装ソースは dos/netresource.go をご覧ください

だが、\host-name の補完だけはまだひどく遅い。改善に取り組んだ結果、share-name は普通の速度になったものの、host-name だけは最初の1回だけは…。エクスプローラーでは速くはないがまだ許容範囲でした。おそらく永続化したキャッシュを使ってるのでしょうね。こっちも永続化キャッシュを使うという手もありますが、いつ破棄するかという問題がつきもので、扱いが難しい。というわけで今のところ永続化は問題先送りです。

そのかわりというわけではありませんが、待っている間ハングアップしたかのように見えるのを回避するため / (スラッシュ)が回転するアニメをコンソールで表示するようにしました。さぁ、dir \\[TAB] してみましょう!

  • (#238) copyコマンドで進捗表示をするようにした

これも2年越しの issue ですね。CopyFileExW の引数にコールバック関数を渡せばよいだけの話なんですが、実装する気力がなくて放置してました。

手こずるかなーと思っていたのですが、やってみたら、64bit版は結構あっさりできました。具体的な実装コードは nodos/copy_windows.goです。

32bit 版はしばらくしてから動かないのに気づきました。uintptr の幅が違っていて、ファイルサイズを表す uint64 を渡せなくなってたんですね。上位32bitと下位32bitを別のuintptr として渡すようにしました。

  • 環境変数名=値 コマンド名 パラメータ… をサポート

env GOOS=linux go build を結構多用するようになったんですが、env と打つのも面倒になってきました。この時の環境変数は os.Setenv で恒久的に設定するのではなく、os.ProcessStart のパラメーターで子プロセスにのみ引き渡します。

  • バッチファイル用の一時ファイル名が重複する問題を修正

バッチファイルを実行する際、バッチファイルで変更される環境変数を取り込むために、nyagos-(PID).txt という一時ファイルを CMD.EXE にはかせていたんですが、

バッチファイル名1  | バッチファイル名2

とやったら、その一時ファイルのパスが重複してエラーになってしまいました。

  • (#277) set /a 式を実装

えーと、それほど必要性も高くなかったんですが、一旦 issue を自分で立てて「やっぱりやめました」もかっこ悪いので、がんばりました。とはいえ、今 issue にある奴のいくつかは「やっぱりやめました」不可避なんですが汗

この issue 自体は1年ほど寝かしていたものですね。意外と短い

  • (#291) バックグラウンド実行のプロセスのIDを表示するようにした

本件とは別に Use ShellExecuteEx as api to run GUI application. · Issue #288 · zetamatta/nyagos という issue がありまして、これを実現した結果、ShellExecuteExW で起動するプロセスの PID が取れるようになりました。CreateProcessW の方はそう難しくないので、結果、本件が物理的にできるようになりました。もうやるしかないでしょう。

当初は考えていなかったのですが、プロセスが終わった時に「プロセスID Done」みたいな出力も出すようにしました。これ、実はプロセス監視用に goroutine を立ち上げているのですが…まぁ、無限ループ回しているわけではなくて "os".(Process)Wait を呼んでるだけなので、許してくれますよね。

  • (#361) GUIアプリの標準出力がリダイレクトできなかった問題を修正

GUI アプリは ShellExecute* で実行していたので、普通にやると標準出力を切り替えることはできません(sudo win32 みたいに、ShellExecute される側に起動するためのランチャープログラムを用意していたら話は別)。

なので、リダイレクトする時だけ、CreateProcessW(os.ProcessStart) を使うよう修正しました。


今回のリリースでは他にもいろいろ行ったのですが、長いので続きは次回の記事にて…