在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
启动的

除了使用运算符
&
无条件地连接两个命令startexit,还可以对两个变体使用如下所示的块

刚刚退出当前批处理:

@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
vs
exit/B
的知识。我想我所寻找的行为最接近于非控制台进程的
start bar&exit/B
,而控制台进程的
bar&exit/B
。无论
bar
是真正的
bar.bat
还是
bar.exe
,后者都具有相同的明显行为(尽管在引擎盖下,我认为两者的操作顺序略有不同,希望