.NET으로 Windows 64 비트 플랫폼을 감지하는 방법?
A의 .NET 2.0 C # 응용 프로그램 I는 운영 체제 플랫폼을 감지하기 위해 다음 코드를 사용 :
string os_platform = System.Environment.OSVersion.Platform.ToString();
"Win32NT"를 반환합니다. 문제는 Windows Vista 64 비트에서 실행될 때 "Win32NT"를 반환한다는 것입니다.
올바른 플랫폼 (32 또는 64 비트)을 알 수있는 다른 방법이 있습니까?
Windows 64 비트에서 32 비트 응용 프로그램으로 실행될 때 64 비트도 감지해야합니다.
64 비트 Windows에서 32 비트 .NET Framework 2.0을 실행하면 IntPtr.Size가 올바른 값을 반환하지 않습니다 (32 비트를 반환 함).
Microsoft의 Raymond Chen이 설명했듯이 먼저 64 비트 프로세스에서 실행 중인지 확인해야합니다 (.NET에서는 IntPtr.Size를 확인하여 수행 할 수 있다고 생각합니다) .32 비트 프로세스에서 실행중인 경우 여전히 Win API 함수 IsWow64Process를 호출해야합니다. 이것이 true를 반환하면 64 비트 Windows에서 32 비트 프로세스로 실행중인 것입니다.
Microsoft의 Raymond Chen : 64 비트 Windows에서 실행 중인지 프로그래밍 방식으로 감지하는 방법
내 해결책 :
static bool is64BitProcess = (IntPtr.Size == 8);
static bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64();
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWow64Process(
[In] IntPtr hProcess,
[Out] out bool wow64Process
);
public static bool InternalCheckIsWow64()
{
if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) ||
Environment.OSVersion.Version.Major >= 6)
{
using (Process p = Process.GetCurrentProcess())
{
bool retVal;
if (!IsWow64Process(p.Handle, out retVal))
{
return false;
}
return retVal;
}
}
else
{
return false;
}
}
.NET 4에는 Environment 클래스에 Is64BitProcess 및 Is64BitOperatingSystem 의 두 가지 새로운 속성이 있습니다. 흥미롭게도, Reflector를 사용하면 32 비트 및 64 비트 버전의 mscorlib에서 다르게 구현되는 것을 볼 수 있습니다. 32 비트 버전은 Is64BitProcess에 대해 false를 반환하고 Is64BitOperatingSystem에 대한 P / Invoke를 통해 IsWow64Process를 호출합니다. 64 비트 버전은 둘 다 true를 반환합니다.
.NET Framework 4.0을 사용하는 경우 쉽습니다.
Environment.Is64BitOperatingSystem
Environment.Is64BitOperatingSystem 속성 (MSDN)을 참조하십시오 .
이것은 Bruno Lopez가 위에서 제안한 것의 구현 일 뿐이지 만 Win2k + 모든 WinXP 서비스 팩에서 작동합니다. 다른 사람들이 직접 롤링하지 않도록 게시 할 것이라고 생각했습니다. (댓글로 게시했을 것이지만 나는 새로운 사용자입니다!)
[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr LoadLibrary(string libraryName);
[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
public extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);
private delegate bool IsWow64ProcessDelegate([In] IntPtr handle, [Out] out bool isWow64Process);
public static bool IsOS64Bit()
{
if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
{
return true;
}
else
{
return false;
}
}
private static IsWow64ProcessDelegate GetIsWow64ProcessDelegate()
{
IntPtr handle = LoadLibrary("kernel32");
if ( handle != IntPtr.Zero)
{
IntPtr fnPtr = GetProcAddress(handle, "IsWow64Process");
if (fnPtr != IntPtr.Zero)
{
return (IsWow64ProcessDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)fnPtr, typeof(IsWow64ProcessDelegate));
}
}
return null;
}
private static bool Is32BitProcessOn64BitProcessor()
{
IsWow64ProcessDelegate fnDelegate = GetIsWow64ProcessDelegate();
if (fnDelegate == null)
{
return false;
}
bool isWow64;
bool retVal = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, out isWow64);
if (retVal == false)
{
return false;
}
return isWow64;
}
전체 답변은 다음과 같습니다 (stefan-mg, ripper234 및 BobbyShaftoe의 답변 모두에서 가져옴).
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);
private bool Is64Bit()
{
if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
{
return true;
}
else
{
return false;
}
}
private bool Is32BitProcessOn64BitProcessor()
{
bool retVal;
IsWow64Process(Process.GetCurrentProcess().Handle, out retVal);
return retVal;
}
먼저 64 비트 프로세스인지 확인하십시오. 그렇지 않은 경우 32 비트 프로세스가 Wow64Process인지 확인하십시오.
Microsoft는 이에 대한 코드 샘플을 넣었습니다.
http://1code.codeplex.com/SourceControl/changeset/view/39074#842775
다음과 같이 보입니다 :
/// <summary>
/// The function determines whether the current operating system is a
/// 64-bit operating system.
/// </summary>
/// <returns>
/// The function returns true if the operating system is 64-bit;
/// otherwise, it returns false.
/// </returns>
public static bool Is64BitOperatingSystem()
{
if (IntPtr.Size == 8) // 64-bit programs run only on Win64
{
return true;
}
else // 32-bit programs run on both 32-bit and 64-bit Windows
{
// Detect whether the current process is a 32-bit process
// running on a 64-bit system.
bool flag;
return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") &&
IsWow64Process(GetCurrentProcess(), out flag)) && flag);
}
}
/// <summary>
/// The function determins whether a method exists in the export
/// table of a certain module.
/// </summary>
/// <param name="moduleName">The name of the module</param>
/// <param name="methodName">The name of the method</param>
/// <returns>
/// The function returns true if the method specified by methodName
/// exists in the export table of the module specified by moduleName.
/// </returns>
static bool DoesWin32MethodExist(string moduleName, string methodName)
{
IntPtr moduleHandle = GetModuleHandle(moduleName);
if (moduleHandle == IntPtr.Zero)
{
return false;
}
return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
}
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern IntPtr GetModuleHandle(string moduleName);
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule,
[MarshalAs(UnmanagedType.LPStr)]string procName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);
원격 시스템 테스트를 위해 WMI 버전도 제공됩니다.
PROCESSOR_ARCHITECTURE
환경 변수를 확인할 수도 있습니다 .
존재하지 않거나 32 비트 Windows에서 "x86"으로 설정되어 있습니다.
private int GetOSArchitecture()
{
string pa =
Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
return ((String.IsNullOrEmpty(pa) ||
String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
}
Chriz Yuen 블로그에서
C # .Net 4.0 2 개의 새로운 환경 속성 인 Environment.Is64BitOperatingSystem을 도입했습니다. Environment.Is64BitProcess;
이 두 속성을 모두 사용할 때는주의하십시오. Windows 7 64 비트 시스템에서 테스트
//Workspace: Target Platform x86
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess False
//Workspace: Target Platform x64
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess True
//Workspace: Target Platform Any
Environment.Is64BitOperatingSystem True
Environment.Is64BitProcess True
이 시도:
Environment.Is64BitOperatingSystem
Environment.Is64BitProcess
가장 빠른 방법 :
if(IntPtr.Size == 8) {
// 64 bit machine
} else if(IntPtr.Size == 4) {
// 32 bit machine
}
참고 : 이것은 매우 직접적입니다.
@ foobar : 당신이 맞아요, 너무 쉽습니다;)
99 %의 경우 시스템 관리자가 약한 개발자는 누구나 Windows를 열거 할 수 있도록 Microsoft가 항상 제공 한 힘을 깨닫지 못합니다.
시스템 관리자는 이러한 점에서 항상 더 좋고 간단한 코드를 작성합니다.
그럼에도 불구하고, 이 환경 변수가 올바른 시스템에서 올바른 값을 리턴하려면 빌드 구성이 AnyCPU 여야합니다 .
System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
32 비트 Windows에서는 "X86", 64 비트 Windows에서는 "AMD64"를 반환합니다.
다음 두 가지 환경 변수 (의사 코드)를 사용하십시오.
if (PROCESSOR_ARCHITECTURE = x86 &&
isDefined(PROCESSOR_ARCHITEW6432) &&
PROCESSOR_ARCHITEW6432 = AMD64) {
//64 bit OS
}
else
if (PROCESSOR_ARCHITECTURE = AMD64) {
//64 bit OS
}
else
if (PROCESSOR_ARCHITECTURE = x86) {
//32 bit OS
}
블로그 게시물 HOWTO : Detect Process Bitness를 참조하십시오 .
dotPeek를 사용 하면 프레임 워크가 실제로 어떻게 작동하는지 확인할 수 있습니다. 그것을 염두에두고, 내가 생각해 낸 것은 다음과 같습니다.
public static class EnvironmentHelper
{
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll")]
static extern IntPtr GetModuleHandle(string moduleName);
[DllImport("kernel32")]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll")]
static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);
public static bool Is64BitOperatingSystem()
{
// Check if this process is natively an x64 process. If it is, it will only run on x64 environments, thus, the environment must be x64.
if (IntPtr.Size == 8)
return true;
// Check if this process is an x86 process running on an x64 environment.
IntPtr moduleHandle = GetModuleHandle("kernel32");
if (moduleHandle != IntPtr.Zero)
{
IntPtr processAddress = GetProcAddress(moduleHandle, "IsWow64Process");
if (processAddress != IntPtr.Zero)
{
bool result;
if (IsWow64Process(GetCurrentProcess(), out result) && result)
return true;
}
}
// The environment must be an x86 environment.
return false;
}
}
사용법 예 :
EnvironmentHelper.Is64BitOperatingSystem();
나는 이것을해야하지만 관리자가 원격으로 할 수 있어야합니다. 어쨌든 이것은 나에게 아주 잘 작동하는 것 같습니다.
public static bool is64bit(String host)
{
using (var reg = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, host))
using (var key = reg.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\"))
{
return key.GetValue("ProgramFilesDir (x86)") !=null;
}
}
이것은 http://1code.codeplex.com/SourceControl/changeset/view/39074#842775 의 Microsoft 코드를 기반으로하는 솔루션입니다 . 쉬운 코드 재사용을 위해 확장 방법을 사용합니다.
가능한 사용법은 다음과 같습니다.
bool bIs64BitOS = System.Environment.OSVersion.IsWin64BitOS();
bool bIs64BitProc = System.Diagnostics.Process.GetCurrentProcess().Is64BitProc();
//Hosts the extension methods
public static class OSHelperTools
{
/// <summary>
/// The function determines whether the current operating system is a
/// 64-bit operating system.
/// </summary>
/// <returns>
/// The function returns true if the operating system is 64-bit;
/// otherwise, it returns false.
/// </returns>
public static bool IsWin64BitOS(this OperatingSystem os)
{
if (IntPtr.Size == 8)
// 64-bit programs run only on Win64
return true;
else// 32-bit programs run on both 32-bit and 64-bit Windows
{ // Detect whether the current process is a 32-bit process
// running on a 64-bit system.
return Process.GetCurrentProcess().Is64BitProc();
}
}
/// <summary>
/// Checks if the process is 64 bit
/// </summary>
/// <param name="os"></param>
/// <returns>
/// The function returns true if the process is 64-bit;
/// otherwise, it returns false.
/// </returns>
public static bool Is64BitProc(this System.Diagnostics.Process p)
{
// 32-bit programs run on both 32-bit and 64-bit Windows
// Detect whether the current process is a 32-bit process
// running on a 64-bit system.
bool result;
return ((DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && IsWow64Process(p.Handle, out result)) && result);
}
/// <summary>
/// The function determins whether a method exists in the export
/// table of a certain module.
/// </summary>
/// <param name="moduleName">The name of the module</param>
/// <param name="methodName">The name of the method</param>
/// <returns>
/// The function returns true if the method specified by methodName
/// exists in the export table of the module specified by moduleName.
/// </returns>
static bool DoesWin32MethodExist(string moduleName, string methodName)
{
IntPtr moduleHandle = GetModuleHandle(moduleName);
if (moduleHandle == IntPtr.Zero)
return false;
return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
}
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern IntPtr GetModuleHandle(string moduleName);
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string procName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);
}
많은 운영 체제에서이 검사를 성공적으로 사용했습니다.
private bool Is64BitSystem
{
get
{
return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%windir%\SysWOW64"));
}
}
이 폴더의 이름은 운영 체제 언어에 관계없이 항상 "SysWOW64"입니다. 이것은 .NET Framework 1.1 이상에서 작동합니다.
이 페이지 에서 DllImport를 사용하는 C #의 직접적인 접근 방식은 다음과 같습니다 .
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool lpSystemInfo);
public static bool Is64Bit()
{
bool retVal;
IsWow64Process(Process.GetCurrentProcess().Handle, out retVal);
return retVal;
}
다음 코드를 사용하고 있습니다. 참고 : AnyCPU 프로젝트 용으로 제작되었습니다.
public static bool Is32bitProcess(Process proc) {
if (!IsThis64bitProcess()) return true; // We're in 32-bit mode, so all are 32-bit.
foreach (ProcessModule module in proc.Modules) {
try {
string fname = Path.GetFileName(module.FileName).ToLowerInvariant();
if (fname.Contains("wow64")) {
return true;
}
} catch {
// What on earth is going on here?
}
}
return false;
}
public static bool Is64bitProcess(Process proc) {
return !Is32bitProcess(proc);
}
public static bool IsThis64bitProcess() {
return (IntPtr.Size == 8);
}
이것이 시스템의 플랫폼과 프로세스를 확인하는 가장 좋은 방법이라는 것을 알았습니다.
bool 64BitSystem = Environment.Is64BitOperatingSystem;
bool 64BitProcess = Environment.Is64BitProcess;
첫 번째 속성은 64 비트 시스템의 경우 true를, 32 비트의 경우 false를 반환합니다. 두 번째 속성은 64 비트 프로세스의 경우 true를, 32 비트의 경우 false를 반환합니다.
이 두 가지 특성은 64 비트 시스템에서 32 비트 프로세스를 실행할 수 있으므로 시스템과 프로세스를 모두 확인해야하기 때문에 필요합니다.
괜찮아요, 그러나 이것은 또한 작동합니다 env
:
PROCESSOR_ARCHITECTURE=x86
..
PROCESSOR_ARCHITECTURE=AMD64
어쩌면 ;-)
여기의 Windows 관리 계측 (WMI) 접근 방법 :
string _osVersion = "";
string _osServicePack = "";
string _osArchitecture = "";
ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_OperatingSystem");
ManagementObjectCollection collection = searcher.Get();
foreach (ManagementObject mbo in collection)
{
_osVersion = mbo.GetPropertyValue("Caption").ToString();
_osServicePack = string.Format("{0}.{1}", mbo.GetPropertyValue("ServicePackMajorVersion").ToString(), mbo.GetPropertyValue("ServicePackMinorVersion").ToString());
try
{
_osArchitecture = mbo.GetPropertyValue("OSArchitecture").ToString();
}
catch
{
// OSArchitecture only supported on Windows 7/Windows Server 2008
}
}
Console.WriteLine("osVersion : " + _osVersion);
Console.WriteLine("osServicePack : " + _osServicePack);
Console.WriteLine("osArchitecture: " + _osArchitecture);
/////////////////////////////////////////
// Test on Windows 7 64-bit
//
// osVersion : Microsoft Windows 7 Professional
// osservicePack : 1.0
// osArchitecture: 64-bit
/////////////////////////////////////////
// Test on Windows Server 2008 64-bit
// --The extra r's come from the registered trademark
//
// osVersion : Microsoftr Windows Serverr 2008 Standard
// osServicePack : 1.0
// osArchitecture: 64-bit
/////////////////////////////////////////
// Test on Windows Server 2003 32-bit
// --OSArchitecture property not supported on W2K3
//
// osVersion : Microsoft(R) Windows(R) Server 2003, Standard Edition
// osServicePack : 2.0
// osArchitecture:
OSInfo. 비트
using System;
namespace CSharp411
{
class Program
{
static void Main( string[] args )
{
Console.WriteLine( "Operation System Information" );
Console.WriteLine( "----------------------------" );
Console.WriteLine( "Name = {0}", OSInfo.Name );
Console.WriteLine( "Edition = {0}", OSInfo.Edition );
Console.WriteLine( "Service Pack = {0}", OSInfo.ServicePack );
Console.WriteLine( "Version = {0}", OSInfo.VersionString );
Console.WriteLine( "Bits = {0}", OSInfo.Bits );
Console.ReadLine();
}
}
}
다음 코드를 프로젝트의 클래스에 포함하십시오.
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool wow64Process);
public static int GetBit()
{
int MethodResult = "";
try
{
int Architecture = 32;
if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6)
{
using (Process p = Process.GetCurrentProcess())
{
bool Is64Bit;
if (IsWow64Process(p.Handle, out Is64Bit))
{
if (Is64Bit)
{
Architecture = 64;
}
}
}
}
MethodResult = Architecture;
}
catch //(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
다음과 같이 사용하십시오.
string Architecture = "This is a " + GetBit() + "bit machine";
설치된 Windows 아키텍처를 얻으려면 이것을 사용하십시오.
string getOSArchitecture()
{
string architectureStr;
if (Directory.Exists(Environment.GetFolderPath(
Environment.SpecialFolder.ProgramFilesX86))) {
architectureStr ="64-bit";
}
else {
architectureStr = "32-bit";
}
return architectureStr;
}
수락 된 답변이 매우 복잡하다는 것을 감안할 때. 더 간단한 방법이 있습니다. 광산은 alexandrudicu의 anaswer의 변형입니다. 64 비트 창이 프로그램 파일 (x86)에 32 비트 응용 프로그램을 설치하면 환경 변수를 사용하여 해당 폴더가 존재하는지 확인할 수 있습니다 (다른 지역화를 보완하기 위해).
예 :
private bool Is64BitSystem
{
get
{
return Directory.Exists(Environment.ExpandEnvironmentVariables(@"%PROGRAMFILES(X86)%"));
}
}
이것은 나를 위해 더 빠르고 간단합니다. OS 버전에 따라 해당 폴더 아래의 특정 경로에 액세스하고 싶습니다.
즐겨 ;-)
Function Is64Bit() As Boolean
Return My.Computer.FileSystem.SpecialDirectories.ProgramFiles.Contains("Program Files (x86)")
End Function
"C : \ Program Files (x86)"가 있는지 확인하십시오. 그렇지 않은 경우 32 비트 OS에있는 것입니다. 그렇다면 OS는 64 비트입니다 (Windows Vista 또는 Windows 7). 충분히 간단 해 보입니다 ...
나는 사용한다:
Dim drivelet As String = Application.StartupPath.ToString
If Directory.Exists(drivelet(0) & ":\Program Files (x86)") Then
MsgBox("64bit")
Else
MsgBox("32bit")
End if
컴퓨터의 여러 위치에 응용 프로그램을 설치 한 경우 응용 프로그램이 시작되는 경로를 가져옵니다. 또한 C:\
컴퓨터의 99.9 %가에 Windows가 설치되어 있으므로 일반적인 경로 를 사용할 수 있습니다 C:\
.
다음 버전을 사용합니다.
public static bool Is64BitSystem()
{
if (Directory.Exists(Environment.GetEnvironmentVariable("Program Files (x86)"))) return true;
else return false;
}
참고 URL : https://stackoverflow.com/questions/336633/how-to-detect-windows-64-bit-platform-with-net
'Programing' 카테고리의 다른 글
Maven이 사용중인 settings.xml 파일을 판별하기위한 Maven 명령 (0) | 2020.04.03 |
---|---|
파이썬에서 산술 평균 (한 유형의 평균) 계산 (0) | 2020.04.03 |
Vim에서 줄 바꿈 삭제 (0) | 2020.04.03 |
PowerShell에서 Windows 탐색기 창을 열 수 있습니까? (0) | 2020.04.03 |
드롭 다운 목록에서 기본 화살표 아이콘을 제거하는 방법 (선택 요소)? (0) | 2020.04.03 |