2012年8月5日日曜日

Windows でサウンドの再生デバイスを切り替えるためのスクリプト(バッチ処理)

1. サウンドの再生デバイスを切り替える操作は手間がかかる

Windows で USB スピーカーとヘッドフォンを切り替えるためには、コントロールパネルの「サウンド」で変更する。

  1. コントロール パネル\ハードウェアとサウンド\サウンドを開き、
  2. 出力先にしたいデバイスを「規定値に設定」し、
  3. OK ボタンを押す。

何度もクリックしなくてはならないので、手間がかかる。

この操作をワンクリックで済ませたい。

SnapCrab_サウンド_2012-8-4_9-40-49_No-00

 

2. 再生デバイスを切り替えるスクリプト

には、オーディオデバイスを変更する方法が書かれている。

これを参考にして、以下のスクリプトを作成した。ファイルのエンコーディグは Shift_JIS 。

var wait = function(title){
    do {
	WScript.Sleep(100);
    } while(!WshShell.AppActivate(title));
};

var WshShell =  WScript.CreateObject("WScript.Shell");
WshShell.Run("control mmsys.cpl");
wait("サウンド")
WshShell.SendKeys("{DOWN " + 
	WScript.Arguments.item(0) +
	"}%{s}{TAB 3}{ENTER}");

スクリプトを使用するには、

  1. テキストファイルに上記を貼り付け保存し、ファイル名を changeSoundDevice.js とする。
  2. changeSoundDevice.js に対するショートカットを作成する。
  3. ショートカットのプロパティを開き、「ショートカット」タブのリンク先の末尾に、「切り替えたい再生デバイスが上から何番目にあるか」指定する。

例えば、自分の環境ではヘッドフォンは上から 2 番目にあり、USBスピーカーは 5 番目にある。それぞれ changeSoundDevice.js に対するショートカットを作成し、ショートカットのリンク先の末尾に、

  • ヘッドフォン: … changeSoundDevice.js 2
  • USBスピーカー: …changeSoundDevice.js 5

SnapCrab_NoName_2012-8-5_10-0-9_No-00と入力する。また、スクリプトを起動するために wscript.exe を先頭に入力する。

C:\Windows\System32\wscript.exe [スクリプトへのパス] [引数...]

後は、ショートカットのアイコンを変更し、クイック起動に登録した。

 

3. デバイスを切り替えた後にユーティリティーを再起動したい場合

サウンドで設定したデバイスの音量を、素早く変更するために Tray Volume を利用している。

デバイスを変更した場合、Tray Volume を再起動しないと、変更したデバイスの音量を Tray Volume で変更できない。

Tray Volume を再起動するためのバッチファイルは既に作成してある。

SnapCrab_NoName_2012-8-5_9-57-2_No-00上記のスクリプトの最後に Tray Volume を再起動するためのバッチファイルを呼び出すように変更した。

ただし、バッチファイル名は restart.bat とし、changeSoundDevice.js と同じフォルダに置くこと。

 

スクリプト内からバッチファイルを「引数付き」で呼び出す場合の注意点

追記(2013/09/12)restart.bat を再起動するアプリケーションを指定できるように汎用化した。それに伴い、上記のスクリプトを変更した。

注意する点は、引数に空白を含むパスを指定する場合、ダブルクォーテーションで囲み、ディレクトリの \ を \\ と書くこと。

VBScrip の場合は、以下を参照。

基礎解説 演習方式で身につけるチェック式WSH超入門:第12回 WshShellオブジェクトを利用する(1) (1/2) - @IT

実行ファイルのパスに半角スペースが含まれている場合は注意が必要だ。Runメソッドはそのような場合、実行ファイルのパスを ""(ダブル・クォーテーション記号)で囲む必要がある。すなわち、Internet Explorer(C:\Program Files\Internet Explorer\iexplore.exe)を起動するには、

objWshShell.Run """C:\Program Files\Internet Explorer\iexplore.exe"""

と書く必要がある。ちなみに、「"(ダブル・クォーテーション)」が3つ連続しているのは、"~"の中では、" を記述するためには "" と重ねて記述しなければならないからである。

 

4. スクリプトについて

スクリプトは JScript で記述されている。

JScript – Wikipedia とは、

JScript(ジェイ・スクリプト)は、マイクロソフト社製のスクリプト言語であり、Microsoft Windows 上で動作する。

JavaScriptと類似しており、… また、Windows Script Host(WSH) を利用することで、Windows 上でのバッチ処理を記述することができる。

拡張子は、通常 .js を使用する。

Windows Script Host – Wikipedia とは、

Windows Script Host(ウインドウズ・スクリプト・ホスト)とは、Microsoft Windowsにおいてテキストファイルに記述したスクリプトを実行するスクリプト実行環境である。…

Windows 98から搭載された。Unixにおけるシェルスクリプトや、MS-DOSにおけるバッチファイルと似た位置づけの技術である。

a. WScript オブジェクトと WshShell オブジェクト

WScript オブジェクト とは、

Windows Script Host のオブジェクト モデルのルート オブジェクトへのアクセスを提供します。

WScript オブジェクトの CreateObject メソッド を用いて、

COM オブジェクトを作成します。

