2010-06-08 7 views
2

Salut j'ai ce petit extrait de code que j'ai écrit qui vérifie si un dossier est présent (n'existe que dans x64) si oui, il fait des commandes "X", sinon (x86) fait des commandes "Z" (x, Z sont juste des marqueurs pour le code) mais ce que je veux savoir, c'est qu'il existe une façon meilleure ou plus fiable de le faire en utilisant seulement le .net Framework 2.0?.NET 2.0 Framework en C# vérifie si l'os 64bit le cas échéant? si ce n'est pas le cas? mieux répondre?

string target = @"C:\Windows\SysWow64"; 
     { 
      if (Directory.Exists(target)) 
      { 
       //do x64 stuff 
      } 
      else 
      { 
       //do x86 stuff 
      } 
+1

duplication possible de [Comment détecter plateforme Windows 64 bits avec .net?] (Http://stackoverflow.com/questions/336633/how-to-detect-windows-64-bit-platform-with-net) – Thorarin

+2

Ne supposez pas que Windows sera toujours installé dans le dossier C: \ Windows \. –

+0

donc je suppose que c'est ok si je fais ceci: if (Directory.Exists (Environment.GetEnvironmentVariable ("SystemRoot") + "\\ SysWow64")) // Dans ce cas, nous traitons OS 64 bits – Koen

Répondre

5

Vous pouvez utiliser réflecteur pour regarder la façon dont il est mis en œuvre FW 4.0:

[DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true, ExactSpelling=true)] 
private static extern IntPtr GetProcAddress(IntPtr hModule, string methodName); 

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 
private static extern IntPtr GetModuleHandle(string moduleName); 

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 
internal static extern IntPtr GetCurrentProcess(); 

[SecurityCritical] 
internal static bool DoesWin32MethodExist(string moduleName, string methodName) 
{ 
    IntPtr moduleHandle = GetModuleHandle(moduleName); 
    if (moduleHandle == IntPtr.Zero) 
    { 
     return false; 
    } 
    return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero); 
} 

[return: MarshalAs(UnmanagedType.Bool)] 
[DllImport("kernel32.dll", SetLastError=true)] 
internal static extern bool IsWow64Process([In] IntPtr hSourceProcessHandle, [MarshalAs(UnmanagedType.Bool)] out bool isWow64); 

[SecuritySafeCritical] 
public static bool get_Is64BitOperatingSystem() 
{ 
    bool flag; 
    return (IntPtr.Size == 8) || 
     ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && 
     IsWow64Process(GetCurrentProcess(), out flag)) && flag); 
} 

Il vérifie si IsWow64Process() fonction existe, et l'appelle.

Mise à jour: ajouté toutes les fonctions utilisées par get_Is64BitOperatingSystem()

Update2: fixes pour le processus 64 bits

+0

'Win32Native' est une classe interne cependant, et' DoesWin32MethodExist' semble être nouveau dans .NET 4.0. – Thorarin

+1

Toute cette API vous indique si votre application 32 bits est en cours d'exécution dans WOW64. Si vous compilez pour que l'application soit AnyCPU, sur un système d'exploitation 64 bits, elle devrait être exécutée en tant qu'application 64 bits et IsWow64() retournera false. – Ants

+0

Merci pour cela. Le réflecteur a chargé mscorlib.dll 32 bits par défaut, donc il n'y a pas de vérification si c'est un processus 64 bits. La version 64 bits de mscorlib renvoie simplement 'true' dans' get_Is64BitOperatingSystem() '. Code corrigé pour ce cas. – max

1

Vous pouvez utiliser la propriété IntPtr.Size. Sa valeur est 4 pour 32 bits et 8 pour 64 bits.

+3

Je pense que cela va revenir la taille correcte en fonction de la version du .Net Framework en cours d'exécution, mais pas du système d'exploitation. IOW, il retournera 4 si vous utilisez un framework 32 bits sur un système d'exploitation 64 bits. –

+1

Il détermine si le processus est 32 ou 64 bits, pas OS. Le système d'exploitation 64 bits peut exécuter les deux. – max

3

Si vous aimez texte,

