はじめに
Windows10は良い,実に良い。WSL (Windows Subsystem for Linux) が使えるからだ。Linux を常用している人には不満かもしれないが,自分のようにたまに使う程度であれば,これで十分だと思う。Windows とのデータ交換も便利だし,何より Linux 用の HDD を用意しなくて済む。
X サーバに VcXsrv を使用している人も多いだろう。VcXsrv の起動には付属の XLaunch を使用していると思うが,起動するたびに以下のような設定画面が毎回表示されて実に鬱陶しいのだ。

解決策はさほど難しくない。まず上記の起動画面にて設定ファイルを適当な名前で適当なフォルダに保存する。設定ファイルは XML 形式となっている。
<?xml version="1.0" encoding="UTF-8"?>
<XLaunch WindowMode="MultiWindow" ClientMode="NoClient" LocalClient="False" Display="-1"
LocalProgram="xcalc" RemoteProgram="xterm" RemotePassword="" PrivateKey="" RemoteHost=""
RemoteUser="" XDMCPHost="" XDMCPBroadcast="False" XDMCPIndirect="False" Clipboard="True"
ClipboardPrimary="True" ExtraParams="" Wgl="False" DisableAC="True" XDMCPTerminate="False"/>
次に XLaunch を起動するショートカットを作成し,-run
オプションを付けて先の設定ファイルを指定すれば良い。
C:\Program Files\VcXsrv\xlaunch.exe -run c:/users/********/config.xlaunch
ところがだ・・・こうすると VcXsrv は一瞬で起動するうえ,とても静かに起動する・・・が,逆に何のメッセージも表示されないため,クリックミスを疑って多重起動してしまうというミスを多発してしまった。メモリが溢れない限り,気にしない人も多いかもしれない。
解決方法
VcXsrv を起動する XLaunch を起動する VBScript を作成し,二重起動をチェックする。また,起動を目立たせるためスプラッシュウィンドウを表示させる。
スプラッシュ画面の表示
コチラは簡単である。WScript.Shell
オブジェクトの PopUp
メソッドを使えば良い。このメソッドは指定したメッセージを指定した時間だけ表示した後,自動的に閉じてくれる。また,メソッドの終了を待たなくて良い。参考資料も多い。
Dim shell: Set shell = CreateObject("WScript.Shell")
Dim msg(1)
msg(0) = "VCXSRV.EXE を起動しています・・・"
msg(1) = "(このウィンドウは自動的に閉じます)"
shell.PopUp Join(msg, vbCrLf), 5, "二重起動防止スクリプト", vbOkOnly
二重起動チェック
コチラは WMI (Windows Management Infrastructure) を使う。まずは WMI サーバーオブジェクトを取得する。取得方法は二種類あるようだ。
Dim loc: Set loc = CreateObject("WbemScripting.SWbemLocator")
Dim wmic: Set wmic = loc.ConnectServer(".", "root\cimv2")
Dim wmic: Set wmic = GetObject("winmgmts:\\.\root\cimv2")
次に得られた WMI サーバーオブジェクトを用いてプロセスを検索すればよい。プロセスリストを取得して検索しても良いが,この場合はプロセス名の大文字・小文字に注意する必要がある。
Dim list: Set list = wmic.ExecQuery("Select * From Win32_Process")
Dim proc
For Each proc in list
If UCase(proc.Name) = "VCXSRV.EXE" Then
MsgBox "既に VCXSRV.EXE は起動しています!!", vbExclamation
WScript.Quit
End If
Next
一方,名前付きでプロセスを検索するときは大文字・小文字の区別はないようだ。
Dim list: Set list = wmic.ExecQuery("Select * From Win32_Process Where Name='VCXSRV.EXE'")
If list.Count > 0 Then
MsgBox "既に VCXSRV.EXE は起動しています!!", vbExclamation
WScript.Quit
End If
実装コード
以上をまとめると次のようなコードになる。VcXsrv を起動する XLaunch を起動するスクリプトなので XLaunch Launch,すなわち XLaunch² である。
Option Explicit
'-------------------------------------------------------------------------------
' VCXSRV.EXE の二重起動チェック
'-------------------------------------------------------------------------------
Dim wmic: Set wmic = GetObject("WinMgmts:Root\Cimv2")
Dim list: Set list = wmic.ExecQuery("Select * From Win32_Process Where Name='VCXSRV.EXE'")
If list.Count > 0 Then
MsgBox "既に VCXSRV.EXE は起動しています!!", vbExclamation, "二重起動防止スクリプト"
WScript.Quit
End If
'-------------------------------------------------------------------------------
' スプラッシュウィンドウの表示 ※5秒間表示する
'-------------------------------------------------------------------------------
Dim shell: Set shell = CreateObject("WScript.Shell")
Dim msg(1)
msg(0) = "VCXSRV.EXE を起動しています・・・"
msg(1) = "(このウィンドウは自動的に閉じます)"
shell.PopUp Join(msg, vbCrLf), 5, "二重起動防止スクリプト", vbOkOnly
'-------------------------------------------------------------------------------
' VCXSRV.EXE の起動
'-------------------------------------------------------------------------------
shell.CurrentDirectory = "C:\Program Files\VcXsrv"
shell.Run "xlaunch.exe -run c:/users/*******/config.xlaunch"
起動画面
VcXsrv が既に起動されていなければ次のような起動画面が5秒間表示される。ちなみに「OK」ボタンを押すとスプラッシュ画面は閉じられるが,VcXsrv はそのまま起動される。

多重起動の場合は次のようなエラー画面が表示される。

参考文献
スプラッシュ画面関連
- 第7回 WshShellオブジェクトの詳細(3) - atmarkit
- 第13回 WshShellオブジェクトを利用する(2) - atmarkit
- VBScript で、すぐに消えるダイアログを表示する - Qiita
WMI (Windows Management Infrastructure) 関連