1 (изменено: Александр_, 2012-01-27 16:52:30)

Тема: AHK: определение разрядности процесса

В скриптах часто приходится узнавать разрядность процесса, т.к. от этого зависят смещения в большинстве структур.
UPD: размер указателя в байтах хранится во встроенной переменной A_PtrSize, поэтому текст между /* и */ не актуален.
/*Самый простой способ: инициализируем участок памяти в 8 байт нулями и пишем туда указатель- теперь в 32-битной системе старшее двойное слово осталось нулевым(т.к. указатель имеет длину 4 байта), а в 64-битной перезаписалось и теперь неравно нулю. Пример:

VarSetCapacity(test, 8, 0)
NumPut(-1, &test, 0, "ptr")
if(!NumGet(&test, 4, "int"))
   msgbox 32-bit process
else
   msgbox 64-bit process

*/
Если нужно определить не только разрядность процесса, но и архитектуру, то можно воспользоваться функциями GetNativeSystemInfo и IsWow64Process:

SystemType := GetSystemType()
if(SystemType = 0x8000)
   msgbox x86
else if(SystemType&0x8000)
{
   SystemType &= 0x7FFF
   if(SystemType=9)
      msgbox x64(32-bit process)
   else if(SystemType=6)
      msgbox AI64(32-bit process)
   else
      msgbox unknown
}
else
{
   if(SystemType=9)
      msgbox x64
   else if(SystemType=6)
      msgbox AI64
   else
      msgbox unknown
}
return

GetSystemType()
{
   VarSetCapacity(SystemInfo, 48, 0)
   VarSetCapacity(Wow64Process, 4, 0)
   DllCall("GetNativeSystemInfo", "ptr", &SystemInfo)
   ProcType := NumGet(&SystemInfo, 0, "uint")
   if(ProcType=0)
      return 0x8000
   else if(ProcType!=0xffff)
   {
      if(DllCall("IsWow64Process", "ptr", -1, "ptr", &Wow64Process))
	  {
		 if(NumGet(&Wow64Process, 0, "int")=0)
		    return ProcType
		 else
		    return ProcType|0x8000
	  }
   }
   return 0
}

2

Re: AHK: определение разрядности процесса

Как-то делал подобный тест, получилось немного по-другому, но работает:

PID := DllCall("GetCurrentProcessId")
hProcess := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION := 0x400, UInt, 0, UInt, PID)

VarSetCapacity(buf, 8)
MsgBox, % DllCall("IsWow64Process", UInt, hProcess, UInt, &buf) ? (NumGet(buf, 0, "Int64") ? 64 : 32) : "Error"
DllCall("CloseHandle", UInt, hProcess)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

3

Re: AHK: определение разрядности процесса

В win7 x64, ahk-l x64 пример выше сообщает "32".
Код из первого поста — x64.

4

Re: AHK: определение разрядности процесса

А да, это для 32-разрядного интерпретатора. ))

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

5

Re: AHK: определение разрядности процесса

teadrinker пишет:
PID := DllCall("GetCurrentProcessId")
hProcess := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION := 0x400, UInt, 0, UInt, PID)

VarSetCapacity(buf, 8)
MsgBox, % DllCall("IsWow64Process", UInt, hProcess, UInt, &buf) ? (NumGet(buf, 0, "Int64") ? 64 : 32) : "Error"
DllCall("CloseHandle", UInt, hProcess)

Похоже куда-то торопился когда писал .
1) Себя открывать не нужно, уже есть хендл с полным доступом, получить который можно функцией GetCurrentProcess(). Во всех существующих версиях Windows(включая win8) можно использовать константу "-1"(я так и делал в первом посте).
2) IsWow64Process принимает два указателя(не uint, а ptr)- хэндл и указатель на BOOL(занимает 4 байта, а не 8).
3) IsWow64Process возвращает единицу(через второй параметр) только если выполняется 32-битный процесс на 64-битной платформе.

6

Re: AHK: определение разрядности процесса

Ага, уже разобрался, спасибо.

Александр_ пишет:

Самый простой способ: инициализируем участок памяти в 8 байт нулями и пишем туда указатель- теперь в 32-битной системе старшее двойное слово осталось нулевым(т.к. указатель имеет длину 4 байта), а в 64-битной перезаписалось и теперь неравно нулю. Пример:

VarSetCapacity(test, 8, 0)
NumPut(-1, &test, 0, "ptr")
if(!NumGet(&test, 4, "int"))
   msgbox 32-bit process
else
   msgbox 64-bit process

Ещё проще:

MsgBox, % A_PtrSize = 4 ? 32 : 64

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

7 (изменено: Александр_, 2012-01-27 16:42:45)

