Windowsではbatファイルをダブルクリックするとファイルに記述されたスクリプトを実行することができます。
ダブルクリックで実行するとコマンドプロンプトのウインドウが表示されて処理が実行されます。メッセージを出力するようなスクリプトならそれでよいのですが、GUIアプリを起動するだけのスクリプトだとなんだか行けてない感じを受けます。
以前、WSL上のLinux GUIアプリを起動できるようにしたことがあったのですが、GUIアプリ実行中にウインドウが表示されたままになり結構気になっていました。その時は時間もなかったですし、ダブルクリックでLinux GUIアプリを起動するという目的は達成していたのでそこまでにしていたのですが、何とかプロンプトウインドウを表示せずに実行できないかと思い調べてみました。
先に結論
ウインドウを表示したくないスクリプト(もしくはコマンド)のショートカットを作成してプロパティを開き、リンク先を powershell.exe -WindowStyle Hidden -ExecutionPolicy RemoteSigned <元のファイルパス>
に変更すればOKです。
例えば元のスクリプトファイルが xxx.ps1
なら
powershell.exe -WindowStyle Hidden -ExecutionPolicy RemoteSigned xxx.ps1
のようにします。
スクリプトの内容によっては実行ポリシーを変更する必要があるかもしれません。必要に応じてオプション -ExecutionPolicy
を変更したり管理者権限で実行するなどしてください。
注意:拡張子を見るとわかる通り、PowerShellスクリプトで実現しています。この記事で書いている方法ではbatファイルでは実現できません。
どうしても既存のbatファイルでやりたいという方は、がんばってPowerShellスクリプトに書き換えるかVBScriptを使った方法があるようなのでそちらを試してみるとよいかもしれません。
ちなみに、スクリプトを書くほど長いコードでない場合は、うまくワンライナーコードを書いてやればこの記事の方法で出来ます。
以降は解説です。
cmd.exe は(基本的に)ウインドウを隠せない
batファイルをダブルクリックすると cmd.exe
によってスクリプトが実行されます。
cmd.exe のヘルプを見たりググったりしてみたのですが、どうもcmd.exeではウインドウを表示しないようにするのは難しそうです。
少し工夫した方法として、VBスクリプトを使う方法があるようなのですが、わざわざVBスクリプトを使うのもなぁという気持ちになったので他を探します。
powershell.exe ならウインドウを隠せる
PowerShell(powershell.exe)はコマンドプロンプト(cmd.exe)の代わりとして作られたのだからいろいろできるようになっているのでは?と思って調べてみたらありました。ウインドウを表示しないオプション。
これならPowerShellで書いたスクリプトであればウインドウを表示せずに実行できそうです。
PowerShell は(既定では)ダブルクリックで実行できない
batファイルを使う感覚でPowerShellのスクリプトファイルを作ってダブルクリックする感じにしたいのですが、デフォルトの設定では実行できないようです。
理由は2つ。
一つ目はわかりやすくて、既定のプログラムがPowerShellを実行するプログラムでないため。
二つ目は既定の実行ポリシーとしてPowerShellスクリプトを実行できないように設定されているため。
既定のプログラムを powershell.exe
にして、実行ポリシーを緩くしてやればダブルクリックで実行可能なのですが、この件のためにセキュリティを下げたりするのは個人的に好ましくないですね。
-ExecutionPolicy
で実行ポリシーを指定できる
また powershell.exe のヘルプで見つけました。 -ExecutionPolicy
でそのセッションに限定して実行ポリシーを指定できるようです。
これでセキュリティレベルの低下を限定的にできます。
ショートカットならオプション付きで powershell.exe を実行できる
ショートカットは特定のファイルへのリンクを作る機能ですが、そのリンク先の文字列に引数やオプションを含めることもできます。
これを利用して -WindowStyle
や -ExecutionPolicy
オプションを指定します。
例えば以下はPowerShell経由で電卓を起動するだけの単純な例です。
powershell.exe -WindowStyle Hidden -ExecutionPolicy RemoteSigned calc.exe
これで実行してみます。
一瞬、黒いウインドウが見えますね。ショートカットのプロパティで「実行時の大きさ」を最小化に指定するとこれも見えなくなります。
これで、calc.exeの部分を任意のスクリプトファイルやPowerShellのワンライナーコードにすることで、やりたいことは実現できそうです。
余談:ワンライナーコードの場合は実行ポリシーの制約を受けない?
実は前述の calc.exe を実行する例では -ExecutionPolicy を指定しなくても実行可能です。
実行ポリシーが最も厳しい Restricted でもコマンドをいくつか実行する程度のワンライナーコードであれば実行できました。もしかするとスクリプトファイルの実行時にしか実行ポリシーは考慮されないのかもしれませんね。
Linux GUIアプリを起動してみる
電卓だと全く意味ないので、この方法を使ってLinux GUIアプリを起動してみます。X410のセットアップなどは完了している状態です。そちらについて知りたい場合は、以前の記事を見てください。
今回は gedit を起動してみます。
ショートカットのリンク先に以下の文字列を書きます。
powershell.exe -WindowStyle hidden wsl -d Ubuntu-18.04 -- export DISPLAY=`$`(cat /etc/resolv.conf `| grep nameserver `| awk `'`{print `$2`; exit`;`}`'`):0.0`; gedit
これで実行してみます。
起動できました。起動できない場合はX410が起動していることを確認したり実行ポリシーを指定したりしてみるといいかもしれません。
これで完成でもよいのですが、このままだとリンク先の文字列がすごくわかりにくいです。原因はWSLに渡すコマンド文字列にPowerShellで制御文字として認識される文字が多くあるためそれぞれエスケープしているせいです。
本題と外れますが、後から見たときに困らないようにWSLで実行する部分はWSL側でスクリプトにしてしまおうと思います。
$HOME/bin/wsl-gedit
を作成して以下の内容を記述します。
#!/usr/bin/env bash
export DISPLAY="$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0"
gedit
実行権限を付けるのを忘れずに。
chmod u+x $HOME/bin/wsl-gedit
これで、別のショートカットを作りリンク先を以下のようにします。
powershell.exe -WindowStyle hidden wsl -d Ubuntu-18.04 -- `$HOME/bin/wsl-gedit
大分読みやすくなりました。実行してみます。
大丈夫そうです。
最後に
この方法ならLinux GUIアプリを他のWindowsアプリとほとんど同じような感覚で利用できますね。
今までPowerShellについて深く調べたことはなかったのですが、ヘルプを見ただけでもかなり高機能だなぁと感じました。
今まではbashなどUnix系のシェルと同じ感覚で使っていたこともあり、違う部分の多さに使いにくいというイメージが強かったですが、きちんと理解して使えばすごく便利そうなので今度きちんと調べてみようと思いました。