はじめに
これは、Visual Basic Advent Calendar 2021の19日目の記事となります。
先日、Twitterを眺めていたら、下記サイトの紹介ツイートを見つけました。
Windowsならバッチで、ファイル参照やフォルダ参照が出来たら便利かも知れないと、早速ググりました。
PowerShellやC#やWSH(JScript)を使用したものが見られます。
この記事は、Visual Basic Advent Calendarですから、WSH(VBScript)で作り直すことにしました。
ファイル選択
下記サイトを参考にWSH(JScript)から、WSH(VBScript)に書き換えました。
アップロード向けファイル選択
HTMLアプリケーション用のファイル選択を利用しているので、ネットに関連したフィルターが用意されています。
項目 | 内容 |
---|---|
初期値 | 指定は出来ません。初期はデスクトップですが別フォルダを選択して閉じた場合、次から同じ親プロセス上なら別フォルダが指定されます。 |
拡張子フィルター | すべてのファイル(.)、画像(.gif,.jpg,.jpeg,.png)、HTML(.htm;.html) |
タイトル | アップロードするファイルの選択 |
@echo off
set dialog="about:<input type=file id=FILE><script language=vbscript>FILE.Click:
set dialog=%dialog%CreateObject("Scripting.FileSystemObject").GetStandardStream(1).WriteLine(FILE.value):
set dialog=%dialog%Close:resizeTo 0,0</script>"
set file=
for /f "tokens=* delims=" %%p in ('mshta.exe %dialog%') do set "file=%%p"
echo selected file is : "%file%"
pause
c:\Temp>fileRef.bat
selected file is : "C:\Temp\江戸時代の円周率.txt"
続行するには何かキーを押してください . . .
汎用向けファイル選択
初期フォルダ、フィルタ、タイトルを指定することが出来ます。
拡張子フィルターで指定するファイルが2種類以上の場合、パイプ(|)を使用します。
参照:【C#】オープンファイルダイアログ-ファイル指定(フィルター)
項目 | 内容 |
---|---|
初期値 | set "File=(初期値を指定)" |
拡張子フィルター | set "Filter=(フィルターを指定)" |
タイトル | set "Title=(タイトル名を指定)" |
@echo off
set "File=C:\Temp\*.txt"
set "Filter=テキスト (*.txt)|*.txt|すべてのファイル (*.*)|*.*|"
set "Title=ファイルの選択"
set dialog="about:<object id=HtmlDlgHelper classid=CLSID:3050f4e1-98b5-11cf-bb82-00aa00bdce0b></object>
set dialog=%dialog%<script language=vbscript>resizeTo 0,0:Sub window_onload():
set dialog=%dialog%Set reg=CreateObject("VBScript.RegExp"):reg.Pattern="\0.*":
set dialog=%dialog%Set Env=CreateObject("WScript.Shell").Environment("Process"):
set dialog=%dialog%ret=HtmlDlgHelper.object.openfiledlg(Env("File"),,Env("Filter"),Env("Title")):
set dialog=%dialog%CreateObject("Scripting.FileSystemObject").GetStandardStream(1).Write reg.Replace(ret,""):
set dialog=%dialog%Close:End Sub</script><hta:application caption=no showintaskbar=no />"
set file=
for /f "delims=" %%p in ('MSHTA.EXE %dialog%') do set "file=%%p"
echo selected file is : "%file%"
pause
注意点として、初回は拡張子フィルターにテキスト (*.txt)
を指定しているが、全ての拡張子が表示されてしまう。
一旦、拡張子フィルターをすべてのファイル (*.*)
にしてからテキスト (*.txt)
を指定すると指定した拡張子のみが表示されるようになる。
次からは同じ親プロセス上なら、テキスト (*.txt)
が指定された状態になっている。
c:\Temp>fileRef.bat
selected file is : "C:\Temp\江戸時代の円周率.txt"
続行するには何かキーを押してください . . .
苦労した点
最初は参考サイトではなく別の方法で検証していたのですが、バッチファイルではパイプ記号(|)のエスケープ処理が難しいかったです。ハット(^)記号をパイプ記号の前に付けてもエラーになり動いてくれない。
参考サイトにて下記のように引数にして渡せば、パイプ記号(|)のエスケープ処理なしで動作できることが分かって、採用しました。
set "Filter=テキスト (*.txt)|*.txt|すべてのファイル (*.*)|*.*|"
Set Env=CreateObject("WScript.Shell").Environment("Process")
ret=HtmlDlgHelper.object.openfiledlg(Env("File"),,Env("Filter"),Env("Title")):
フォルダ選択
項目 | 内容 |
---|---|
ルートフォルダ | set "RootFolder=(ルートフォルダを指定)" |
メッセージ | set "Title=(メッセージ名を指定)" |
@echo off
set "RootFolder=C:\Temp"
set "Title=読込みフォルダを選択してください"
set dialog="about:<script language=vbscript>resizeTo 0,0:Sub window_onload():
set dialog=%dialog%Set Shell=CreateObject("Shell.Application"):
set dialog=%dialog%Set Env=CreateObject("WScript.Shell").Environment("Process"):
set dialog=%dialog%Set Folder=Shell.BrowseForFolder(0, Env("Title"), 1, Env("RootFolder")):
set dialog=%dialog%If Folder Is Nothing Then ret="" Else ret=Folder.Items.Item.Path End If:
set dialog=%dialog%CreateObject("Scripting.FileSystemObject").GetStandardStream(1).Write ret:
set dialog=%dialog%Close:End Sub</script><hta:application caption=no showintaskbar=no />"
set folder=
for /f "delims=" %%p in ('MSHTA.EXE %dialog%') do set "folder=%%p"
echo selected folder is : "%folder%"
pause
c:\Temp>folderRef.bat
selected file is : "C:\Temp\Test"
続行するには何かキーを押してください . . .
最後に
これまでは、フォルダ固定にしていたりファイルやフォルダをドラッグ&ドロップして引数から処理してました。自分が使用するだけならいいのですが、他の人に操作を依頼するなら、GUIでファイル選択やフォルダ選択できれば、操作性は向上します。
例として、江戸時代の円周率.txt
ファイルを指定していました。実は江戸時代の寺子屋では、円周率は3.16で教えていたのです。明治になって円周率は3.14に訂正されました。そんな記事をnoteに書きました。