PDA

Показать полную графическую версию : [решено] Как проверить разрядность операционной системы?


Страниц : 1 2 3 [4] 5 6

greg zakharov
03-02-2021, 15:18
Например, в моей Win 10 x64 переменная "PROCESSOR_ARCHITECTURE" имеет значение "AMD64", а "PROCESSOR_ARCHITEW6432" не определена.Позвольте вам объяснить причину не с точки зрения кофейной гущи, а - кода Windows. Переменная окружения PROCESSOR_ARCHITECTURE - это значение поля wProcessorArchitecture структуры SYSTEM_INFO (https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info). Перейдя по ссылке, вы прочтёте следующее:
The processor architecture of the installed operating system.Таким образом, если 32-битная система работает на базе процессора x64 архитектуры, значение переменной будет x86 (или 0), а потому прочие проверки в общем излишни. SYSTEM_INFO формируется на основе различных системных данных, в частности значение wProcessorArchitecture является значением поля NativeProcessorArchitecture структуры KUSER_SHARED_DATA (смещение 0x26A). Таким образом, однозначно идентифицировать битность системы можно в pwsh так:
[Runtime.InteropServices.Marshal]::ReadInt16([IntPtr]0x7FFE026A)
9 - x64, 0 - x86 и т.д.
Что касается ещё более низкого уровня - лучше смотреть в сторону сегментных регистров.

DJ Mogarych
03-02-2021, 15:26
Ещё есть вот такая команда, но я не знаю, как её в cmd обработать:

wmic os get osarchitecture


В Powershell как-то проще:

if ((gwmi win32_operatingsystem).osarchitecture -match "64") {
"64 бита"
}
else {
"Не 64 бита"
}

greg zakharov
03-02-2021, 15:41
Ещё есть вот такая команда...wmic os get osarchitecture | sed "s/[^0-9*]//g;/[[:digit:]]/!d"Засада в том, что WMI может и не возвращать какого-либо значения в принципе (особенно когда pipe вошёл в состояние interlock), так что В Powershell как-то прощени разу не проще, а - скрещение пальцев (в приведенном вами примере).

Iska
03-02-2021, 17:03
а "PROCESSOR_ARCHITEW6432" не определена. »
Она будет у Вас определена в среде для x86-процессов.

greg zakharov
03-02-2021, 17:33
Iska, только вот кто в здравом уме станет запускать 32-битный командный шелл (из SysWOW64) в 64-битной ОС? Кто бы что ни говорил, а идеологически верным будет спросить у KUSER_SHARED_DATA нужные данные.

alpap
03-02-2021, 18:10
Таким образом, однозначно идентифицировать битность системы можно в pwsh так: »
9 - x64, 0 - x86 и т.д. »
это точно?
потому как pwsh выдает по [Runtime.InteropServices.Marshal]::ReadInt16([IntPtr]0x7FFE026A) именно: 0
а systeminfo это:

Система
Название ОС: Microsoft Windows 7 Professional
Версия ОС: 6.1.7601 Service Pack 1 сборка 7601
Тип ОС: Multiprocessor Free (64-bit)
Папка Windows: C:\Windows
Изготовитель системы: ASUSTeK Computer Inc.
Модель системы: N53Jn
Тип системы: x64-based PC
Системная память: 8368148480 МБ

также оба кода (на cmd и ps) из п59 и код из п60 выдают: x64
вопрос чему верить не задаю, так как windows ставил я сам и склерозом не страдаю поэтому знаю какой разрядности ОС.

greg zakharov
03-02-2021, 18:21
потому как pwsh выдает...Такое поведение характерно для крякнутых систем (в системе что-то хучится). Либо, запустите WinDbg, приаттачтесь, скажем, к вашему любимому текстовому процессору, не забыв предварительно настроить кэширование отладочных символов, а далее извлеките саму структуру по адресу 0x7FFE0000. Найдёте расхождения в смещениях полей или если обнаружите подозрительную активность в системе, дайте знать.

DJ Mogarych
03-02-2021, 19:46
Вспомнился анекдот "в гамаке и стоя".