Re: AHK: определение разрядности процесса

teadrinker пишет:

Ещё проще:

MsgBox, % A_PtrSize = 4 ? 32 : 64

Бл#, вот спасибо! Я был уверен, что эта переменная есть, но умудрился её не найти. Ну и ещё проще:

MsgBox % 8*A_PtrSize

8

Re: AHK: определение разрядности процесса

Да, мощно!

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

9

Re: AHK: определение разрядности процесса

И всё же изыскания не напрасны, пример с GetSystemType() позволяет определить x64 систему при использовании 32-битной AHK.

10

Re: AHK: определение разрядности процесса

До кучи:

MsgBox, % "OS`t"(Is64bitOS() ? "x64":"x86")
     . "`nAHK`t"(A_PtrSize=8 ? "x64":"x86")

Is64bitOS()
{
   Return, A_PtrSize=8
   Or (DllCall("IsWow64Process", "Ptr", DllCall("GetCurrentProcess")
                               , "Char*", IsWow64) And IsWow64)
}

11

Re: AHK: определение разрядности процесса

Так понимаю, для написания AHK-скриптов не столь важно знать разрядность системы, достаточно определить разрядность интерпретатора с помощью A_PtrSize. Или я не прав?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

12

Re: AHK: определение разрядности процесса

teadrinker пишет:

Так понимаю, для написания AHK-скриптов не столь важно знать разрядность системы, достаточно определить разрядность интерпретатора с помощью A_PtrSize. Или я не прав?

Прав, смещения в структурах обычно зависят только от размера указателя. Иногда нужно знать размер указателя в другом процессе, если работаем с его структурами(например PEB). Совсем редко нужно знать архитектуру процессора, если работаем с двоичным кодом(дизассемблируем). Разрядность ОСи мне ещё ни разу не приходилось определять, но можно её использовать для определения разрядности системных процессов.

13

Re: AHK: определение разрядности процесса

Ясно, спасибо.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

14

Re: AHK: определение разрядности процесса

А каким образом определить разрядность стороннего процесса по пути запуска или по PID?
Вначале можно узнать значение переменной A_Is64bitOS, и если ОС 64-х битная - то воспользоваться функцией PsGetProcessWow64Process. Только вот как её вызвать - не знаю, фантазия закончилась... Или может есть более простые пути?

15 (изменено: YMP, 2014-06-08 18:39:27)

Re: AHK: определение разрядности процесса

Вот так можно:


MsgBox, % GetBitness("AutoHotkey.exe")
MsgBox, % GetBitness("Explorer.exe")

GetBitness(Process) { ; PID or Name.exe
    Process, Exist, %Process%
    If !(PID := ErrorLevel)
        return 0
    hProcess := DllCall("OpenProcess", "uint", 0x400    ; PROCESS_QUERY_INFORMATION
                                     , "uint", 0, "uint", PID, "ptr")
    If (hProcess = 0)
        return 0
    res := DllCall("IsWow64Process", "ptr", hProcess, "int *", Wow64Process)
    If (res = 0)
        return 0
    DllCall("CloseHandle", "ptr", hProcess)
    return Wow64Process? 32:64
}

16

Re: AHK: определение разрядности процесса

YMP
Спасибо. то, что надо. Скрипт оказался несколько сложнее, чем позволяют мои скиллы, сам бы не додумался до такого )

17

Re: AHK: определение разрядности процесса

YMP пишет:

Вот так можно:

К сожалению, не работает. На XP x32 и Win7 x32 возвращает значение 64.

18

Re: AHK: определение разрядности процесса

А зачем вы на 32-битной системе пытаетесь определить разрядность процесса?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

19

Re: AHK: определение разрядности процесса

teadrinker пишет:

А зачем вы на 32-битной системе пытаетесь определить разрядность процесса?

Упс, точно.
Я ведь сам писал, что "узнать значение переменной A_Is64bitOS, и если ОС 64-х битная..."
Пардон, забыл об этом нюансе.

20 (изменено: seriousstas, 2018-05-21 17:51:37)

Re: AHK: определение разрядности процесса

Снова сравниваю с Autoit (пытаюсь перейти сюда..) ..
там есть такое работающие условие

If @OSArch = "X86" Then
Else
EndIf

Из того , что пробовал выше на 64 разрядном проце и ОС - сообщает 32 (win 8.1 x64),
кроме того , что во втором сообщении (от teadrinker) .
Какой метод будет работающим и оптимальным  ?
Мне достаточно определить разрядность ОС

21

Re: AHK: определение разрядности процесса

A_Is64bitOS.

22

Re: AHK: определение разрядности процесса

Malcev
Спасиб!