はじめに
サポンテはさまざまなところに行って、さまざまな仕事をしています。最近(少し前)、異動はしていないのですが Windows 10 -> Windows 11 に移行しました。
サポンテはデフォルトのままでは使っていないため、自分なりの環境構築に時間がかかります。次にどこかに異動になったとき、すぐに業務に取り掛かれるように Windows 11 用の必須設定を備忘録として、ここに記しておきます。
続きを読むWindows では Alt + PrintScreen キーで、アクティブウィンドウのキャプチャを取得する機能があります。また、Microsoft Office のスクリーンショット機能でも、特定のウィンドウを選択してキャプチャを撮れる機能があります。
しかし、しばしば「特定のウィンドウと、その手前に表示されたダイアログを一緒に撮りたい」という要件がしばしば発生します。なんらかのエラーメッセージに遭遇したとき、背面に表示されているウィンドウの状況と一緒に撮影したい場合です1。
もちろん「範囲選択」を使えば事足りるのですが、そもそもせっかくウィンドウの矩形が判っているのに、わざわざマウスを操作して(それもウィンドウの背景がなるべく入り込まないように神経を使いながら)手間をかけなければならないのでしょうか。面倒です。
PowerShell で解決してみます。
シェルの実行中でも、ユーザーに注意を促すために GUI のダイアログを表示したい要件はしばしばあります。
PowerShell で実現する方法を調べていたところ、いくつかの方法がありつつ、自分の求めているものとは違っていた部分もあったので、ここに記します。
サポンテが求める要件は以下の二つです。
特に大切なのは後者です。実際に業務で「ダイアログがウィンドウの後ろ側に回り込んで、ダイアログが表示されていることが分からなかった」「ウィンドウが固まって操作が不能になった」「どのウィンドウで発生しているエラーか分からない」などのクレームをもらうことがあります。「ダイアログをモーダルで表示する」ところで考えが止まってしまって「どのウィンドウで管理されているダイアログなのか」を考慮していないアプリケーションは少なくないようです。ユーザーはとても困ってます。
Windows 11 で動作確認しました。Windows 10 だとどうなるかは不明です。
$src=@' using System; using System.Runtime.InteropServices; public static class Win32 { private static int GW_HWNDNEXT = 2; [DllImport("user32.dll")] public extern static int MessageBox(int hWnd, string msg, string caption, int uType); [DllImport("user32")] private extern static int GetParent(int hWnd); [DllImport("user32")] private extern static int GetWindow(int hWnd, int wCmd); [DllImport("user32")] private extern static int FindWindow(string lpClassName, string lpWindowName); [DllImport("user32")] private extern static int GetWindowThreadProcessId(int hWnd, out int lpDwProcessId); [DllImport("user32")] private extern static int IsWindowVisible(int hWnd); // プロセスID(pid)をウィンドウハンドル(hWnd)に変換する public static int GetHwndFromPid(int pid) { int hWnd; hWnd = FindWindow(null, null); while (hWnd != 0) { if (GetParent(hWnd) == 0 && IsWindowVisible(hWnd) != 0 && pid == GetPidFromHwnd(hWnd)) { return hWnd; } hWnd = GetWindow(hWnd, GW_HWNDNEXT); } return hWnd; } // ウィンドウハンドルを(hWnd)をプロセスID(pid)に変換する public static int GetPidFromHwnd(int hWnd) { int pid; GetWindowThreadProcessId(hWnd, out pid); return pid; } } '@ Add-Type -TypeDefinition $src # 自分自身を実行しているターミナルのプロセス ID を取得する $parentPid = 0 Get-WmiObject win32_process -filter processid=$pid | ForEach-Object { $parentPid = $_.parentprocessid; } # 自分自身を実行しているターミナルの Window Handle を取得する $hWnd = [Win32]::GetHwndFromPid($parentPid) # 取得できないなら止むを得ない。無念...。 if ($hWnd -eq 0) { $hWnd = $null; } # メッセージボックスを表示する [Win32]::MessageBox($hWnd, "コンテキスト", "キャプション", 0)
以下のサイトを参考にしました。ありがとうございます。
PowerShellでメッセージボックスを使う4つの方法 - 適材適所 PIDとHWNDの変換(C#/VB.NET) [サンプルソース] [ヨーキー景吾の逃走]
あと、ターミナルのプロセス ID を取得するところは Yahoo!知恵袋 さんのどこかのアンサーを参考にしたのですが失念してしまいました。
サポンテは macOS と Windows を半々の割合で使っているので、キーボードショートカット1なんてそんなにたくさん覚えられないんですよ。だから Spotlight や Launchy で「単語登録」って入力したら、使っている IME の単語登録機能が起動して欲しい。
やり方は、それぞれ単語登録アプリが格納されている場所(パスなど)が分かれば簡単です。
(ググっても「IME パッドから...」とかいう記事ばかり出てきたのですが、そうではない方法を探しているんですよ)
現在サポンテがメインで使っている「かわせみ3」。
いったんメニューから「単語登録/削除...」を起動します。
起動した「単語登録/削除.app」が Dock 表示されるので、副クリック2して「オプション > Finderに表示」を選択します。Finder に表示された「単語登録/削除.app」のエイリアスをどこかに作り、「単語登録」というファイル名にしておけば、Spotlight が拾ってくれて起動できるようになります。
ちなみにサポンテはだいたい、そういうものは ~/Applications
に入れています。
システム環境設定の中に入っていたので「AppleScript を使うしかないんだろう」と思っていましたが、Apple のディスカッションボードに既にスクリプトがありました。すばらしい!
tell application "System Settings" tell pane id "com.apple.Keyboard-Settings.extension" reveal anchor "TextReplacements" end tell activate end tell
※ activate
のタイミングだけ変更させていただいています。
Launchy のカタログに C:\Windows\System32\IME\IMEJP\IMJPDCT.exe
をショートカットなどで登録します。
環境によって違うかもしれませんが、サポンテが使っている Windows 11 ではそれで対応できました。
その他の IME については使っていない由、分かり兼ねますです。すみません。
macOS については上記「かわせみ3」のようなやり方で、他も応用が利くのではないかと思っています。
Windows の他のバージョンについても、大きくは変わらないかと思います。
Windows ではエクスプローラーのアドレスバーに cmd
とか powershell
とか入力すると、エクスプローラーで開いているディレクトリをカレントとしてターミナルを開いてくれます。
便利!1
Subversion でも同じことをしたい。いちいち右クリックとかしたくない。
サポンテは職場で TortoiseSVN を使用しています。svn
コマンドを直接使うことはほとんどないのですが、作業フォルダですばやく「リポジトリブラウザ」を開きたいことがよくあります。エクスプローラーのアドレスバーに subversion
とか入力すると2リポジトリブラウザを起動してほしい!というコンセプトで、昨日の git に続いてスクリプトを作ります。
パスの通っている位置に、バッチファイルを作るだけです。
サポンテは「Scripts」などの名前のフォルダを作って、そこに色々入れています。そのフォルダは Launchy のカタログ化対象にも登録していて、グローバルに起動するスクリプトもそこに格納しています。
Git に比べると少々複雑になります。
@echo off for /f "usebackq delims=" %%A in (`cd`) do set CURRENT_DIR=%%A start "subversion" "TortoiseProc.exe" /command:repobrowser /path:"%CURRENT_DIR%"
これを subversion.bat
のようなファイル名で、先ほどの「パスの通っているフォルダ」に置いてください。アドレスバーに subversion
とタイプして Enter キーを押すと、リポジトリブラウザが開くはずです。
以上です。3
Windows ではエクスプローラーのアドレスバーに cmd
とか powershell
とか入力すると、エクスプローラーで開いているディレクトリをカレントとしてターミナルを開いてくれます。
便利!1
Git for Windows でも同じことをしたい。いちいち右クリックとかしたくない。
パスの通っている位置に、バッチファイルを作るだけです。
サポンテは「Scripts」などの名前のフォルダを作って、そこに色々入れています。そのフォルダは Launchy のカタログ化対象にも登録していて、グローバルに起動するスクリプトもそこに格納しています。
@echo off start "git bash" "C:\Program Files\Git\git-bash.exe"
これを git.bat
のようなファイル名で、先ほどの「パスの通っているフォルダ」に置いてください。アドレスバーに git
とタイプして Enter キーを押すと、git bash が開くはずです。
以上です。
Subversion については明日書きます。