Console.WriteLine(System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")); 

qui renverra x86 ou AMD64.

+0

comment cela peut-il être transformé en "si x64" faire cela d'autre? – NightsEVil

+1

et qui affiche x86 sur mon ordinateur portable x64. – NightsEVil

+0

Ceci reflète l'architecture du processeur et non l'état d'exécution du domaine de l'application. S'il vous plaît voir la section "Notes" de mon message dans ce fil. [Direct Link] (http://stackoverflow.com/a/10807723/1195927) – JFish222

4

Aucun des éléments suivants n'est un contenu original (je citerai du mieux que je peux), mais je vais vous aider à rassembler des informations sur cette situation.

Si vous utilisez .Net 4 ou supérieur, arrêtez de lire maintenant. Ceci est construit dans le cadre (consultez System.Environment.get_is64bitoperatingsystem)

Pour tout le reste, il y a un certain nombre d'options que j'ai rencontrées en cours de route.

Solution 1: temps de compilation des directives

Blog MSDN de Raymond Chen: http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx

BOOL Is64BitWindows() 
{ 
#if defined(_WIN64) 
return TRUE; // 64-bit programs run only on Win64 
#elif defined(_WIN32) 
// 32-bit programs run on both 32-bit and 64-bit Windows 
// so must sniff 
BOOL f64 = FALSE; 
return IsWow64Process(GetCurrentProcess(), &f64) && f64; 
#else 
return FALSE; // Win64 does not support Win16 
#endif 
} 

Crédits cette solution: les points @Thorarin à un dup. fil où Stefan Schultze liens vers cet article. Je ne suis pas sûr que le fil est une dupe cependant. L'auteur dit spécifiquement qu'il vérifie la plate-forme du système d'exploitation. Je ne suis pas sûr que l'intention est de découvrir si votre application fonctionne en mode 32 bits ou 64 bits.

Solution 2: pointeur Observations Je vais céder la parole à @max pour celui-ci et vient d'ajouter l'article MSDN suivant pour une lecture supplémentaire: http://msdn.microsoft.com/en-us/library/system.intptr.size.aspx Le bit à savoir: la taille du pointeur sur 32 bits = 4, sur 64 bits = 8.

Donnez à l'homme un point!

Solution 3: Utilisation de WinAPI - AKA - Vers l'enfer w /.Net, je vais découvrir ma putain de moi! http://msdn.microsoft.com/en-us/library/ms684139(v=vs.85).aspx

BOOL WINAPI IsWow64Process(
    __in HANDLE hProcess, 
    __out PBOOL Wow64Process 
); 

Notes: Il y a hacks tels que la recherche de "Program Files (x86)", ou regarder vos drapeaux d'architecture de processeur.
Les problèmes avec ces méthodes que

  1. Ils comptent sur les noms de dossiers communs qui ne peuvent pas tenir dans les installations « personnalisées »
  2. drapeau x64 du processeur ne sera pas toujours refléter votre état d'exécution actuel. Êtes-vous sûr d'avoir compilé pour "Any CPU"? Exécution d'un système d'exploitation 32 bits sur un processeur 64 bits?

Idéalement, vous ne devriez pas compter sur des indicateurs externes et chercher plutôt des indices dans le domaine actuel. Nous voulons que toutes les solutions (dans la mesure du possible) soient à l'épreuve des bombes.

2

Vous pouvez déterminer que le système d'exploitation actuel est un système d'exploitation 64 bits ou non. Dans .NET Framework 4, une fonction est disponible. Is64BitOperatingSystem est disponible pour vérifier que le système d'exploitation actuel est un système d'exploitation 64 bits.

if (System.Environment.Is64BitOperatingSystem == true) 
    { 
     Response.Write("This is 64 Bit Operating System."); 
    } 
    else 
    { 
     Response.Write("This is not 64 Bit Operating System."); 
    } 
+0

Avez-vous oublié qu'il s'agit d'une propriété .net 4.0? Question indique "en utilisant seulement le .net Framework 2.0" – Jeremy

+0

Il demande .NET 2.0 Environment.Is64BitOperatingSystem existe seulement dans 4.0 –

0

Dans VB.NET, ce que je voulais fonctionne comme ci-dessous.

Définir le "Win64" sur mesure constante x64 toutes les configurations (debug, version, etc.) comme dans le diagramme ci-dessous et utiliser comme

Si (Win64) Puis

'64 bit code 

autre

' 32 bit code here 

End If

enter image description here