48

通常、バッチ スクリプトにファイル名を指定するようにユーザーに要求するのは厄介な作業であり、スペルミスや、スペースを含むパスの前後の引用符などは必要ありません。残念ながら、ユーザーの精度はよく知られていません。入力ファイルの場所が実行時までわからない状況では、ファイル選択入力に GUI を使用すると、ユーザー エラーの可能性が減少します。

File... OpenWindows バッチ スクリプトからスタイル GUI ファイル チューザーまたはフォルダー チューザーを呼び出す方法はありますか?

スクリプト ユーザーが PowerShell または .NET をインストールしている場合は可能です。以下の回答を参照してください。

また、他の誰かが提供できる他のソリューションにも興味があります。

4

9 に答える 9

62

ファイルブラウザ

2016.3.20 を更新:

PowerShell は最近のほぼすべての最新の Windows インストールのネイティブ コンポーネントであるため、C# フォールバックは不要になったと宣言します。Vista または XP との互換性のためにまだ必要な場合は、新しい回答に移動しました。この編集から始めて、スクリプトをバッチ + PowerShell ハイブリッドとして書き直し、複数選択を実行する機能を組み込みます。読みやすく、必要に応じて微調整するのが非常に簡単です。

<# : chooser.bat
:: launches a File... Open sort of file chooser and outputs choice(s) to the console
:: https://stackoverflow.com/a/15885133/1683264

@echo off
setlocal

for /f "delims=" %%I in ('powershell -noprofile "iex (${%~f0} | out-string)"') do (
    echo You chose %%~I
)
goto :EOF

: end Batch portion / begin PowerShell hybrid chimera #>

Add-Type -AssemblyName System.Windows.Forms
$f = new-object Windows.Forms.OpenFileDialog
$f.InitialDirectory = pwd
$f.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
$f.ShowHelp = $true
$f.Multiselect = $true
[void]$f.ShowDialog()
if ($f.Multiselect) { $f.FileNames } else { $f.FileName }

これにより、ファイル選択ダイアログが表示されます。

ファイルチューザー

You chose C:\Users\me\Desktop\tmp.txt選択の結果はコンソールに出力されます。強制的に単一のファイルを選択する場合は、$f.Multiselectプロパティを に変更します$false

(PowerShell コマンドはJust Tinkering Blogから容赦なく盗み出されました。)やなど、設定できるその他のプロパティについては、 OpenFileDialog クラスのドキュメントを参照してください。TitleInitialDirectory


フォルダ ブラウザ

更新 2015.08.10:

フォルダー チューザーを呼び出すための COM メソッドが既に存在するため、フォルダー チューザーを開いてパスを出力できる PowerShell ワンライナーを作成するのは非常に簡単です。

:: fchooser.bat
:: launches a folder chooser and outputs choice to the console
:: https://stackoverflow.com/a/15885133/1683264

@echo off
setlocal

set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please choose a folder.',0,0).self.path""

for /f "usebackq delims=" %%I in (`powershell %psCommand%`) do set "folder=%%I"

setlocal enabledelayedexpansion
echo You chose !folder!
endlocal

このBrowseForFolder()メソッドでは、4 番目の引数で階層のルートを指定します。有効な値のリストについては、ShellSpecialFolderConstantsを参照してください。

これにより、フォルダ選択ダイアログが表示されます。

ここに画像の説明を入力

You chose C:\Users\me\Desktop選択の結果はコンソールに出力されます。

など、設定できるその他のプロパティについては、 FolderBrowserDialog クラスのドキュメントを参照してくださいRootFolder。私の元の .NET PowerShell および C# ソリューションは、必要に応じてこの回答のリビジョン 4System.Windows.Formsで見つけることができますが、この COM メソッドの方が読みやすく、維持しやすいです。

于 2013-04-08T17:18:49.237 に答える
14

これは XP 以上で動作し、hibrid ファイルは必要ありません。長いコマンド ラインで mshta を実行するだけです。

@echo off
set dialog="about:<input type=file id=FILE><script>FILE.click();new ActiveXObject
set dialog=%dialog%('Scripting.FileSystemObject').GetStandardStream(1).WriteLine(FILE.value);
set dialog=%dialog%close();resizeTo(0,0);</script>"

for /f "tokens=* delims=" %%p in ('mshta.exe %dialog%') do set "file=%%p"
echo selected  file is : "%file%"
pause
于 2016-05-06T19:00:50.820 に答える
11

Windows スクリプト ホスト


ファイルの選択

Windows XP には、VBScriptと JScript がファイル選択プロンプトを起動できる不思議なUserAccounts.CommonDialogWSH オブジェクトがありました。どうやら、それはセキュリティ リスクと見なされ、Vista で削除されました。


