This site is a mirror of ama.ne.jp.

icon of Amane Katagiri WScript . ShellからStart-Processへ(一敗と、さらにその後)

Windowsでウィンドウを一切表示せずにバックグラウンドで実行してほしいスタートアッププログラムがあるとき、VBScriptで以下のスクリプトを用意しておくと便利ですね。

Set ws = CreateObject("WScript.Shell")
ws.run "WRITE YOUR COMMAND HERE", vbhide

これを startup-your-brain.vbs として保存して、スタートアップフォルダ1にショートカットを置くと、次回起動時から指定したプログラムが起動します。画面には変化がありませんが、タスクマネージャーから見ると起動しているのが確認できるかもしれません。

ws.run がプログラムを実行するメソッドで、 vbhide オプションによってウィンドウが作られなくなるようです。与えたプログラムがジョブの完了と共に終了するものならプロセスは残りませんし、バックグラウンドで何かを実行するプログラムならずっと待機してくれます。

VBScript(Microsoft Visual Basic Scripting Edition)は、1996年からJScriptと共にブラウザでの処理を目的に搭載されたスクリプト言語です。これがWindows上で動作するスクリプトエンジンWSH(Windows Script Host)で動作する汎用スクリプト言語として採用され、今回のようなバッググラウンドでのスタートアップに使えるようになりました。

しかし、Windowsの普及初期から長い歴史が続くVBScriptは、Visual BasicやVBA(Visual Basic for Applications)に比べて言語としての表現力が低く、使いにくい点も多いです。また、2024年頃にはVBScriptを中長期的に廃止する計画が発表されており2、2027年にはデフォルトでインストールされなくなると明言されています。

Windows上で動作する汎用スクリプトとしてのVBScriptの代替は、既にPowerShellが担っています。PowerShellは2003年頃からWSHの代替として開発された新世代のシェルであり、現在は主にPowerShell 5.1とPowerShell 7.xが利用できます。スクリプトファイルの拡張子は *.ps1 です。

さて、冒頭のバッググラウンドでのスタートアップをPowerShellで書くにはどうしたらいいでしょうか? 調べてみると、以下のような感じになりそうです。

Start-Process -FilePath "COMMAND" -ArgumentList "-y our --argument list" -WindowStyle Hidden

では、保存した startup-your-brain.ps1 を実行してみましょう。

……あれ、ダブルクリックしても実行できませんね。コンテキストメニューに「PowerShell で実行」があります。いったん試してみましょうか。

このシステムではスクリプトの実行が無効になっているため、ファイル startup-your-brain.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
    + CategoryInfo          : セキュリティ エラー: (: ) []、ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnauthorizedAccess

コンソールアプリ特有の黒い画面が表示され、こんなエラーが赤文字で出てきました。なんだか怖いですね。特に実行ポリシーを触ったことはなかったのですが、今は「Restricted」になっています。このポリシーでは、PowerShell上でコマンドを実行できても、スクリプトを起点にした実行はできないようです。WSHに隠れてマルウェアが爆増した歴史を踏まえれば、セキュリティ上当然の対策かもしれませんが、ちょっと不便ですね。

では、ショートカットでPowerShellを経由してスクリプトを呼ぶ作戦に切り替えてみましょう。一時的にポリシーを「RemoteSigned」にゆるめるオプションを与えたショートカットを作り、ローカルのスクリプトを実行できるようにします。

powershell -ExecutionPolicy RemoteSigned -File "startup-your-brain.ps1"

……おっ、動いていそうです! しかし、黒いウィンドウが一瞬表示されてしまいました。これでは「ウィンドウを一切表示せずにバックグラウンドで実行」とはなりません。

では、PowerShellのポリシー自体をゆるくしたらどうでしょう? 一時的な実験として、実行ポリシーを「RemoteSigned」にしてみます。

> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): y

この状態で、もう一度 startup-your-brain.ps1 を「PowerShell で実行」してみます。

このポリシーならスクリプト単体で動きましたが、やはり黒いウィンドウが表示されてしまいました。どうも、PowerShell単体では黒いウィンドウは抑制できないように見えます。コンソールアプリだからでしょうか?

PowerShell -WindowStyle Hidden -Command Exit と足すといい、という情報もかなり流通していて試しましたが、動作はほぼ変わりませんでした。調べた感じでは、おそらくタスクスケジューラに登録しても変わらないみたいです。確かに、過去にバッチファイル(コマンドプロンプト)でいろいろな回避策を試して上手くいかなかった末にVBScript経由で起動しているわけなので、問題が逆戻りしただけという気がします。

……なるほど。つまり、現時点ではVBScriptからPowerShellに移行するメリットはなさそうです。2027年になってもインストールすればまだまだVBScriptは使えるので、急いで移行しなくても大丈夫かもしれません。

うーん。与えられたプログラムを起動するだけの透明なGUIツールがほしいだけなのに――あれ? これ、さっさと作っちゃった方が早い気がしますね。C#とかはビルド環境を整えるのが面倒そうなので、Goでやってみましょうか。

package main

import (
    "os"
    "os/exec"
    "syscall"
)

func main() {
    if len(os.Args) < 2 {
        return
    }
    cmd := exec.Command(os.Args[1], os.Args[2:]...)
    cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
    cmd.Start()
}

これだけシンプルなら、脆弱性が入り込む余地もないでしょう。マルウェアの隠れ蓑にはなるかもしれませんが……まぁ、これくらいツールキットなら同梱されているレベルのものです。では、Windows向けにビルドしてみますね。

GOOS=windows GOARCH=amd64 go build -ldflags "-H=windowsgui" -o silent.exe main.go

-ldflags="-H windowsgui" でGUIアプリとしてビルドします。

これで、VBScriptから本当に欲しい機能だけを抜き出したシンプルなツールの完成です。もしGoのビルド環境はないけど使ってみたい、かつ私を信頼できる方はビルド済みの silent.exe を差し上げますのでお使いください。

では、早速使ってみましょう! これならショートカット方式で呼び出せるはずです。以下のようなショートカットを作ります。

silent.exe COMMAND -y our --argument list

ダブルクリックで起動すると、無事に「ウィンドウを一切表示せずにバックグラウンドで実行」できるはずです! これでもう、VBScriptが明日いきなり消えてしまっても安心ですね。

しかし、VBScript( *.vbs )とJScript( *.js )のスクリプトファイルのアイコンが消えてしまうのは少し寂しい気持ちもあります。VBScriptは水色の巻物が、JScriptは黄色い巻物が広げられたかわいいアイコンが使われているんですよ。知っていましたか?

~左からVBScript・JScriptのアイコン、用途不明な白地に青文字の巻物アイコン

一方でPowerShellのアイコンは、プロンプト3をモチーフにしたクールでシンプルなデザインです。もちろん、高機能でモダンなスクリプトエンジンに切り替えるのは、利便性の向上やセキュリティ面でも非常に重要なことでしょう。それでも、時代遅れのWSHと一緒にこうしたレトロなセンスまで消滅してしまうのは、なかなか惜しいものだと思ってしまいます。


  1. エクスプローラで shell:startup と入力して移動するのが速いです。 

  2. VBScript deprecation: Timelines and next steps | Windows IT Pro Blog 

  3. 近年でいうところのエーアイに与える命令ではなく、ユーザが入力可能なことを示すUIとしての文字列( > $ # など)のこと。 

「読んだ」を押すと、あなたがボタンを押した事実を明示的に通知してこのページに戻ります。このページに戻ってからブラウザの「戻る」ボタンを押すと、何度か同じページが表示されることがあります。