据我所知,它.bat是旧的16位命名约定,.cmd适用于32位Windows,即从NT开始.但我继续在任何地方看到.bat文件,并且它们似乎使用任一后缀完全相同.假设我的代码将永远不需要对新台币任何旧的运行,是否真的重要走哪条路我名字我的批处理文件,还是有一些疑难杂症,通过使用错误的后缀等着我?
Windows批处理编程是否支持异常处理?如果没有,有没有办法有效地模拟批处理文件中的异常处理?
我希望能够在任何CALL级别的批处理脚本中的任何地方"抛出异常",并重复弹出CALL堆栈,直到它找到一个活动的"TRY块",于是"CATCH块"可以处理异常完全继续,或做一些清理并继续弹出CALL堆栈.如果永远不处理异常,则终止批处理并且控制返回到命令行上下文并显示错误消息.
已经有几种方法可以在任何CALL深度上终止批处理,但这些技术都不允许通过异常处理通常在其他语言中提供的任何结构化清理活动.
注意: 这是我已经知道最近才被发现的好答案的情况,我想分享这些信息
我怀疑没有好的解决方案,但也许我忽略了一些事情:
我所追求的是一种方法:
(a) 从 PowerShell 调用批处理文件,其方式可以在 PowerShell 自动变量中稳健地$LASTEXITCODE反映其(隐式或显式)退出代码。
值得注意的是,调用以 , 退出的批处理文件whoami -nosuch || exit /b应该会导致$LASTEXITCODE反映 的whoami退出代码,即1。当您从 PowerShell 调用批处理文件(按名称或路径)时,情况并非如此:退出代码为0(相反,在cmd.exe会话内部设置为%ERRORLEVEL% )1。
另请注意,调用应与 PowerShell 的输出流保持集成,因此我并不是在寻找基于System.Diagnostics.Process.
此外,我不知道或无法控制调用的批处理文件 - 我正在寻找通用的解决方案。
(b) 传递给批处理文件的双引号参数不会以任何方式被更改,并且cmd.exe的行为不会以任何方式被修改;尤其:
^字符不应该(见下文)。/V:ON选项。我知道如何解决(a)的唯一方法是通过调用批处理文件cmd /c call。
不幸的是,这违反了要求 (b),因为在参数中使用call看似总是双倍的^字符。(并且,相反,不使用 …
我是在 Windows 上使用批处理的新手,对 errorlevel 的使用有疑问。
我在谷歌上引用了TechNet(Exit)和许多示例。
他们中的大多数人像这样使用 /b 和 %errorlevel%
if errorlevel 1 exit /b %errorlevel%
Run Code Online (Sandbox Code Playgroud)
我想知道两者之间的区别
if errorlevel 1 exit /b
Run Code Online (Sandbox Code Playgroud)
和
if errorlevel 1 exit /b %errorlevel%
Run Code Online (Sandbox Code Playgroud)
我认为没有区别,因为 %errorlevel% 没有改变。我错了吗?
我想将 PowerShell 脚本包装到一个批处理文件中,最终使其对任何人都可以执行,并且可以在单个分布式文件中执行。我的想法是使用读取文件本身的 CMD 命令开始一个文件,跳过前几行并将其余行通过管道传输到 powershell,然后让批处理文件结束。在 Bash 中,使用简短的可读命令将是一项简单的任务,但是您可以从众多技巧中看出 Windows 已经在这方面遇到了大麻烦。这就是它的样子:
@echo off
(for /f "skip=4 delims=" %%a in ('type %0') do @echo.%%a) |powershell -noprofile -noninteractive -
goto :EOF
---------- BEGIN POWERSHELL ----------
write-host "Hello PowerShell!"
if ($true)
{
write-host "TRUE"
}
write-host "Good bye."
Run Code Online (Sandbox Code Playgroud)
问题是,PowerShell 脚本没有完全执行,它在第一行写完后停止。我可以让它工作更多,这取决于脚本本身,但在这里找不到任何模式。
如果您将第 2 行的结果通过管道传输到文件或cat进程(如果您安装了 unix 工具,Windows 甚至无法单独执行此操作),您可以看到文件的完整 PowerShell 部分,因此不会被剪切关什么的。PowerShell 只是不想在这里执行脚本。
复制文件,删除前 4 行并将其重命名为 *.ps1,然后调用:
powershell -ExecutionPolicy unrestricted -File FILENAME.ps1
Run Code Online (Sandbox Code Playgroud)
它会完全执行。所以它也不是 PowerShell 脚本内容。在这种情况下,是什么让 powershell 过早结束?
请注意:
c:\temp\1.cmd
@echo off
setlocal
cmd /c dir aaa
IF %ERRORLEVEL% NEQ 0 GOTO fail
GOTO end
:fail
echo - Script failed
:end
endlocal
Run Code Online (Sandbox Code Playgroud)
现在,如果我在命令提示符下运行它:
C:\temp> cmd
Microsoft Windows [Version 10.0.16299.967]
(c) 2017 Microsoft Corporation. All rights reserved.
C:\temp>c:\temp\1.cmd
Volume in drive C has no label.
Volume Serial Number is 4A5E-F223
Directory of C:\temp
File Not Found
- Script failed
C:\temp>echo %errorlevel%
1
C:\temp>
Run Code Online (Sandbox Code Playgroud)
现在我从 Powershell 运行它:
C:\temp> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.16299.967
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, …Run Code Online (Sandbox Code Playgroud)