7

Фон:

На работе у нас довольно много скриптов и маленьких помощников с пакетными файлами (xyz.cmd). Windows 7 только начинает распространяться здесь, и, очевидно, мы сталкиваемся с проблемами, связанными с различными переменными среды 32-битных и 64-битных окон.

В частности, если вы запустите 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 , есть ли это - просто! способ заставить эти пакетные файлы всегда использовать 32-битный cmd.exe на 64-битных версиях Windows и нормально работать на 32-битных версиях Windows?

Очевидно, что я могу добавить "заголовок" к каждому такому пакетному файлу, чтобы изменить переменные среды и вызовы regedit, и / или, очевидно, я мог бы просто сказать пользователям «запускать этот пакетный файл через SysWOW64 cmd.exe», но ни одно из этих решений не кажется очень привлекательный :-)

4 ответа4

11

У меня есть три возможных решения вашей проблемы:

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

PowerShell доступен для всех операционных систем Windows XP и новее. PowerShell разработан Microsoft, чтобы в конечном итоге заменить простой cmd.exe, и предоставляет богатый язык для выполнения практически любой задачи. Большинство пакетных программ фактически работают в PowerShell, и в большинстве случаев могут потребовать минимальной настройки.

4

Вы должны явно запустить нужную версию 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).

1

Я переписываю эту оболочку, чтобы она была более эффективной и универсальной, просто добавьте заголовок и работайте, нечего настраивать.

Это будет обрабатывать эти сценарии не в принятом ответе:

  • Работа в системах без переменной "архитектура процесса" (более старая, чем XP) через Windows 10.
  • Работает на системах 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
)
-3

Файлы .com, созданные на 32-разрядной машине, работают только на 32-разрядных компьютерах. Если вы скомпилируете его как исполняемый файл, а затем переименуете его расширение в .com, то только 32-битные машины смогут его запустить.

Это не очень удобно, если вы постоянно редактируете скрипт, но я думаю, что это лучший метод, поскольку он также скрывает ваш код.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .