Чтобы программно определить, запущены ли вы на 64-разрядной Windows, вы можете использовать функцию
IsWow64Process
, которая показывает, не запущен ли ваш 32-разрядный процесс в режиме эмуляции.Но как вы программно определите, не запущен ли ваш 64-битный процесс на 64-битной Windows? Легко.
function Is64BitProcessRunningOn64BitWindows: Boolean; begin Result := True; end;Тот факт, что ваша 64-разрядная программа работает, и означает, что вы запущены на 64-разрядной Windows! Если бы вы были на 32-разрядной машине, ваш код не смог бы запуститься.
Это всё равно, что спрашивать: "включен ли компьютер?". Если бы он был выключен, ваша программа не смогла бы задать вопрос.
Конечно же, если вам нужен единый исходный текст для компиляции и в 32-разрядную программу и в 64-разрядную, то вам нужно сделать немного больше работы:
function Is64BitWindows: Boolean; var IsWow64Process: function(hProcess: THandle; out Wow64Process: Bool): Bool; stdcall; Wow64Process: Bool; begin {$IF Defined(CPU64)} Result := True; // 64-битная программа запускается только на Win64 {$ELSEIF Defined(CPU16)} Result := False; // Win64 не поддерживает 16-разрядные приложения {$ELSE} // 32-битные программы могут работать и на 32-разрядной и на 64-разрядной Windows // так что этот вопрос требует дальнейшего исследования IsWow64Process := GetProcAddress(GetModuleHandle(Kernel32), 'IsWow64Process'); Wow64Process := False; if Assigned(IsWow64Process) then Wow64Process := IsWow64Process(GetCurrentProcess, Wow64Process) and Wow64Process; Result := Wow64Process; {$IFEND} end;Я добавил ветку для 16-битных программ на случай, если вы достаточно сумасшедший, чтобы писать их сегодня.
Примечание переводчика: поскольку в Delphi пока нет 64-разрядного компилятора, то не известно, как будут называться соответствующие директивы. Поэтому я взял директивы от FreePascal.
Огромное спасибо переводчику за труды по переводу статей! Куждый новый перевод жду с нетерпеньем )
ОтветитьУдалитьМаразм полный, для определения системы и процессора есть соответсвующие функции WinAPI
ОтветитьУдалитьSYSTEM_INFO si;
GetSystemInfo(&si);
GetNativeSystemInfo(&si);
Этого вполне достаточно для индентификации всего и вся. Читайте MSDN, а не занимайтесь шаманством с бубнами.
Потрясающий комментарий. Это вы Реймонду Чену говорите MSDN читать, да? :D
ОтветитьУдалитьGetNativeSystemInfo - не очень удачное решение, потому что вы не можете предвидеть будущие архитектуры, в то время как IsWow64Process будет работать и сейчас и для любых потенциальных будущих платформ.
Об использовании IsWow64Process для определения разрядности системы, кстати, сказано в самом описании GetNativeSystemInfo.
Опечатка у вас, должно быть так
ОтветитьУдалить...
IsWow64Process := GetProcAddress(GetModuleHandle(Kernel32), 'IsWow64Process');
...
Спасибо, исправил.
ОтветитьУдалитьP.S. Сайт в подписи можно просто не указывать. Кстати, можно просто выделить ошибочный фрагмент и нажать Ctrl + Enter.
Вышла Delphi XE2 с 64-bit компилятором, директива для x64 следующая {$IFDEF CPUX64}, 32 {$IFDEF CPUX86} для 32-бит кода.
ОтветитьУдалитьВ описании функции IsWow64Process на MSDN указано, что минимальная винда это XP Serice Pack 2. То есть даже на простой XP без сервиспаков она работать не будет.
ОтветитьУдалитьНехорошо.
Microsoft потихоньку удаляет информацию о старых ОС из MSDN. Поэтому, что касается совместимости со старыми системами - надо смотреть в старой документации.
ОтветитьУдалитьДалее, 64-битные ОС до Windows Vista стоят крайне особо:
- 64-битный Windows 2000 был только под Itanium, это не x86, там нет запуска 32-битных приложений.
- 64-битный Windows XP - это переименованный Windows Server 2003: используется то же ядро и тот же исходный код. Первый выпуск 64-битной XP основан на SP1 для Win2003.
- Был ещё вариант 64-битного XP для Itanium - это первая редакция Windows с поддержкой WOW64, откуда он перекочевал в 2003 Server и x86-64 XP.
P.S. Именно поэтому у 64-битной XP не было SP1, за RTM шёл SP2.
ОтветитьУдалитьИными словами, IsWow64Process есть в любой версии Windows, которая поддерживает запуск 32-битных программ через WOW64 - включая Windows XP Professional x64 Edition RTM (он же - SP1). Это я проверил.
ОтветитьУдалитьРазумеется, функцию надо в любом случае импортировать динамически, поскольку в 32-битных системах её нет.
Что за муки?
ОтветитьУдалитьЕсть миллион способов узнать версию системы и if Pos('64',...)>0 then...
Для 32 процессов из wow64 получаю Tag сервиса. Делаю так:
ОтветитьУдалить[code]
NtReadVirtualMemory(hp, Pointer(LongWord(TBI.TebBaseAddress)+3936), @Buffer,
sizeof(Buffer), ReturnLength);
[/code]
Магическое смещение нашел на просторах интернета.
В 64 битном приложении всегда дает 0.
Как в 64 добыть тег, который указывает на сервис, которому принадлежит поток?