File / folder chooser dialog from a Windows batch script
File Browser
Update 2016.3.20:
Since PowerShell is a native component of pretty much all modern Windows installations nowadays, I'm declaring the C# fallback as no longer necessary. If you still need it for Vista or XP compatibility, I moved it to a new answer. Starting with this edit, I'm rewriting the script as a Batch + PowerShell hybrid and incorporating the ability to perform multi-select. It's profoundly easier to read and to tweak as needed.
<# : chooser.bat:: launches a File... Open sort of file chooser and outputs choice(s) to the console:: https://stackoverflow.com/a/15885133/1683264@echo offsetlocalfor /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 }
This results in a file chooser dialog.
The result of a selection outputs You chose C:\Users\me\Desktop\tmp.txt
to the console. If you want to force single file selection, just change the $f.Multiselect
property to $false
.
(PowerShell command mercilessly leeched from the Just Tinkering Blog.) See the OpenFileDialog Class documentation for other properties you can set, such as Title
and InitialDirectory
.
Folder Browser
Update 2015.08.10:
Since there is already a COM method for invoking a folder chooser, it's pretty easy to build a PowerShell one-liner that can open the folder chooser and output the path.
:: fchooser.bat:: launches a folder chooser and outputs choice to the console:: https://stackoverflow.com/a/15885133/1683264@echo offsetlocalset "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 enabledelayedexpansionecho You chose !folder!endlocal
In the BrowseForFolder()
method, the fourth argument specifies the root of the hierarchy. See ShellSpecialFolderConstants for a list of valid values.
This results in a folder chooser dialog.
The result of a selection outputs You chose C:\Users\me\Desktop
to the console.
See the FolderBrowserDialog class documentation for other properties you can set, such as RootFolder
. My original .NET System.Windows.Forms
PowerShell and C# solutions can be found in revision 4 of this answer if needed, but this COM method is much easier to read and maintain.
This should work from XP upwards and does'nt require an hibrid file, it just runs mshta with a long command line:
@echo offset dialog="about:<input type=file id=FILE><script>FILE.click();new ActiveXObjectset 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
Windows Script Host
File Selection
Windows XP had a mysterious UserAccounts.CommonDialog
WSH object which allowed VBScript and JScript to launch the file selection prompt. Apparently, that was deemed a security risk and removed in Vista.
Folder Selection
However, the WSH Shell.Application object BrowseForFolder method will still allow the creation of a folder selection dialog. Here's a hybrid batch + JScript example. Save it with a .bat
extension.
@if (@a==@b) @end /*:: fchooser2.bat:: batch portion@echo offsetlocalfor /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 : '');
In the BrowseForFolder()
method, the fourth argument specifies the root of the hierarchy. See ShellSpecialFolderConstants for a list of valid values.