alpap
03-02-2021, 21:06
запустите WinDbg »
началось
во-первых для 7-ки я вряд ли уже что-то скачаю
во-вторых даже если и был бы не стану лезть в такие дебри
в-третьих (Такое поведение характерно для крякнутых систем) да, ОС не лицензия, хоть и не левая сборка
но почему это все должно влиять на то что при достаточно большом числе запусков одними инструментами я получаю ожидаемый результат, а другим инструментом нет. Пусть я поверю что этот другой инструмент будет гарантированно стабильно работать только на лицензии, но ситуация есть как есть и нужен результат именно на этой системе и соответствующий действительности для данных условий. Другие инструменты позволяют это делать. Подозреваю что и на лицензии отработают точно так же. Тут назревает вопрос, а стоит ли напрягаться, оно надо?

Andrey_Vladimirovich
04-02-2021, 02:34
Благодарю всех за ответы. Всё же остался вопрос по самой переменной %PROCESSOR_ARCHITECTURE%. Правильно ли я понимаю, что она определяет только архитектуру CPU (меня в данном случает интересует только разрядность), а не разрядность ОС? Это конечно, редкость, но и на x64 железо может быть установлена x32 ОС.

Iska
04-02-2021, 05:58
Iska, только вот кто в здравом уме станет запускать 32-битный командный шелл (из SysWOW64) в 64-битной ОС? »
Только здесь штук шесть таких за последний год было. Типичный пример — x86 Total Commander, любители репаков «всё-во-всём».

Правильно ли я понимаю, что она определяет только архитектуру CPU (меня в данном случает интересует только разрядность), а не разрядность ОС? »
Нет. Вот в этом случае:
но и на x64 железо может быть установлена x32 ОС. »
будет только %PROCESSOR_ARCHITECTURE%, и будет она содержать x86.

