[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[分享]调用另一个批处理的两个问题。

本帖最后由 applba 于 2011-6-6 16:04 编辑

1.三种调用方式对goto ef的处理

a.cmd为调用者,b.cmd为被调用者,在子目录tmpdir中。

第一种 call调用
用法 call tmpdir\b.cmd
这种用法不会开启新的cmd.exe进程实例。
call调用b.cmd时会获取cmd.exe的控制权,在遇到goto :eof 时会交还控制权,这样cmd.exe可以执行a.cmd中的剩余语句。

第二种 start调用
用法 start tmpdir\b.cmd
这种用法会开启新的cmd.exe进程实例,还可以通过/i来继承调用者的环境变量。
b.cmd在新开启的cmd.exe中运行,基本和a.cmd不相干了。

第三种 直接调用
用法 tmpdir\b.cmd
这种用法和一个普通命令的用法一样,也不会开启新的cmd.exe进程实例。
但是有一个致命的缺陷,只要遇到b.cmd中的 goto :eof,就会导致调用者a.cmd退出。
tmpdir\b.cmd 后面的代码得不到执行,估计是a.cmd把b.cmd中的代码当作自己的代码。

所以总结一下,调用另一个批处理,最合适的是使用call方式。
start调用一般用来调用win32 GUI程序。
直接调用也可以用来调用win32GUI程序。

注意,每个文件末尾都有一个隐含的 :eof或goto :eof。



2、嵌套调用的%CD%的问题。
三个文件 a.cmd调用 b.cmd,b.cmd又调用c.cmd,b和c都位于同一个子目录tmpdir。
a.cmd
  1. @echo off
  2. echo 当前工作目录是%cd%
  3. echo.
  4. pause
  5. call tmpdir\b.cmd
  6. pause
复制代码
b.cmd
  1. @echo off
  2. echo 调用b成功
  3. echo 当前目录是%cd%
  4. echo.
  5. pause
  6. call c.cmd
复制代码
c.cmd
  1. @echo off
  2. echo 调用c成功
  3. echo %cd%
  4. echo.
  5. echo 测试完毕
  6. pause
复制代码
运行上面的a.cmd,b.cmd被正确执行,但是确提示找不到c.cmd,而单独运行b.cmd确可以正常调用.cmd。
通过分析发现,调用b.cmd的时候,%cd%还是a.cmd的,a.cmd同目录下自然没有c.cmd。

好吧,一句话:不管嵌套多少层,%cD%都是最初的调用者的。

解决方法有两个:
1.使用绝对路径,比如 call "%~dp0c.cmd"。
2.切换工作目录,比如在b.cmd的开始或者call b.cmd之前插入pushd %~dp0"。
1

评分人数

挺好的,讲得很全面,期待楼主补全整套教程。

不过好像有点笔误,把eof写成oef了...

TOP

本帖最后由 applba 于 2011-6-6 16:12 编辑

其实有一个非常基础的,实在不好意思放出来。

第二节 调用命令和程序 ★
    1、直接调用
    2、START调用
    3、CALL调用
    4、调用CMD.exe

上面两个问题是以前自己写批处理的时候遇到的,就总结了一下。

TOP

但是有一个致命的缺陷,只要遇到b.cmd中的 goto :eof,就会导致调用者a.cmd退出。
applba 发表于 2011-6-6 15:23

其实直接调用批处理不返回算不上什么缺陷
而是cmd和command的一种特性而已
早期的很多批处理大量利用了这种特性
因为它简化了很多程序逻辑上的处理
天的白色影子

TOP

加call是调用,调用其他程式后会返回到原来的指令地址。
不加call是跳转,控制权交给其他程式,再也不回头了。

TOP

好吧,我承认我是感性认识,你们都是理性认识……

TOP

呵呵有感
CALL  是督办任务
satrt  是分配任务
直接调用就是踢皮球
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

返回列表