CreateObject メソッドで生成するのは WshShell オブジェクト

ネイティブの Windows シェルへのアクセスを提供します。

SnapCrab_NoName_2012-8-5_14-1-44_No-00

WshShell オブジェクトの Run メソッド を利用して、プログラムを起動する。

新しいプロセス内でプログラムを実行します。

起動したアプリケーションをアクティブにするためには AppActivate メソッド を利用する。

アプリケーション ウィンドウをアクティブにします。

WScript オブジェクト のSleep メソッド をコマンドの間に挟まないと、ユーザが操作したときのように、GUI が上手くキー入力を受け付けてくれない。

スクリプトのプロセスをミリ秒で指定された長さだけ非アクティブにした後、実行を再開します。

ユーザのキー入力をシミュレートするには、WshSell オブジェクトSendKeys メソッド を用いる。

キーボードから入力したときのように、1 つ以上のキー ストロークをアクティブなウィンドウに送ります。

スクリプトに与えられた引数は WScript オブジェクトの Arguments プロパティ を通して行われる。

 

b. コントロールパネルのサウンドをコマンドプロンプトから呼び出す

@IT:Windows TIPS -- Knowledge:コントロール・パネル・アイテムをコマンドラインから呼び出す によると、

コマンドラインやスクリプトからコントロール・パネル・アイテムを実行するには、対応するシステム・フォルダ中のcpl形式ファイルを実行すればよい。前述したとおり、デフォルトのWindowsに含まれるアイテムは、「%SystemRoot%\system32」に保存されている。

cplファイルはDLLファイルであり、コマンドラインで実行する場合、本来はcontrolコマンドのパラメータとして次のように指定する必要がある。

c:\>control main.cpl ←「マウス」アイテムが実行される

しかしcplファイルは実行コマンドと関連付けられているため、コマンド名“control”を省略してcplファイル名を直接実行してもよい。

サウンドのプロパティをコマンドラインから、起動するには以下のコマンドを入力する。

mmsys.cpl

ただし、JScript の中でコマンドを呼び出すとき、

control mmsys.cpl

と記述しないとエラーとなった。

 

c. バッチ処理では pause コマンドで処理を止める

当初、コントロールパネルのサウンドを起動し、ユーザが変更を完了した後に、Tray Volume を再起動する処理にしようと考えた。しかし、サウンドは普通のアプリケーションを扱うようにはいかなかった。

例えば、バッチファイルに、起動したいアプリケーションを連続して記述すると、

notepad
notepad

最初に起動したアプリケーションを終了させた後に、次のアプリケーションが起動する。

start コマンドを使うと、各々独立したウィンドウで開かれる。

コマンドプロンプトを使ってみよう! -設定・システム操作- によると、

startは、現在実行中のコマンドプロンプトとは別のウィンドウを開き、
してされたコマンドまたは、プログラムを実行するコマンドである。

start notepad
start notepad

start コマンドの wait オプションは、前のアプリケーションが終了するまで次のアプリケーションを起動しない。

start /wait notepad
start /wait notepad

しかし、コントロールパネルのサウンドは、wait オプションを使っても、ユーザが設定を完了する前に、次の文が実行される。

start /wait mmsys.cpl
start /wait notepad

mmsys.cpl は、設定を完了することと、アプリケーションを終了させたことが同義ではないようだ。仕方がないので、サウンドを開いた後、pause コマンドを利用して、次の文が実行されるのを防ぐことにした。

mmsys.cpl
pause

しかし、これでは使い勝手が悪いので、下記スクリプトに変更した。

var wait = function(title){
    do {
	WScript.Sleep(100);
    } while(!WshShell.AppActivate(title));
};

var WshShell =  WScript.CreateObject("WScript.Shell");
WshShell.Run("control mmsys.cpl");
wait("サウンド")
WshShell.SendKeys("{DOWN " + 
	WScript.Arguments.item(0) +
	"}%{s}{TAB 3}{ENTER}");

WshShell.Run("restart.bat");

 

d. Windows Script Host でスクリプトを実行する

JScript を実行するには、C:\Windows\System32\wscript.exe を利用する。

スクリプトがあるフォルダで、コマンドプロンプトを用いてスクリプトに引数を与え実行するには、

wscript changeSoundDevice.js 5

とする。

アイコンをクリックして、上記のコマンドを実行したい場合は、

  1. 上記のスクリプトへのショートカットを作成
  2. ショートカットのプロパティを開く
  3. リンク先フィールドに C:\Windows\System32\wscript.exe [スクリプトへのパス] [引数] を入力する。

4コメント:

匿名 さんのコメント...

やったー!毎日面倒だった切り替えが一発でできるようになりました。これは感動。
ありがとうございました。

匿名 さんのコメント...

これはすばらしい!
ソフトに頼らずにすみました。
ありがとうございます。

ちなみに、Vista では「TAB」の次の数字を「4」に書き換える必要がありました。
Vista なひとのために記しておきます。

匿名 さんのコメント...

ちょうど同じことをしたく調べていてビンゴでした、ありがとうございますっ。

Vistaでしたので上記コメもとても参考になりました。

匿名 さんのコメント...

残念ですが、Windows10ではコンパイルエラー(9行目16文字目)で動作しませんでした。