WOW64 Implementation Details - Win32 apps | Microsoft Docs (https://docs.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details)
Detect 64 vs 32 bit OS or Process - Windows CMD - SS64.com (https://ss64.com/nt/syntax-64bit.html)

Andrey_Vladimirovich
04-02-2021, 07:12
Забавно, зачем же разработчики так назвали переменную %PROCESSOR_ARCHITECTURE%, если её значение зависит от условий, в которых она запущена? Вот об это я изначально и споткнулся.

Iska
05-02-2021, 14:05
Andrey_Vladimirovich, видимо решили, что она должна отражать состояние для окружения именно текущего процесса. А потом оставили, вероятно — чтобы не ломать совместимость. Изначально-то ни о каких x64 процессорах речь не шла — были Intel x86, MIPS, Alpha и PowerPC. И проверка была банальная (причём, я веду речь не только о пакетных файлах):
IF %PROCESSOR_ARCHITECTURE% == x86 (…)
Теперь представьте, что меняется платформа, и под x64 запускается некое унаследованное приложение, в котором используется подобного рода проверка. И тут выбор — либо Вы оставляете для x86-процессов под x64-платформой те же значения переменных окружения и добавляете новую (PROCESSOR_ARCHITEW6432) — и всё унаследованное у Вас гладко и безболезненно продолжает работать, либо Вы кромсаете по живому — и теряете рынок.

Andrey_Vladimirovich
05-02-2021, 15:33
Iska
согласен, что оставили для совместимости. Но изначально было принято не правильное решение. Ведь само название переменной %PROCESSOR_ARCHITECTURE% говорит об архитектуре процессора, либо я не правильно понимаю, что имеется в виду под словом "PROCESSOR" в данном контексте. Поправьте меня, если я не прав. А если прав, то очевидно, что ОС никак не может влиять на процессор. Максимум, что может, так это изменить микропрограмму (если такая имеется) и то, это, например, изменит логику работы процессора, но не его разрядность. И если сходить по ссылке в сообщении 61 написанном greg zakharov, то, как он и указал, написано "The processor architecture of the installed operating system.". Правда, сам он почему-то сделал иной вывод из написанного. Я понимаю, что так сделал разработчик и понимать это нужно так, как это работает, но логики в этом нет. Либо я в упор чего-то не вижу и/или не понимаю.

DJ Mogarych
05-02-2021, 20:06
Andrey_Vladimirovich, видимо, это просто костыль с древних времён, который никто не будет уже менять. Не стоит искать в этом какую-то непогрешимую логику, надо просто принять это как данность.

Iska
05-02-2021, 20:40
Но изначально было принято не правильное решение. »
Andrey_Vladimirovich, ещё раз: изначально всё было правильным. Несоответствие возникло при переходе к x64-процессорам, потому что разработчики сделали правильный вывод — пусть лучше будет несоответствие, но приложения работают, нежели будет соответствие, но приложения перестанут работать.

Вот, например (http://web.mit.edu/Emacs/source/emacs/nt/nmake.defs):

# Determine the architecture we're running on.
# Define ARCH for our purposes;
# Define CPU for use by ntwin32.mak;
# Define CONFIG_H to the appropriate config.h for the system;
#
!ifdef PROCESSOR_ARCHITECTURE
# We're on Windows NT
CPU = $(PROCESSOR_ARCHITECTURE)
CONFIG_H = config.nt
OS_TYPE = windowsnt
! if "$(PROCESSOR_ARCHITECTURE)" == "x86"
ARCH = i386
CPU = i386
! else
! if "$(PROCESSOR_ARCHITECTURE)" == "MIPS"
ARCH = mips
! else
! if "$(PROCESSOR_ARCHITECTURE)" == "ALPHA"
ARCH = alpha
! else
! if "$(PROCESSOR_ARCHITECTURE)" == "PPC"
ARCH = ppc
! else
! error Unknown architecture type "$(PROCESSOR_ARCHITECTURE)"
! endif
! endif
! endif
! endif
!else
# We're on Windows 95
ARCH = i386
CPU = i386
CONFIG_H = config.nt
OS_TYPE = windows95
!endif

Andrey_Vladimirovich
06-02-2021, 03:20
Andrey_Vladimirovich, ещё раз: изначально всё было правильным. »
Нет, просто изначально это не создавало проблем с точки зрения логики (правильнее сказать, таких проблем).

Iska
06-02-2021, 06:38
Andrey_Vladimirovich, нет. Вы никак не поймёте — изначально эта переменная окружения и показывала именно архитектуру процессора. Я же Вам даже образец реального кода тех времён привёл.

Andrey_Vladimirovich
06-02-2021, 07:14
Iska
то, что эта переменная изначально имела отношение к железу, тут у меня вопросов нет. То есть, изначально эта переменная предназначалась исключительно для определения архитектуры CPU (т.е. железа) и вопроса в определении разрядности (как CPU, так и ОС) не стояло, т.к. все были x32. А потом, с появлением x64 решили, что называется "перегрузить" переменную и использовать её, в добавок с другой, в определении разрядности, как ОС, так и запущенного процесса. Так?

Iska
06-02-2021, 08:22
изначально эта переменная предназначалась исключительно для определения архитектуры CPU (т.е. железа) и вопроса в определении разрядности (как CPU, так и ОС) не стояло, т.к. все были x32. »
Так.

А потом, с появлением x64 решили, что называется "перегрузить" переменную и использовать её, в добавок с другой, в определении разрядности, как ОС, так и запущенного процесса. Так? »
Нет. Никто не предназначал её для определения разрядности ОС, ни изначально, ни потом. Значение x86 оставили в этой переменной окружения в случае исполнения x86-процессов под x64 ОС именно для совместимости, чтобы работали унаследованные приложения. А для возможности определения данного факта не для унаследованных, а современных приложений, добавили для этого случая новую переменную окружения — PROCESSOR_ARCHITEW6432.

То, что мы используем эти две переменные окружения для определения разрядности ОС — просто побочный эффект, который работает по вышеизложенной причине (и потому, что на пользовательском уровне не встретишь ни IA, ни ARM).




© OSzone.net 2001-2012