File / folder chooser dialog from a Windows batch script

后端 未结 9 591
一生所求
一生所求 2020-11-22 11:58

Typically, asking the user to supply a file name to a batch script is a messy affair, requiring no misspellings, quotes around paths with spaces, and so forth. Unfortunatel

9条回答
  •  长发绾君心
    2020-11-22 12:36

    Batch + PowerShell + C# polyglot solution

    This is the same solution as the Batch + PowerShell hybrid, but with the C# fallback stuff re-added for XP and Vista compatibility. Multiple file selection has been added at xNightmare67x's request.

    <# : 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 }
    

    For a folder chooser for XP or Vista, use either the WSH solution or npocmaka's HTA solution.

提交回复
热议问题