由于PowerShell是当今几乎所有现代Windows安装的原生组件,我宣布C#回退不再是必要的。如果你仍然需要它来兼容Vista或XP,我moved it to a new answer。从这个编辑开始,我将把脚本重写为Batch + 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 }
:: 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
@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
@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
rem preparation command
set pwshcmd=powershell -noprofile -command "&{[System.Reflection.Assembly]::LoadWithPartialName('System.windows.forms') | Out-Null;$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog; $OpenFileDialog.ShowDialog()|out-null; $OpenFileDialog.FileName}"
rem exec commands powershell and get result in FileName variable
for /f "delims=" %%I in ('%pwshcmd%') do set "FileName=%%I"
echo %FileName%
<# : 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 }
<!-- : starting html comment
:: FileSelector.bat
@echo off
for /f "tokens=* delims=" %%p in ('mshta.exe "%~f0"') do (
set "file=%%~fp"
)
echo/
if not "%file%" == "" (
echo selected file is : %file%
)
echo/
exit /b
-->
<Title>== FILE SELECTOR==</Title>
<body>
<script language='javascript'>
function pipeFile() {
var file=document.getElementById('file').value;
var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
close(fso.Write(file));
}
</script>
<input type='file' name='file' size='30'>
</input><hr><button onclick='pipeFile()'>Submit</button>
</body>
1.1- 没有提交rojo提议的表格(见评论):
<!-- : starting html comment
:: FileSelector.bat
@echo off
for /f "tokens=* delims=" %%p in ('mshta.exe "%~f0"') do (
set "file=%%~fp"
)
echo/
if not "%file%" == "" (
echo selected file is : "%file%"
)
echo/
exit /b
-->
<Title>== FILE SELECTOR==</Title>
<body>
<script language='javascript'>
function pipeFile() {
var file=document.getElementById('file').value;
var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
close(fso.Write(file));
}
</script>
<input id='file' type='file' name='file' size='30' onchange='pipeFile()' >
</input>
<hr>
<button onclick='pipeFile()'>Submit</button>
<script>document.getElementById('file').click();</script>
</body>
9条答案
按热度按时间epggiuax1#
文件浏览器
2016年3月20日更新:
由于PowerShell是当今几乎所有现代Windows安装的原生组件,我宣布C#回退不再是必要的。如果你仍然需要它来兼容Vista或XP,我moved it to a new answer。从这个编辑开始,我将把脚本重写为Batch + PowerShell混合体,并加入执行多选的能力。它非常容易阅读,并根据需要进行调整。
这将导致出现一个文件选择器对话框。
选择的结果输出
You chose C:\Users\me\Desktop\tmp.txt
到控制台。如果你想强制选择单个文件,只需将$f.Multiselect
属性改为$false
。(PowerShell命令无情地从Just Tinkering Blog中榨取。)请参阅OpenFileDialog Class文档,了解可以设置的其他属性,例如
Title
和InitialDirectory
。文件夹浏览器
2015年8月10日更新:
由于invoking a folder chooser已经有一个COM方法,因此构建一个可以打开文件夹选择器并输出路径的PowerShell一行程序非常容易。
在
BrowseForFolder()
方法中,第四个参数指定层次结构的根。有关有效值的列表,请参阅ShellSpecialFolderConstants。这将导致出现一个文件夹选择器对话框。
选择结果输出
You chose C:\Users\me\Desktop
到控制台。请参阅FolderBrowserDialog class文档了解您可以设置的其他属性,例如
RootFolder
。如果需要,可以在此答案的revision 4中找到我最初的.NETSystem.Windows.Forms
PowerShell和C#解决方案,但此COM方法更易于阅读和维护。6uxekuva2#
这应该可以从XP向上运行,不需要hibrid文件,它只需要用一个长命令行运行mshta:
cs7cruho3#
Windows脚本宿主
文件选择
Windows XP有一个神秘的
UserAccounts.CommonDialog
WSH对象which allowed VBScript和JScript来启动文件选择提示。显然,这被认为是一个安全风险,并在Vista中删除。文件夹选择
但是,WSHShell.Application对象BrowseForFolder方法仍然允许创建文件夹选择对话框。下面是一个混合批处理+ JScript示例。使用
.bat
扩展名保存它。在
BrowseForFolder()
方法中,第四个参数指定层次结构的根。有关有效值的列表,请参阅ShellSpecialFolderConstants。68de4m5k4#
一个文件/文件夹的选择可以用纯批处理完成,如下所示。当然,感觉和外观不像GUI那么令人愉快,但它工作得很好,在我看来它比GUI版本更容易使用。选择方法是基于CHOICE命令,所以它需要在Windows版本中下载它,不包括它,并稍微修改它的参数。当然,为了使用SET /P而不是CHOICE,可以容易地修改代码,但是这种改变将消除仅需要一次按键来导航和选择的非常简单和快速的选择方法。
yjghlzjz5#
在批处理中直接运行PowerShell命令的其他解决方案
pdkcd3nj6#
批处理+ PowerShell + C#多国语言解决方案
这是与Batch + PowerShell hybrid相同的解决方案,但是为了XP和Vista的兼容性而重新添加了C#后备功能。应xNightmare67x的要求,添加了多文件选择功能。
对于XP或Vista的文件夹选择器,请使用WSH solution或npocmaka's HTA solution。
hpcdzsge7#
还有两条路。
1.使用混合.bat/hta(必须保存为
bat
)脚本。它可以使用vbscript或javascript,但示例是使用javascrtipt。不创建临时文件。选择文件夹不太容易,需要外部javascript库,但选择文件很容易1.1- 没有提交rojo提议的表格(见评论):
2.由于你已经在使用powershell/net,你可以创建自编译的jscript.net混合。它不需要临时cs文件来编译,直接使用内置的jscrript.net编译器。也不需要powershell,代码可读性更强:
mbyulnm08#
我将留下一个“echo”,甚至是为了验证多项选择在此代码中是否有效
nqwrtyyt9#
我已经写了我自己的便携式解决方案:https://github.com/andry81/contools/tree/HEAD/Utilities/src/_gui/wxFileDialog/
您可以从此处下载可执行文件:https://github.com/andry81/contools/tree/HEAD/Utilities/bin/contools/wxFileDialog.exe
该实用程序依赖于wxWidgets 3.1.x,因此您实际上可以为其他操作系统构建它。