在 Windows 批处理文件中,您可以连锁执行*不是*另一个批处理文件的内容吗? [英] In a Windows batch file, can you chain-execute something that is *not* another batch file?

查看:23
本文介绍了在 Windows 批处理文件中,您可以连锁执行*不是*另一个批处理文件的内容吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如果您有两个 .bat.cmd 文件,我们称它们为 foobar,以下规则适用:

没有调用:

:: 欢迎来到 foo.bat@bar.bat@echo 我们永远不会到达这一行,因为 bar.bat 是链执行的".

使用调用:

:: 欢迎来到 foo.bat@call bar.bat@echo 这一行在 bar.bat 返回后执行.

我的问题是:有没有办法执行相反的操作,即确保-batch-file 可执行文件链接的?

:: 欢迎来到 foo.bat@chain bar.exe@echo 即使 bar 现在是 .exe,我们也永远不会到达这一行.@echo 至少,如果链"命令确实存在,情况就会如此.

换句话说,有没有办法执行最后一个例子中虚构的 chain 命令的功能?

解决方案

必须使用命令 start 在单独的进程中运行可执行文件并另外 exit current批处理或整个命令过程.

@echo offecho 欢迎来到 %~nx0启动标题"bar.exe &退出/Becho 即使 bar 现在是一个 .exe,我们也永远不会到达这一行.

这个批处理文件在一个单独的进程中启动 bar.exeTitle 作为窗口标题,如果可执行文件是在这种情况下打开的新控制台窗口的控制台应用程序.

然后在 start 完成后 exit/B 由命令处理器无条件执行,而 bar.exe 在单独的进程中运行导致终止处理当前批处理文件.

如果这个批处理文件不是使用命令 call 从另一个批处理文件调用自身,命令处理器现在完成处理批处理文件,导致退出命令处理,除了批处理文件是用 cmd.exe 带有选项 /K 以在完成批处理后保持命令提示符窗口打开,默认情况下不是这种情况.

但是如果这个批处理文件是用call从另一个批处理文件调用的,那么这个子批处理文件的处理就完成了,命令处理器继续处理父批处理文件,而bar.exe 在单独的进程中运行.

@echo offecho 欢迎来到 %~nx0启动标题"bar.exe &出口echo 即使 bar 现在是一个 .exe,我们也永远不会到达这一行.

在这个批处理代码中,命令exit没有选项/B导致在start完成启动bar后终止命令处理.exe 在一个单独的进程中,即使当前的批处理文件是通过 call 从另一个批处理文件调用的,即使批处理文件处理是用 cmd.exe 启动的带参数/K.

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

仅退出当前批处理:

