【问题标题】:Trying to write a calling batch file but keep getting "cannot find" error尝试编写调用批处理文件但不断收到“找不到”错误
【发布时间】:2014-06-22 17:27:46
【问题描述】:

我正在尝试编写一个批处理文件来调用另一个替换目录中的两个文件的批处理文件。这是我的代码:

set mmcIpath="C:"*"\mmc-stable-win32\MultiMC\instances"

call C:\%mmcIpath%\spc_we_replace_CED+CEDU.bat

每当我设置临时环境变量时,它都会说找不到目录。

--附加信息--

我运行一个名为 MultiMC5 的 Minecraft 启动器;它具有运行命令的功能 - 但由于某种原因只有一个命令。所以我想让它调用一个批处理文件来运行多个命令。

我的主批处理文件位于“C:...\MultiMC\instances”中,但我希望程序能够调用它。它不能,因为它在名为“CED (210 mods-)”的子目录中工作。所以我在子目录中放置了另一批以调用主目录(我想对名为“CEDU (300+ mods-)”的第二个子目录执行相同的操作)。我收到此错误:“系统找不到指定的路径。”。它发生在我设置路径时。

我使用的是 Windows 8.1,并搜索了有关如何使用通配符和如何使用 FOR 循环的提示,但没有一种通配符方法对我有用,而且我根本无法理解 FOR 循环。我还尝试删除和添加引号之类的内容以尝试修复它,但这也不起作用。

我的问题:

set 命令是否与通配符兼容,如果是,我该如何让它工作?

【问题讨论】:

  • set 将变量设置为字符串。 * 是字符串中的有效字符。但是您不能使用带有通配符的路径。为什么要使用通配符?
  • 我想这样做,这样我就可以将目录放在我需要的任何地方,而无需一直更改批处理文件。它似乎更早地适用于具有完全相同代码的批处理文件(尽管由于某种原因我无法检查,因为暂停命令不起作用)。
  • 有一种搜索目录的方法 - 但这可能需要几分钟。这是您的选择吗?你越能知道那个目录在哪里,搜索就越快。 (例如:它总是低于 %USERPROFILE% 吗?)
  • 是的,但在其他计算机上我想从 USB 记忆棒上运行它(尝试在驱动器名称中使用通配符)。我使用批处理文件链的原因是程序在目录中运行命令,但我想将主批处理保留在外面,因为它很大(占用大量内存,因为它必须排除许多文件并做其他事情)。所以我尝试在目录中使用一个较小的批处理文件来调用它,但这似乎不起作用。
  • -对不起,StackExchange 的新手-“它是”,我的意思是它在 %USERPROFILE% 下并且在 Documents 文件夹中(该程序存在于一堆“固定”目录中,否则它不起作用)。

标签: batch-file path cmd wildcard


【解决方案1】:

看起来您的问题是主批处理文件可以在任何驱动器上,并且您想使用相对于主批处理文件位置的路径调用其他批处理文件。对吗?

您可以使用%~d0 获取驱动器,使用%~p0 获取路径,使用%~dp0 获取驱动器+路径。请参阅下面的示例并执行存储在几个不同目录中的这个小批处理文件:

@echo off
echo Batch is stored on drive %~d0
echo in the directory %~p0
echo resulting in path %~dp0

因此,您可以使用由 %0 引用的参数 0,该参数始终包含具有完整路径的批处理文件的名称,使用上面在命令提示符窗口中输入 for /? 显示的命令 FOR 的帮助中解释的语法来调用另一个批处理文件的路径取决于主批处理文件的路径。

【讨论】:

  • 好吧... ...唯一的问题是,我的主批处理文件在父目录中(见上面的评论 - 在上面的帖子下面)...
【解决方案2】:

现在我们这里有一个经典的 XY problem - 被问及解决方案,而不是根本问题。

这是一个可能的解决方案:

