在Windows批处理文件中,是否可以链执行不是另一个批处理文件的内容?
我理解如果您有两个在Windows批处理文件中,是否可以链执行不是另一个批处理文件的内容?,windows,batch-file,cmd,Windows,Batch File,Cmd,我理解如果您有两个.bat或.cmd文件,我们将它们称为foo和bar,以下规则适用: 没有呼叫: :: Welcome to foo.bat @bar.bat @echo We never get to this line because bar.bat is "chain-executed". :: Welcome to foo.bat @call bar.bat @echo This line is executed after bar.bat returns. 使用呼叫: :: We
.bat
或.cmd
文件,我们将它们称为foo
和bar
,以下规则适用:
没有呼叫
:
:: Welcome to foo.bat
@bar.bat
@echo We never get to this line because bar.bat is "chain-executed".
:: Welcome to foo.bat
@call bar.bat
@echo This line is executed after bar.bat returns.
使用呼叫
:
:: Welcome to foo.bat
@bar.bat
@echo We never get to this line because bar.bat is "chain-executed".
:: Welcome to foo.bat
@call bar.bat
@echo This line is executed after bar.bat returns.
我的问题是:是否有一种执行逆向操作的方法,即确保链接非批处理文件可执行文件
换句话说,在最后一个示例中,是否有一种执行虚构的
链
命令功能的方法?必须使用commandstart在单独的进程中运行可执行文件,另外退出当前批处理或整个命令进程
@echo off
echo Welcome to %~nx0
start "Title" bar.exe & exit /B
echo Even though bar is now an .exe, we never get to this line.
此批处理文件在一个单独的进程中启动bar.exe
,如果可执行文件是在这种情况下打开的新控制台窗口的控制台应用程序,则将Title
作为窗口标题
然后在start
finished之后,exit/B
由命令处理器无条件执行,而bar.exe
在单独的进程中运行,导致终止当前批处理文件的处理
如果此批处理文件不是使用commandcall从另一批处理文件调用的,则命令处理器现在完成批处理文件的处理,从而退出命令处理,除了使用cmd.exe
调用批处理文件外,还使用选项/K
在完成批处理后保持命令提示窗口打开,默认情况下并非如此
但是,如果此批处理文件是从另一个批处理文件调用的,则只完成此子批处理文件的处理,并且命令处理器继续处理父批处理文件,而bar.exe
在单独的进程中运行
@echo off
echo Welcome to %~nx0
start "Title" bar.exe & exit
echo Even though bar is now an .exe, we never get to this line.
在此批处理代码中,命令exit没有选项/B
,这导致在单独的过程中start
完成启动bar.exe
后终止命令处理,即使当前批处理文件是从另一个批处理文件调用的call,即使批处理文件处理是用参数/K
的cmd.exe
启动的
除了使用运算符&
无条件地连接两个命令start和exit,还可以对两个变体使用如下所示的块
刚刚退出当前批处理:
@echo off
echo Welcome to %~nx0
(
start "Title" bar.exe
exit /B
)
echo Even though bar is now an .exe, we never get to this line.
退出整个命令过程:
@echo off
echo Welcome to %~nx0
(
start "Title" bar.exe
exit
)
echo Even though bar is now an .exe, we never get to this line.
当然,只有在根据批处理文件中的至少一个条件启动bar.exe
时,才可以通过退出当前批处理或整个命令处理来启动应用程序
注1:也可以使用
goto:EOF
而不是exit/B
来结束当前批处理
注2:
goto:EOF
和exit/B
都会导致如果命令是批处理子例程的一部分,则只退出子例程,即使用call:label
调用标签下面的代码,因为批处理子例程就像嵌入主批处理文件中的子批处理文件一样
更多示例演示调用
和退出/B
的行为:
Test1.bat:
@echo off
echo Running %~nx0
call Test2.bat
echo Finished %~nx0
@echo off
echo Running %~nx0
Test3.bat
echo Finished %~nx0
@echo off
echo Finished %~nx0
@echo off
echo Running %~nx0
Test.exe 4
call Test5.bat
echo Finished %~nx0
@echo off
echo Running %~nx0
Test.exe 5
Test.exe 6 & exit /B
echo Finished %~nx0
Test2.bat:
@echo off
echo Running %~nx0
call Test2.bat
echo Finished %~nx0
@echo off
echo Running %~nx0
Test3.bat
echo Finished %~nx0
@echo off
echo Finished %~nx0
@echo off
echo Running %~nx0
Test.exe 4
call Test5.bat
echo Finished %~nx0
@echo off
echo Running %~nx0
Test.exe 5
Test.exe 6 & exit /B
echo Finished %~nx0
测试3.bat:
@echo off
echo Running %~nx0
call Test2.bat
echo Finished %~nx0
@echo off
echo Running %~nx0
Test3.bat
echo Finished %~nx0
@echo off
echo Finished %~nx0
@echo off
echo Running %~nx0
Test.exe 4
call Test5.bat
echo Finished %~nx0
@echo off
echo Running %~nx0
Test.exe 5
Test.exe 6 & exit /B
echo Finished %~nx0
在命令提示符窗口内运行Test1.bat
,结果是输出:
Running Test1.bat
Running Test2.bat
Finished Test3.bat
Finished Test1.bat
Running Test4.bat
Running Test.exe with argument 4
Running Test5.bat
Running Test.exe with argument 5
Running Test.exe with argument 6
Finished Test4.bat
Running Test1.bat
Running Test2.bat
Finished Test3.bat
因此,行Finished Test2.bat
丢失,因为命令处理器从Test3.bat
直接返回到Test1.bat
接下来,我们将编译以下C代码以控制台应用程序Test.exe
:
#include <stdio.h>
int main (int argc, char* argv[])
{
if(argc > 1)
{
printf("Running %s with argument %s\n",argv[0],argv[1]);
}
else
{
printf("Running %s without an argument\n",argv[0]);
}
return 0;
}
Test5.bat:
@echo off
echo Running %~nx0
call Test2.bat
echo Finished %~nx0
@echo off
echo Running %~nx0
Test3.bat
echo Finished %~nx0
@echo off
echo Finished %~nx0
@echo off
echo Running %~nx0
Test.exe 4
call Test5.bat
echo Finished %~nx0
@echo off
echo Running %~nx0
Test.exe 5
Test.exe 6 & exit /B
echo Finished %~nx0
在命令提示符窗口中运行Test4.bat
,结果是输出:
Running Test1.bat
Running Test2.bat
Finished Test3.bat
Finished Test1.bat
Running Test4.bat
Running Test.exe with argument 4
Running Test5.bat
Running Test.exe with argument 5
Running Test.exe with argument 6
Finished Test4.bat
Running Test1.bat
Running Test2.bat
Finished Test3.bat
因此,行Finished Test5.bat
丢失,因为命令处理器从执行带有参数6
的Test.exe
返回到Test4.bat
但是使用bar&exit/B
时,如果bar
是具有文件扩展名bat
或cmd
的批处理文件,或具有文件扩展名exe
或com
的可执行文件,则这一点非常重要。这可以通过将Test2.bat的代码更改为:
@echo off
echo Running %~nx0
Test3.bat & exit /B
echo Finished %~nx0
在命令提示符窗口内运行Test1.bat
,结果是输出:
Running Test1.bat
Running Test2.bat
Finished Test3.bat
Finished Test1.bat
Running Test4.bat
Running Test.exe with argument 4
Running Test5.bat
Running Test.exe with argument 5
Running Test.exe with argument 6
Finished Test4.bat
Running Test1.bat
Running Test2.bat
Finished Test3.bat
因此,在第二批处理文件中附加了exit/B
,命令处理器将第二批处理文件中的exit解释为第一批处理文件上下文中的exit。只需将bar.exe放在一行,它就会执行。当程序退出时,它将返回批处理文件。@Squashman这样做的缺点是,当从Windows资源管理器双击时,foo.bat
,在等待bar.exe
完成时,它的shell窗口将挂起。然后使用START命令.Hmm。实际上,我的评论毫无意义:当bar
是批处理文件时,也会出现这种行为。我认为是否使用start
的选择与链接的问题是正交的,我想(??)让执行回到foo
中没有坏处,无论是在start bar
之后还是仅仅bar
Nice,这教会了我一些关于exit
vsexit/B
的知识。我想我所寻找的行为最接近于非控制台进程的start bar&exit/B
,而控制台进程的bar&exit/B
。无论bar
是真正的bar.bat
还是bar.exe
,后者都具有相同的明显行为(尽管在引擎盖下,我认为两者的操作顺序略有不同,希望