@echo offecho 欢迎来到 %~nx0(启动标题"栏.exe退出/B)echo 即使 bar 现在是一个 .exe,我们也永远不会到达这一行.

退出整个命令过程:

@echo offecho 欢迎来到 %~nx0(启动标题"栏.exe出口)echo 即使 bar 现在是一个 .exe,我们也永远不会到达这一行.

这种退出当前批处理或整个命令处理的应用程序的启动当然只有在 bar.exe 根据批处理文件中的至少一个条件启动时才有意义.

注1:
也可以使用 goto :EOF 而不是 exit/B 来结束当前的批处理.

注2:goto :EOFexit/B 如果命令是批处理子例程的一部分,则结果都只是退出子例程,即使用 call 调用的标签下方的代码:label 因为批处理子程序就像嵌入在关于批处理的主批处理文件中的子批处理文件.

更多的例子来演示 callexit/B 的行为:

Test1.bat:

@echo off回声正在运行 %~nx0调用Test2.bat回声完成 %~nx0

Test2.bat:

@echo off回声正在运行 %~nx0测试3.bat回声完成 %~nx0

Test3.bat:

@echo off回声完成 %~nx0

在命令提示符窗口中运行 Test1.bat 会产生输出:

运行Test1.bat运行Test2.bat完成Test3.bat完成Test1.bat

所以 Finished Test2.bat 行丢失了,因为命令处理器从 Test3.bat 直接返回到 Test1.bat.

接下来我们编译以下C代码到控制台应用程序Test.exe:

#include int main (int argc, char* argv[]){如果(argc > 1){printf("运行 %s,参数为 %s
",argv[0],argv[1]);}别的{printf("不带参数运行 %s
",argv[0]);}返回0;}

我们在以下两个批处理文件中使用了Test.exe:

Test4.bat:

@echo off回声正在运行 %~nx0测试.exe 4调用Test5.bat回声完成 %~nx0

Test5.bat:

@echo off回声正在运行 %~nx0测试.exe 5Test.exe 6 &退出/B回声完成 %~nx0

在命令提示符窗口中运行 Test4.bat 会产生输出:

运行Test4.bat使用参数 4 运行 Test.exe运行Test5.bat使用参数 5 运行 Test.exe使用参数 6 运行 Test.exe完成Test4.bat

所以 Finished Test5.bat 行丢失了,因为命令处理器从执行 Test.exe 和参数 6 直接返回到 Test4.bat.

但是使用 bar &exit/B 如果 bar 是带有文件扩展名 batcmd 的批处理文件,或者带有文件的可执行文件,那么这很重要扩展名 execom.这可以通过将 Test2.bat 的代码更改为:

来证明

@echo off回声正在运行 %~nx0Test3.bat &退出/B回声完成 %~nx0

在命令提示符窗口中运行 Test1.bat 会产生输出:

运行Test1.bat运行Test2.bat完成Test3.bat

因此,在第二个批处理文件中附加 exit/B 后,命令处理器将第二个批处理文件中的 exit 解释为第一个批处理文件上下文中的退出.

I understand if you have two .bat or .cmd files, let's call them foo and bar, the following rules apply:

Without call:

:: Welcome to foo.bat
@bar.bat
@echo We never get to this line because bar.bat is "chain-executed".

With call:

:: Welcome to foo.bat
@call bar.bat
@echo This line is executed after bar.bat returns.

My question is: is there a way of performing the converse operation, i.e. ensuring that a non-batch-file executable is chained?

:: Welcome to foo.bat
@chain bar.exe
@echo Even though bar is now an .exe,  we never get to this line.
@echo At least, that would be the case if the "chain" command really existed.

In other words, is there a way of performing the function of the fictitious chain command in that last example?

解决方案

It is necessary to use command start to run the executable in a separate process and additionally exit current batch processing or entire command process.

@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.

This batch file starts bar.exe in a separate process with Title as window title in case of executable is a console application for the new console window opened in this case.

Then after start finished exit /B is unconditionally executed by command processor while bar.exe is running in a separate process resulting in terminating processing of current batch file.

If this batch file was not called itself from another batch file using command call, the command processor finishes now processing the batch file resulting in exiting command processing, except the batch file was called with cmd.exe with option /K to keep command prompt window open after finishing batch processing which is not the case by default.

But if this batch file was called with call from another batch file, just processing of this child batch file is finished and command processor continues processing of parent batch file while bar.exe runs in a separate process.

@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.

In this batch code the command exit is without option /B which results in terminating command processing after start finished starting bar.exe in a separate process even if the current batch file was called from another batch file with call and even if batch file processing was started with cmd.exe with parameter /K.

Instead of unconditionally concatenating the two commands start and exit with operator & it is also possible to use a block as shown below for the two variants.

With just exiting current batch processing:

@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.

With exiting entire command process:

@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.

Such a start of an application with exiting either current batch processing or entire command processing makes of course only sense when bar.exe is started depending on at least one condition in the batch file.

Note 1:
It is also possible to use goto :EOF instead of exit /B to end current batch processing.

Note 2: goto :EOF and exit /B result both in just exiting the subroutine if the command is being part of a batch subroutine, i.e. code below a label called with call :label because a batch subroutine is just like a child batch file embedded within a main batch file regarding batch processing.

Some more examples to demonstrate the behavior of call and exit /B:

Test1.bat:

@echo off
echo Running %~nx0
call Test2.bat
echo Finished %~nx0

Test2.bat:

@echo off
echo Running %~nx0
Test3.bat
echo Finished %~nx0

Test3.bat:

@echo off
echo Finished %~nx0

Running Test1.bat from within a command prompt window results in output:

Running Test1.bat
Running Test2.bat
Finished Test3.bat
Finished Test1.bat

So the line Finished Test2.bat is missing because command processor returned from Test3.bat directly to Test1.bat.

Next we compile following C code to console application Test.exe:

#include <stdio.h>

int main (int argc, char* argv[])
{
    if(argc > 1)
    {
        printf("Running %s with argument %s
",argv[0],argv[1]);
    }
    else
    {
        printf("Running %s without an argument
",argv[0]);
    }
    return 0;
}

And we make use of Test.exe in following 2 batch files:

Test4.bat:

@echo off
echo Running %~nx0
Test.exe 4
call Test5.bat
echo Finished %~nx0

Test5.bat:

@echo off
echo Running %~nx0
Test.exe 5
Test.exe 6 & exit /B
echo Finished %~nx0

Running Test4.bat from within a command prompt window results in output:

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

So the line Finished Test5.bat is missing because command processor returned from executing Test.exe with argument 6 directly to Test4.bat.

But with using bar & exit /B it is nevertheless important if bar is a batch file with file extension bat or cmd, or an executable with file extension exe or com. This can be demonstrated by changing code of Test2.bat to:

@echo off
echo Running %~nx0
Test3.bat & exit /B
echo Finished %~nx0

Running Test1.bat from within a command prompt window results in output:

Running Test1.bat
Running Test2.bat
Finished Test3.bat

So with exit /B appended in second batch file, command processor interprets exit in second batch file as exit in context of first batch file.

这篇关于在 Windows 批处理文件中,您可以连锁执行*不是*另一个批处理文件的内容吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