четверг, 23 июня 2011 г.

Cmd: Detect 64-bit Windows

Windows 64-bit присутствует на рынке довольно давно, но несмотря на это, не перестаёт удивлять разнообразие методов (не всегда корректных) определения разрядности системы в cmd скриптах.

В качестве примера, рассмотрим популярные ответы на вопрос Detect Windows Server version 32/64-bit in CLI на сайте superuser.com:
  1. systeminfo | find /I "System type"
    
    Недостатки: Во первых, работает медленно. Во вторых, не будет работать если используется локаль отличная от английской. В третьих, необходимо дополнительно проводить разбор вывода.

  2. Arch=x86
    if exist "%ProgramFiles(x86)%" set Arch=x64
    
    Недостаток: Условие отработает некорректно если существует директория с таким именем. Редкий случай, но тем не менее возможный.

  3. reg.exe query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | find "BuildLabEx"
    
    Недостаток: Необходим дополнительный разбор вывода.

  4. wmic OS get OSArchitecture
    
    Недостаток: Необходим дополнительный разбор вывода.

  5. set Arch=x64
    if "%PROCESSOR_ARCHITECTURE%" == "x86" ( 
        if not defined PROCESSOR_ARCHITEW6432 set Arch=x86
    )
    
    Недостатки: пока не обнаружены.
    Продолжительное время успешно использую данный метод. К тому же, при желании можно уточнить актуальную архитектуру: x86, amd64, ia64.
А какой способ используете Вы?

четверг, 16 июня 2011 г.

Cmd: reg.exe undocumented /reg switch

Задача

Из командного файла прочитать значение в реестре. В 64-х разрядной системе, в зависимости от условия читать из 32-х или 64-х битной ветки. Если используется 64-х битная версия cmd.exe, всё относительно просто: в зависимости от условия читать из HKLM\Software или HKLM\Software\Wow6432Node.

В 32-х битной версии командного интерпретатора (Post-Build Event в Visual Studio) этот способ не работает, т.к. запросы reg.exe перенаправляются подсистемой WOW64 в HKLM\Software\Wow6432Node.

Решение

Как подсказывает заголовок, reg.exe имеет недокументированный ключ /reg:. После двоеточия, без пробела, следует указать требуемую разрядность ("32" или "64"). Этот ключ работает в 32-х битной и 64-х битной версии утилиты, поэтому грамотно созданный командный файл будет корректно работать в интерпретаторе любой разрядности.

Пример использования (на всякий случай):
reg.exe query HKLM\Software\Python\PythonCore\2.6\InstallPath /ve /reg:64

Рабочая среда: Windows 7 x64

вторник, 7 июня 2011 г.

WinDbg: !error extension and locale

Проблема

WinDbg имеет весьма полезное расширение !error которое декодирует код ошибки и отображает соответствующее описание.

Но, порой, вместо описания можно увидеть ошибку <unable to get error code text> если отладка происходит в режиме пользователя:
0:000> !error 0xC000000D 1
Error code: (NTSTATUS) 0xc000000d - <unable to get error code text>
Так же, можно увидеть пустую строку или часть сообщения если запущена отладочная сессия ядра:
0: kd> !error 87
Error code: (Win32) 0x87 (135) -                              JOIN     SUBST          ,                          .
Последний вывод, кстати, наталкивает на мысль о том что проблема с локалью.