フォルダの選択

ただし、WSH Shell.Application オブジェクトのBrowseForFolderメソッドを使用すると、フォルダ選択ダイアログを作成できます。ハイブリッド バッチ + JScript の例を次に示します。.bat拡張子を付けて保存してください。

@if (@a==@b) @end /*

:: fchooser2.bat
:: batch portion

@echo off
setlocal

for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0"') do (
    echo You chose %%I
)

goto :EOF

:: JScript portion */

var shl = new ActiveXObject("Shell.Application");
var folder = shl.BrowseForFolder(0, "Please choose a folder.", 0, 0x00);
WSH.Echo(folder ? folder.self.path : '');

フォルダ選択ダイアログ

このBrowseForFolder()メソッドでは、4 番目の引数で階層のルートを指定します。有効な値のリストについては、ShellSpecialFolderConstantsを参照してください。

于 2013-04-09T16:06:37.100 に答える
7

以下に示すように、ファイル/フォルダーの選択は純粋なバッチで行うことができます。もちろん、手触りや見た目は GUI ほど快適ではありませんが、非常にうまく機能し、GUI バージョンよりも使いやすいと思います。選択方法は CHOICE コマンドに基づいているため、CHOICE コマンドが含まれていない Windows バージョンではダウンロードして、パラメーターを少し変更する必要があります。もちろん、コードは CHOICE の代わりに SET /P を使用するように簡単に変更できますが、この変更により、ナビゲートして選択するためにキーを 1 回押すだけで済む非常に単純で高速な選択方法が不要になります。

@echo off
setlocal

rem Select a file or folder browsing a directory tree
rem Antonio Perez Ayala

rem Usage examples of SelectFileOrFolder subroutine:

call :SelectFileOrFolder file=
echo/
echo Selected file from *.* = "%file%"
pause

call :SelectFileOrFolder file=*.bat
echo/
echo Selected Batch file = "%file%"
pause

call :SelectFileOrFolder folder=/F
echo/
echo Selected folder = "%folder%"
pause

goto :EOF


:SelectFileOrFolder resultVar [ "list of wildcards" | /F ]

setlocal EnableDelayedExpansion

rem Process parameters
set "files=*.*"
if "%~2" neq "" (
   if /I "%~2" equ "/F" (set "files=") else set "files=%~2"
)

rem Set the number of lines per page, max 34
set "pageSize=30"
set "char=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

rem Load current directory contents
set "name[1]=<DIR>  .."
:ProcessThisDir
set "numNames=1"
for /D %%a in (*) do (
   set /A numNames+=1
   set "name[!numNames!]=<DIR>  %%a"
)
for %%a in (%files%) do (
   set /A numNames+=1
   set "name[!numNames!]=       %%a"
)
set /A numPages=(numNames-1)/pageSize+1

rem Show directory contents, one page at a time
set start=1
:ShowPage
set /A page=(start-1)/pageSize+1, end=start+pageSize-1
if %end% gtr %numNames% set end=%numNames%
cls
echo Page %page%/%numPages% of %CD%
echo/
if %start% equ 1 (set base=0) else set "base=1"
set /A lastOpt=pageSize+base, j=base
for /L %%i in (%start%,1,%end%) do (
   for %%j in (!j!) do echo     !char:~%%j,1! -  !name[%%i]!
   set /A j+=1
)
echo/

rem Assemble the get option message
if %start% equ 1 (set "mssg=: ") else (set "mssg= (0=Previous page")
if %end% lss %numNames% (
   if "%mssg%" equ ": " (set "mssg= (") else set "mssg=%mssg%, "
   set "mssg=!mssg!Z=Next page"
)
if "%mssg%" neq ": " set "mssg=%mssg%): "

:GetOption
choice /C "%char%" /N /M "Select desired item%mssg%"
if %errorlevel% equ 1 (
   rem "0": Previous page or Parent directory
   if %start% gtr 1 (
      set /A start-=pageSize
      goto ShowPage
   ) else (
      cd ..
      goto ProcessThisDir
   )
)
if %errorlevel% equ 36 (
   rem "Z": Next page, if any
   if %end% lss %numNames% (
      set /A start+=pageSize
      goto ShowPage
   ) else (
      goto GetOption
   )
)
if %errorlevel% gtr %lastOpt% goto GetOption
set /A option=start+%errorlevel%-1-base
if %option% gtr %numNames% goto GetOption
if defined files (
   if "!name[%option%]:~0,5!" neq "<DIR>" goto endSelect
) else (
   choice /C OS /M "Open or Select '!name[%option%]:~7!' folder"
   if errorlevel 2 goto endSelect
)
cd "!name[%option%]:~7!"
goto ProcessThisDir

:endSelect
rem Return selected file/folder
for %%a in ("!name[%option%]:~7!") do set "result=%%~Fa"
endlocal & set "%~1=%result%
exit /B
于 2015-01-28T03:30:41.033 に答える
5

バッチ + PowerShell + C# ポリグロット ソリューション

これはBatch + PowerShell ハイブリッドと同じソリューションですが、XP と Vista の互換性のために C# のフォールバック機能が再度追加されています。xNightmare67x のリクエストにより、複数のファイル選択が追加されました。

<# : chooser_XP_Vista.bat
:: // launches a File... Open sort of file chooser and outputs choice(s) to the console
:: // https://stackoverflow.com/a/36156326/1683264

@echo off
setlocal enabledelayedexpansion

rem // Does powershell.exe exist within %PATH%?

for %%I in ("powershell.exe") do if "%%~$PATH:I" neq "" (
    set chooser=powershell -noprofile "iex (${%~f0} | out-string)"
) else (

    rem // If not, compose and link C# application to open file browser dialog

    set "chooser=%temp%\chooser.exe"

    >"%temp%\c.cs" (
        echo using System;
        echo using System.Windows.Forms;
        echo class dummy {
        echo    public static void Main^(^) {
        echo        OpenFileDialog f = new OpenFileDialog^(^);
        echo        f.InitialDirectory = Environment.CurrentDirectory;
        echo        f.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
        echo        f.ShowHelp = true;
        echo        f.Multiselect = true;
        echo        f.ShowDialog^(^);
        echo        foreach ^(String filename in f.FileNames^) {
        echo            Console.WriteLine^(filename^);
        echo        }
        echo    }
        echo }
    )
    for /f "delims=" %%I in ('dir /b /s "%windir%\microsoft.net\*csc.exe"') do (
        if not exist "!chooser!" "%%I" /nologo /out:"!chooser!" "%temp%\c.cs" 2>NUL
    )
    del "%temp%\c.cs"
    if not exist "!chooser!" (
        echo Error: Please install .NET 2.0 or newer, or install PowerShell.
        goto :EOF
    )
)

rem // Do something with the chosen file(s)
for /f "delims=" %%I in ('%chooser%') do (
    echo You chose %%~I
)

rem // comment this out to keep chooser.exe in %temp% for faster subsequent runs
del "%temp%\chooser.exe" >NUL 2>NUL

goto :EOF
:: // end Batch portion / begin PowerShell hybrid chimera #>

Add-Type -AssemblyName System.Windows.Forms
$f = new-object Windows.Forms.OpenFileDialog
$f.InitialDirectory = pwd
$f.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
$f.ShowHelp = $true
$f.Multiselect = $true
[void]$f.ShowDialog()
if ($f.Multiselect) { $f.FileNames } else { $f.FileName }

XP または Vista のフォルダー チューザーには、WSH ソリューションまたはnpocmaka の HTA ソリューションのいずれかを使用します。

于 2016-03-22T13:54:40.087 に答える
1

このコードで複数の選択肢が機能することを確認するために、「エコー」も残します

echo off
set cmd=Add-Type -AssemblyName System.Windows.Forms;$f=new-object                 Windows.Forms.OpenFileDialog;$f.InitialDirectory=        [environment]::GetFolderPath('Desktop');$f.Filter='Text Files(*.txt)^|*.txt^|All         Files(*.*)^|*.*';$f.Multiselect=$true;[void]$f.ShowDialog();if($f.Multiselect)        {$f.FileNames}else{$f.FileName}
set pwshcmd=powershell -noprofile -command "&{%cmd%}"
for /f "tokens=* delims=" %%I in ('%pwshcmd%') do call :sum "%%I" ret
echo =========
echo --%ret%--
pause
exit /B
:sum [mud] [ret]
echo "%~1"
set FileName=%FileName% "%~1"
set ret=%FileName%
exit /B
于 2020-05-11T23:49:50.013 に答える
0

私は独自のポータブル ソリューションを作成しました: https://sourceforge.net/p/contools/contools/HEAD/tree/trunk/Utilities/src/_gui/wxFileDialog/

ここから実行可能ファイルをダウンロードできます: https://sourceforge.net/p/contools/contools/HEAD/tree/trunk/Utilities/bin/contools/wxFileDialog.exe

このユーティリティは wxWidgets 3.1.x に依存しているため、実際には他のオペレーティング システム用にビルドできます。

于 2018-10-07T03:25:44.330 に答える