9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Visual BasicAdvent Calendar 2021

Day 19

バッチ実行中にファイル選択やフォルダ選択を行うGUI

Last updated at Posted at 2021-12-19

はじめに

これは、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)
タイトル アップロードするファイルの選択
fileRef.bat
@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

image.png

結果
c:\Temp>fileRef.bat
selected  file is : "C:\Temp\江戸時代の円周率.txt"
続行するには何かキーを押してください . . .

汎用向けファイル選択

初期フォルダ、フィルタ、タイトルを指定することが出来ます。
拡張子フィルターで指定するファイルが2種類以上の場合、パイプ(|)を使用します。
参照:【C#】オープンファイルダイアログ-ファイル指定(フィルター)

項目 内容
初期値 set "File=(初期値を指定)"
拡張子フィルター set "Filter=(フィルターを指定)"
タイトル set "Title=(タイトル名を指定)"
fileRef2.bat
@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)を指定しているが、全ての拡張子が表示されてしまう。
image.png
一旦、拡張子フィルターをすべてのファイル (*.*)にしてからテキスト (*.txt)を指定すると指定した拡張子のみが表示されるようになる。
次からは同じ親プロセス上なら、テキスト (*.txt)が指定された状態になっている。
image.png

結果
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=(メッセージ名を指定)"
folderRef.bat
@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

image.png

結果
c:\Temp>folderRef.bat
selected  file is : "C:\Temp\Test"
続行するには何かキーを押してください . . .

最後に

これまでは、フォルダ固定にしていたりファイルやフォルダをドラッグ&ドロップして引数から処理してました。自分が使用するだけならいいのですが、他の人に操作を依頼するなら、GUIでファイル選択やフォルダ選択できれば、操作性は向上します。

例として、江戸時代の円周率.txtファイルを指定していました。実は江戸時代の寺子屋では、円周率は3.16で教えていたのです。明治になって円周率は3.14に訂正されました。そんな記事をnoteに書きました。

9
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?