是否可以将 Windows cmd 文件(批处理文件)“声明”为 32 位?

是否可以将 Windows cmd 文件(批处理文件)“声明”为 32 位?

背景:

我们在工作中使用批处理文件 ( xyz.cmd) 编写了相当多的脚本和小助手。Windows 7 现在才开始在这里普及,显然,我们遇到了与 32 位和 64 位 Windows 的不同环境变量相关的问题。

具体来说,如果您C:\Windows\system32\cmd.exe在 64 位 Windows 上运行,您将获得:

...
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
...

然而,如果你C:\Windows\SysWOW64\cmd.exe从 64 位 Windows 启动,你将获得:

...
ProgramFiles=C:\Program Files (x86)         <-- NOTE
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
...

碰巧的是,由于这个 cmd.exe 是一个 32 位进程,它还可以“免费”获得所有其他 SysWOW64 重定向 - 任何调用都regedit将转到 32 位注册表等。

如果批处理文件要执行一些与 32 位应用程序相关的任务(例如路径 + 注册表内容),这将非常有用。

问题:

假设我有一类批处理文件,希望它们始终使用 32 位版本运行cmd.exe,有没有一种——简单的!——方法可以强制这些批处理文件在 64 位版本的 Windows 上始终使用 32 位 cmd.exe,并在 32 位版本的 Windows 上正常运行?

明显地我可以向每个这样的批处理文件添加一个“标题”来更改环境变量和注册表调用和/或明显地我可以告诉用户“通过 SysWOW64 cmd.exe 运行此批处理文件”,但这两种解决方案似乎都不太有吸引力:-)

答案1

对于您的问题,我有三种可能的解决方案:

1) 使用包装器批处理文件

在我以前工作过的一家公司,我们运行的所有程序都有一个包装器批处理文件。我们这样做是为了简化与用户的交互,但它的工作原理类似。如果您愿意,您可以为每个批处理文件创建一个包装器(本质上是创建两个批处理文件),或者创建一个包装器,允许您从菜单中选择每个批处理文件(如上所述http://http-server.carleton.ca/~dmcfet/menu.html)。您可以让每个菜单选择标识要运行的批处理文件的路径,然后让包装器选择正确的 cmd.exe 来启动它。

2) 使用批处理文件作为自包装器

对于每个批处理文件,您可以包含一个标头,以确定您使用的是哪种操作系统(32 位或 64 位)。如果您使用的是 64 位操作系统,您会知道默认情况下,您使用 64 位版本的 cmd.exe 启动它。您可以让该文件然后使用相同的批处理文件启动 32 位版本的 cmd.exe,但您也可以向批处理文件传递一个标志,告诉它忽略 64 位检查。然后它将在正确的 32 位 cmd.exe 下运行。

例如:

@ECHO Off

::Check if 64-bit check skip flag exists

IF %1 == /skipcheck (goto run)

::Check if OS is 64-bit

IF %processor_architecture%==AMD64 (<path_to_32-bit_cmd> /c "<path_to_batch_file>\<name_of_my_batch_file>" /skipcheck)
IF %processor_architecture%==AMD64 (goto end)

:run

echo Hello World!

:end

我还没有测试过上述代码,所以我可能在错误的位置使用了一些引号或括号,但这是总体思路。

3)迁移至电源外壳

PowerShell 适用于所有 Windows 操作系统 XP 及更新版本。PowerShell 由 Microsoft 设计,最终将取代简单的 cmd.exe,并提供丰富的语言来执行几乎所有任务。大多数批处理程序实际上都可以在 PowerShell 中运行,最多可能需要进行最少的调整。

答案2

您应该明确运行所需的 cmd.exe 版本并让它执行批处理文件:

在 64 位中执行:C:\Windows\system32\cmd.exe /C path\to\batchfile.cmd
在 32 位中执行:C:\Windows\SysWOW64\cmd.exe /C path\to\batchfile.cmd

/C 参数执行提供的命令并终止.(是的,这是 XP 文档的链接)。

答案3

我正在重写该包装器,使其更加高效和通用,只需转储标题即可,无需进行任何配置。

这将处理未在接受的答案中的这些情况:

  • 通过 Windows 10 在没有“进程架构”变量的系统(比 XP 更旧的版本)上运行。
  • 在 x86 或 x64 系统上运行
  • 操作系统安装在“C:\Windows”以外的驱动器和路径上
  • 获取脚本的名称和路径以自动重新运行。
  • 将所有命令行参数传递给运行的新迭代。

只需将标题转储进去即可。

REM \/ HEADER TO ENSURE 32 Bit CLI \/
@(
    SETLOCAL
    ECHO OFF
    REM check for Only state where we are not in a 32 bit CMD
    ECHO."%PROCESSOR_ARCHITECTURE%_%ProgramFiles%" | FIND /I "AMD64_" | FIND /I /V "86"  >NUL && (
        CALL "%SystemRoot%\SysWOW64\cmd.exe" /c ""%~f0" %*"
        GOTO :EOF
    )
)
REM /\ HEADER TO ENSURE 32 Bit CLI /\

REM YOUR CODE HERE

(
   ENDLOCAL
   EXIT /b
)

相关内容