@ECHO OFF
SETLOCAL
set mmcIpath="C:"*"\mmc-stable-win32\MultiMC\instances"
set "mmcIpath=U:\\.*\\mmc-stable-win32\\MultiMC\\instances"
SET "targetbat=spc_we_replace.bat"

FOR /f "delims=" %%a IN (
  'dir /b/s /ad "%mmcIpath:~0,3%"^|findstr /e /i /r /c:"%mmcIpath%" '
  ) DO (
 IF EXIST "%%a\%targetbat%" (
  ECHO CALL "%%a\%targetbat%"
  ECHO GOTO nextstep
 )
)

:nextstep

GOTO :EOF

我保留了mmcIpath 的原始设置,并将其替换为适合我系统的表单。

方法是执行dir/s/b/ad 命令(目录,基本格式,仅带有子目录,目录名称)并使用findstr 对其进行过滤。我选择了开关/i(不区分大小写)/e(必须以字符串结尾)/r正则表达式/c:(以下是要匹配的一个字符串)。

正则表达式是按照findstr的规则构造的——\如果要用作字面量需要加倍; .* 表示“任意数量的任意字符”

这应该提供通过过滤器的文字目录名称列表。在找到的目录中查找文件名,call 目标文件(如果找到)。出于测试目的,所需的 CALL 命令仅是 ECHOed。 验证命令正确后,将ECHO CALL更改为CALL以实际执行文件。

如果需要,下面的ECHO GOTO 表明在找到第一个目标文件后可以中断循环。您还没有指明是只运行第一个目标还是运行所有找到的目标。


这是我的测试源。我使用U: 来测试数据。您的系统可能会有所不同。

@ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION
set "mmcIpath=\mmc-stable-win32\MultiMC\instances"
FOR /l %%a IN (1,1,4) DO MD u:\%%a%mmcIpath% 2>nul
FOR /l %%a IN (2,2,4) DO COPY NUL u:\%%a%mmcIpath%\spc_we_replace.bat 2>NUL >nul
ENDLOCAL
ENDLOCAL


@ECHO OFF
SETLOCAL
set mmcIpath="C:"*"\mmc-stable-win32\MultiMC\instances"
set "mmcIpath=U:\\.*\\mmc-stable-win32\\MultiMC\\instances"
SET "targetbat=spc_we_replace.bat"

FOR /f "delims=" %%a IN (
  'dir /b/s /ad "%mmcIpath:~0,3%"^|findstr /e /i /r /c:"%mmcIpath%" '
  ) DO (
 IF EXIST "%%a\%targetbat%" (
  ECHO CALL "%%a\%targetbat%"
  ECHO GOTO nextstep
 )
)

:nextstep

GOTO :EOF

请注意,第一部分只是将u:\1\mmc-stable-win32\MultiMC\instances 建立到u:\4\mmc-stable-win32\MultiMC\instances,然后在u:\2\mmc-stable-win32\MultiMC\instancesu:\4\mmc-stable-win32\MultiMC\instances 中创建一个虚拟文件spc_we_replace.bat

第二部分分配给mmcIath的字符串是根据findstr的语法规则-每个\加倍,.*表示“任意数量的任意字符”。您必须修改该字符串以适合您的系统。请注意,"%mmcIpath:~0,3%" 无偿地从字符串中获取前 3 个字符。就我而言,那将是U:\。 YMMV

【讨论】:

  • -sigh- 我的问题是我想在我的一些目录中自动替换一些 Minecraft mod 文件。我有多个文件要替换,所以我尝试使用一个程序(它是一个名为 MultiMC5 的启动器)来执行此操作。但是,它只能执行一个命令——不能再执行了。所以我希望它调用主批处理,因为我有很多实例,所以我制作了一个对实例文件夹通用的。但后来我发现该程序只能在实例目录中运行,而不是父目录(文件所在的位置)。所以我尝试使用一个简短的批处理文件链,但也没有用。
  • 另外,我测试了你的,但它没有用(得到另一个“找不到指定的路径”错误)。我必须自己调整吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多