Croyez-le ou non, mon programme d'installation est si ancien qu'il ne dispose pas d'une option pour détecter la version 64 bits de Windows.
Existe-t-il un appel Windows DLL ou (encore mieux) une variable d'environnement qui donnerait ces informations pour Windows XP et Windows Vista?
ne solution possible
Je vois que Wikipedia indique que la version 64 bits de Windows XP et Windows Vista ont une variable d’environnement unique: %ProgramW6432%
, Donc je suppose que ce serait vide sous Windows 32 bits.
Cette variable pointe vers le répertoire Program Files
, Qui stocke tout le programme installé de Windows et autres. La valeur par défaut sur les systèmes de langue anglaise est C:\Program Files
. Dans les éditions 64 bits de Windows (XP, 2003, Vista), il existe également %ProgramFiles(x86)%
dont la valeur par défaut est C:\Program Files (x86)
et %ProgramW6432%
Qui est définie par défaut sur C:\Program Files
. Le %ProgramFiles%
Lui-même dépend du fait que le processus demandant la variable d'environnement soit lui-même 32 bits ou 64 bits (ceci est dû à la redirection Windows sur Windows 64 bits).
Voir le script de traitement par lots répertorié dans Comment vérifier si l'ordinateur exécute un système d'exploitation 32 bits ou 64 bits. Il inclut également des instructions pour vérifier ceci du registre:
Vous pouvez utiliser l'emplacement de registre suivant pour vérifier si l'ordinateur exécute le système d'exploitation Windows 32 ou 64 bits:
HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
Vous verrez les entrées de registre suivantes dans le volet de droite:
Identifier REG_SZ x86 Family 6 Model 14 Stepping 12
Platform ID REG_DWORD 0x00000020(32)
Les mots "x86" et "0x00000020 (32)" ci-dessus indiquent que la version du système d'exploitation est 32 bits.
Pour rechercher une version 64 bits de Windows dans une boîte de commande, j'utilise le modèle suivant:
test.bat:
@echo off
if defined ProgramFiles(x86) (
@echo yes
@echo Some 64-bit work
) else (
@echo no
@echo Some 32-bit work
)
ProgramFiles(x86)
est une variable d'environnement définie automatiquement par cmd.exe (versions 32 bits et 64 bits) sur les ordinateurs Windows 64 bits uniquement.
Voici du code Delphi pour vérifier si votre programme fonctionne sur un système d'exploitation 64 bits:
function Is64BitOS: Boolean;
{$IFNDEF WIN64}
type
TIsWow64Process = function(Handle:THandle; var IsWow64 : BOOL) : BOOL; stdcall;
var
hKernel32 : Integer;
IsWow64Process : TIsWow64Process;
IsWow64 : BOOL;
{$ENDIF}
begin
{$IFDEF WIN64}
//We're a 64-bit application; obviously we're running on 64-bit Windows.
Result := True;
{$ELSE}
// We can check if the operating system is 64-bit by checking whether
// we are running under Wow64 (we are 32-bit code). We must check if this
// function is implemented before we call it, because some older 32-bit
// versions of kernel32.dll (eg. Windows 2000) don't know about it.
// See "IsWow64Process", http://msdn.Microsoft.com/en-us/library/ms684139.aspx
Result := False;
hKernel32 := LoadLibrary('kernel32.dll');
if hKernel32 = 0 then RaiseLastOSError;
try
@IsWow64Process := GetProcAddress(hkernel32, 'IsWow64Process');
if Assigned(IsWow64Process) then begin
if (IsWow64Process(GetCurrentProcess, IsWow64)) then begin
Result := IsWow64;
end
else RaiseLastOSError;
end;
finally
FreeLibrary(hKernel32);
end;
{$ENDIf}
end;
J'ai testé la solution suggérée dans ma question:
Testé pour la variable d'environnement Windows: ProgramW6432
Si ce n'est pas vide, alors c'est Windows 64 bits.
A partir d'un script batch:
IF PROCESSOR_ARCHITECTURE == x86 AND
PROCESSOR_ARCHITEW6432 NOT DEFINED THEN
// OS is 32bit
ELSE
// OS is 64bit
END IF
Utilisation de Windows API :
if (GetSystemWow64Directory(Directory, MaxDirectory) > 0)
// OS is 64bit
else
// OS is 32bit
Sources:
Si vous pouvez effectuer des appels d'API, essayez d'utiliser GetProcAddress / GetModuleHandle pour vérifier l'existence de IsWow64Process , présent uniquement dans les systèmes d'exploitation Windows 64. versions binaires.
Vous pouvez également essayer la variable d'environnement ProgramFiles (x86) utilisée dans Vista/2008 pour la compatibilité descendante, mais je ne suis pas sûr à 100% de XP-64. ou 2003-64.
Bonne chance!
J'ai utilisé cela dans un script de connexion pour détecter Windows 64 bits
si "% ProgramW6432%" == "% ProgramFiles%" goto is64flag
Je ne sais pas quelle langue vous utilisez, mais . NET a la variable d'environnement PROCESSOR_ARCHITEW6432
si le système d'exploitation est 64 bits.
Si tout ce que vous voulez savoir, c'est si votre application fonctionne en 32 bits ou en 64 bits, vous pouvez vérifier IntPtr.Size
. Il sera 4 si vous utilisez le mode 32 bits et 8 si vous utilisez le mode 64 bits.
Pour un one-liner VBScript/WMI qui récupère le nombre de bits réels (32 ou 64) du système d'exploitation ou du matériel, consultez http://csi-windows.com/toolkit/csi-getosbits
Je veux ajouter ce que j'utilise dans les scripts Shell (mais que je peux facilement utiliser dans n'importe quelle langue) ici. La raison en est que certaines des solutions ici ne fonctionnent pas avec un WoW64, certaines utilisent des choses qui ne sont pas vraiment faites pour ça (vérifier s'il y a un dossier * (x86)) ou ne fonctionnent pas dans les scripts cmd. J’estime que c’est la manière "appropriée" de le faire et que cela devrait être sûr même dans les futures versions de Windows.
@echo off
if /i %processor_architecture%==AMD64 GOTO AMD64
if /i %PROCESSOR_ARCHITEW6432%==AMD64 GOTO AMD64
rem only defined in WoW64 processes
if /i %processor_architecture%==x86 GOTO x86
GOTO ERR
:AMD64
rem do AMD64 stuff
GOTO EXEC
:x86
rem do x86 stuff
GOTO EXEC
:EXEC
rem do Arch independent stuff
GOTO END
:ERR
rem I feel there should always be a proper error-path!
@echo Unsupported architecture!
pause
:END
Beaucoup de réponses mentionnent l'appel de IsWoW64Process()
ou des fonctions associées. Ce n'est pas la manière correcte . Vous devez utiliser GetNativeSystemInfo()
qui a été conçu à cet effet. Voici un exemple:
SYSTEM_INFO info;
GetNativeSystemInfo(&info);
if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
// It's a 64-bit OS
}
Voir également: https://msdn.Microsoft.com/en-us/library/windows/desktop/ms724340%28v=vs.85%29.aspx
Je ne sais pas sur quelle version de Windows il existe, mais sous Windows Vista et version ultérieure, cela fonctionne:
Function Is64Bit As Boolean
Dim x64 As Boolean = System.Environment.Is64BitOperatingSystem
If x64 Then
Return true
Else
Return false
End If
End Function
En C #:
public bool Is64bit() {
return Marshal.SizeOf(typeof(IntPtr)) == 8;
}
Dans VB.NET :
Public Function Is64bit() As Boolean
If Marshal.SizeOf(GetType(IntPtr)) = 8 Then Return True
Return False
End Function
J'utilise ceci:
@echo off
if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
echo 64 BIT
) else (
echo 32 BIT
)
Il fonctionne sous Windows XP, testé sous Windows XP Professional 64 bits et 32 bits).
La meilleure façon de procéder consiste sûrement à vérifier s’il existe deux répertoires de fichiers de programme, "Program Files" et "Program Files (x86)". L’avantage de cette méthode est que vous pouvez le faire lorsque le système est en cours d’exécution, la machine n'a pas pu démarrer et vous souhaitez réinstaller le système d'exploitation
J'ai testé le fichier de commandes suivant sur Windows 7 x64/x86 et Windows XP x86 et c'est bien, mais je n'ai pas encore essayé Windows XP x64, mais cela fonctionnera probablement:
If Defined ProgramW6432 (Do x64 stuff or end if you are aiming for x86) else (Do x86 stuff or end if you are aiming for x64)
Voici une méthode plus simple pour les scripts batch
@echo off
goto %PROCESSOR_ARCHITECTURE%
:AMD64
echo AMD64
goto :EOF
:x86
echo x86
goto :EOF
Je sais que c'est ancien mais voici ce que j'utilise pour détecter Win764
On Error Resume Next
Set objWSHShell = CreateObject("WScript.Shell")
strWinVer = objWSHShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\BuildLabEx")
If len(strWinVer) > 0 Then
arrWinVer = Split(strWinVer,".")
strWinVer = arrWinVer(2)
End If
Select Case strWinVer
Case "x86fre"
strWinVer = "Win7"
Case "AMD64fre"
strWinVer = "Win7 64-bit"
Case Else
objWSHShell.Popup("OS Not Recognized")
WScript.Quit
End Select
Sous Windows Powershell, si l'expression suivante renvoie true, il s'agit d'un système d'exploitation 64 bits:
(([Array](Get-WmiObject -Class Win32_Processor | Select-Object AddressWidth))[0].AddressWidth -eq 64)
Ceci a été pris et modifié depuis: http://depsharee.blogspot.com/2011/06/how-do-detect-operating-system.html (Méthode n ° 3). J'ai testé cela sur Win7 64 bits (dans les sessions PowerShell 32 et 64 bits), et XP 32 bits).
Fait intéressant, si j'utilise
get-wmiobject -class Win32_Environment -filter "Name='PROCESSOR_ARCHITECTURE'"
Je reçois AMD64 en ISE 32 bits et 64 bits (sur Win7 64 bits).
Une autre manière créée par eGerman qui utilise les numéros PE des fichiers exécutables compilés (ne repose pas sur des enregistrements de registre ou des variables d’environnement):
@echo off &setlocal
call :getPETarget "%SystemRoot%\Explorer.exe"
if "%=ExitCode%" EQU "00008664" (
echo x64
) else (
if "%=ExitCode%" EQU "0000014C" (
echo x32
) else (
echo undefined
)
)
goto :eof
:getPETarget FilePath
:: ~~~~~~~~~~~~~~~~~~~~~~
:: Errorlevel
:: 0 Success
:: 1 File Not Found
:: 2 Wrong Magic Number
:: 3 Out Of Scope
:: 4 No PE File
:: ~~~~~~~~~~~~~~~~~~~~~~
:: =ExitCode
:: CPU identifier
setlocal DisableDelayedExpansion
set "File=%~1"
set Cmp="%temp%\%random%.%random%.1KB"
set Dmp="%temp%\%random%.%random%.dmp"
REM write 1024 times 'A' into a temporary file
if exist "%File%" (
>%Cmp% (
for /l %%i in (1 1 32) do <nul set /p "=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
)
setlocal EnableDelayedExpansion
) else (endlocal &cmd /c exit 0 &exit /b 1)
REM generate a HEX dump of the executable file (first 1024 Bytes)
set "X=1"
>!Dmp! (
for /f "skip=1 tokens=1,2 delims=: " %%i in ('fc /b "!File!" !Cmp!^|findstr /vbi "FC:"') do (
set /a "Y=0x%%i"
for /l %%k in (!X! 1 !Y!) do echo 41
set /a "X=Y+2"
echo %%j
)
)
del !Cmp!
REM read certain values out of the HEX dump
set "err="
<!Dmp! (
set /p "A="
set /p "B="
REM magic number has to be "MZ"
if "!A!!B!" neq "4D5A" (set "err=2") else (
REM skip next 58 bytes
for /l %%i in (3 1 60) do set /p "="
REM bytes 61-64 contain the offset to the PE header in little endian order
set /p "C="
set /p "D="
set /p "E="
set /p "F="
REM check if the beginning of the PE header is part of the HEX dump
if 0x!F!!E!!D!!C! lss 1 (set "err=3") else (
if 0x!F!!E!!D!!C! gtr 1018 (set "err=3") else (
REM skip the offset to the PE header
for /l %%i in (65 1 0x!F!!E!!D!!C!) do set /p "="
REM next 4 bytes have to contain the signature of the PE header
set /p "G="
set /p "H="
set /p "I="
set /p "J="
REM next 2 bytes contain the CPU identifier in little endian order
set /p "K="
set /p "L="
)
)
)
)
del !Dmp!
if defined err (endlocal &endlocal &cmd /c exit 0 &exit /b %err%)
REM was the signature ("PE\0\0") of the PE header found
if "%G%%H%%I%%J%"=="50450000" (
REM calculate the decimal value of the CPU identifier
set /a "CPUID=0x%L%%K%"
) else (endlocal &endlocal &cmd /c exit 0 &exit /b 4)
endlocal &endlocal &cmd /c exit %CPUID% &exit /b 0