我刚刚收到一个错误报告,该问题仅在程序“在64位计算机上运行”时才会出现。现在,Delphi不会生成64位代码,所以从理论上说这应该不重要,但显然它确实在这种情况下。我想我有一个解决方法,但它会破坏32位Windows上的东西,所以我需要一些方法来告诉:
有谁知道如何从我的应用程序中获得这些答案?
答案 0 :(得分:20)
Mason,您可以使用IsWow64Process(WOW64是x86模拟器,允许32位基于Windows的应用程序在64位Windows上无缝运行)
Uses Windows;
type
WinIsWow64 = function( Handle: THandle; var Iret: BOOL ): Windows.BOOL; stdcall;
function IAmIn64Bits: Boolean;
var
HandleTo64BitsProcess: WinIsWow64;
Iret : Windows.BOOL;
begin
Result := False;
HandleTo64BitsProcess := GetProcAddress(GetModuleHandle('kernel32.dll'), 'IsWow64Process');
if Assigned(HandleTo64BitsProcess) then
begin
if not HandleTo64BitsProcess(GetCurrentProcess, Iret) then
Raise Exception.Create('Invalid handle');
Result := Iret;
end;
end;
再见。
答案 1 :(得分:8)
我看到你的问题2(你在Win64上运行吗?)已经回答了。请记住,为了使您的代码能够面向未来,您需要考虑在Win64上运行的(假设的)64位Delphi应用程序中,IsWow64Process也将返回FALSE。
关于你的第一个问题 - 你是64位CPU - 你可以检查硬件上各自的CPUID功能标志,如下面的代码所示。
function Is64BitProcessor: boolean;
begin
Result:=false;
if CpuidAvailable = true then Result := Has64BitFeatureFlag;
end;
使用以下两个低级函数:
function CPUIDavailable:boolean;
asm // if EFLAGS bit 21 can be modified then CPUID is available
pushfd //Save Flags
pushfd //Copy flags to EAX
pop eax
mov ecx,eax //Make another copy in ECX
btc eax,21 //Complement bit 21
push eax //Copy EAX to flags
popfd
pushfd //Copy flags back to EAX
pop eax
cmp eax,ecx //Compare "old" flags value with potentially modified "new" value
setne al //Set return value
popfd //Restore flags
end;
function Has64BitFeatureFlag: boolean;
asm
//IF CPUID.80000001h.EDX[bit29]=1 THEN it's a 64bit processor.
//But we first need to check whether there's a function 80000001h.
push ebx //Save EBX as CPUID will modify EBX
push esi //Save ESI as we'll use ESI internally
xor eax,eax //Setting EAX = input param for CPUID to 0
cpuid //Call CPUID.0
//Returns -> EAX = max "standard" EAX input value
mov esi, eax //Saving MaxStdInput Value
mov eax,80000000h //Setting EAX = input param for CPUID to $80000000
cpuid //Call CPUID.80000000h
//Returns -> EAX = max "extended" EAX input value
//If 80000000h call is unsupported (no 64-bit processor),
//cpuid should return the same as in call 0
cmp eax, esi
je @No64BitProcessor //IF EAX{MaxExtInput} = ESI{MaxStdInput} THEN goto No64BitProcessor;
cmp eax, 80000001h
jb @No64BitProcessor //IF EAX{MaxExtInput} < $80000001 THEN goto No64BitProcessor;
mov eax,80000001h //Call $80000001 is supported, setting EAX:=$80000001
cpuid //Call CPUID.80000001h
//Checking "AMD long mode"/"Intel EM64T" feature bit (i.e., 64bit processor)
bt edx, 29 //by checking CPUID.80000001h.EDX[bit29]
setc al //IF Bit29=1 then AL{Result}:=1{true; it's a 64-bit processor}
jmp @Exit //Exit {Note that Delphi may actually recode this as POP ESI; POP EBX; RET}
@No64BitProcessor:
xor eax, eax //Result{AL/EAX}:=0{false; it's a 32-bit processor};
@Exit:
pop esi //Restore ESI
pop ebx //Restore EBX
end;
EDIT1:关于xor eax,eax //Setting EAX = input param for CPUID to 0
cpuid //Call CPUID.0
//Returns -> EAX = max "standard" EAX input value
mov esi, eax //Saving MaxStdInput Value
mov eax,80000000h //Setting EAX = input param for CPUID to $80000000
cpuid //Call CPUID.80000000h
//Returns -> EAX = max "extended" EAX input value
//If 80000000h call is unsupported (no 64-bit processor),
//cpuid should return the same as in call 0
cmp eax, esi
je @No64BitProcessor //IF EAX{MaxExtInput} = ESI{MaxStdInput} THEN goto No64BitProcessor;
cmp eax, 80000001h
jb @No64BitProcessor //IF EAX{MaxExtInput} < $80000001 THEN goto No64BitProcessor;
mov eax,80000001h //Call $80000001 is supported, setting EAX:=$80000001
cpuid //Call CPUID.80000001h
//Checking "AMD long mode"/"Intel EM64T" feature bit (i.e., 64bit processor)
bt edx, 29 //by checking CPUID.80000001h.EDX[bit29]
setc al //IF Bit29=1 then AL{Result}:=1{true; it's a 64-bit processor}
jmp @Exit //Exit {Note that Delphi may actually recode this as POP ESI; POP EBX; RET}
的注释:这当然是假设一个&gt; = 32位x86处理器(80386或更高版本),但Delphi Win32代码无论如何都不会在早期的机器上运行。 CPUID指令是在80486后期处理器中引入的。
答案 2 :(得分:3)
您可以检查是否存在,然后拨打IsWow64Process。链接的MSDN页面显示了所需的代码。
答案 3 :(得分:2)
MSDN页面说:
与不支持此操作系统的操作系统兼容 函数,调用GetProcAddress来检测IsWow64Process是否为 在Kernel32.dll中实现。如果GetProcAddress成功,那么它是安全的 叫这个功能。否则,WOW64不存在。请注意这一点 技术不是检测操作系统是否可靠的方法 是64位版本的Windows,因为当前的Kernel32.dll 32位Windows的版本也包含此功能。
这意味着:这是一个新功能,您必须小心静态链接到它。
答案 4 :(得分:0)
在第一个功能的开头,您需要添加
if SizeOf(Pointer)=8 then
Exit(True); // Current app is 64 bit
答案 5 :(得分:-1)
如果sizeof(IntPtr) == 8
您是64位Windows上的64位应用程序(编辑:仅适用于Delphi Prism)
如果IsWow64Process
成功并返回true ,那么您就是32位应用程序
64位Windows
其他您使用的是32位Windows