• [原译]获取操作系统版本信息


    坊间流传的代码都有些问题,比如不能正常获取win7以上的版本信息,不能获取诸如专业版,旗舰版等的信息,不能正常获取操作系统位的信息。

    使用代码,写了一个简单的库来实现效果。用法大概如下:

    StringBuilder sb = new StringBuilder(String.Empty);
    sb.AppendLine("Operation System Information");
    sb.AppendLine("----------------------------");
    sb.AppendLine(String.Format("Name = {0}", OSVersionInfo.Name));
    sb.AppendLine(String.Format("Edition = {0}", OSVersionInfo.Edition));
    if (OSVersionInfo.ServicePack!=string.Empty)
    sb.AppendLine(String.Format("Service Pack = {0}", OSVersionInfo.ServicePack));
    else
    sb.AppendLine("Service Pack = None");
    sb.AppendLine(String.Format("Version = {0}", OSVersionInfo.VersionString));
    sb.AppendLine(String.Format("ProcessorBits = {0}", OSVersionInfo.ProcessorBits));
    sb.AppendLine(String.Format("OSBits = {0}", OSVersionInfo.OSBits));
    sb.AppendLine(String.Format("ProgramBits = {0}", OSVersionInfo.ProgramBits));
    
    textBox1.Text = sb.ToString();

    对比一下坊间的几种不足:
    总的来说。最大的问题就是不能正确检测你的操作系统到底是32位还是64位。几种方法大致如下:
    1. 使用IntPtr指针的大小
    最关键的一句代码是:

    return IntPtr.Size * 8;


    但是事实上,这个返回的不是操作系统的位数,返回的是运行的程序的位数,如果在64位的windows上以32位的模式运行了这个程序,那么就会返回32.

    2. 使用PROCESSOR_ARCHITECTURE 环境变量

    string pa = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
    return ((String.IsNullOrEmpty(pa) || String.Compare(pa, 0,
    "x86", 0, 3, true) == 0) ? 32 : 64);

    这就是纯粹的误导了,因为和1的情况一样。不能返回处理器的位数而是返回了运行程序的位数,如果在64位的windows上以32位的模式运行了这个程序,那么就会返回32.

    3. 使用PInvoke 和 GetSystemInfo
    注意:为了保持文章不要太长。。我没有包括PInvoke API的声明,(译者注:C#的互操作性嘛),但你可能在我提供的源代码里找到。

    ProcessorArchitecture pbits = ProcessorArchitecture.Unknown;
    try
    {
    SYSTEM_INFO l_System_Info = new SYSTEM_INFO();
    GetSystemInfo(ref l_System_Info);
    switch (l_System_Info.uProcessorInfo.wProcessorArchitecture)
    {
    case 9: // PROCESSOR_ARCHITECTURE_AMD64
    pbits = ProcessorArchitecture.Bit64;
    break;
    case 6: // PROCESSOR_ARCHITECTURE_IA64
    pbits = ProcessorArchitecture.Itanium64;
    break;
    case 0: // PROCESSOR_ARCHITECTURE_INTEL
    pbits = ProcessorArchitecture.Bit32;
    break;
    default: // PROCESSOR_ARCHITECTURE_UNKNOWN
    pbits = ProcessorArchitecture.Unknown;
    break;
    }
    }
    catch
    {
    Ignore 
    }
    return pbits;


    老问题,还是会返回运行程序的位数,而不是操作系统/处理器的位数。
    4. 使用PInvoke和GetNativeSystemInfo
    我看到过有人说上面的都不可信。可以使用GetNativeSystemInfo代替,代码和上面一样,只是把GetSystemInfo换成GetNativeSystemInfo就好。

    结果不一样了。但是。。。这个API返回了处理器本身的位数,而我对操作系统的位数感兴趣。。毕竟64位的处理器上也可以轻松运行32位的操作系统
    5. 组合 IntPtr.Size 和 IsWow64Process

    static public SoftwareArchitecture OSBits
    {
    get
    {
    SoftwareArchitecture osbits = SoftwareArchitecture.Unknown;
    
    switch (IntPtr.Size * 8)
    {
    case 64:
    osbits = SoftwareArchitecture.Bit64;
    break;
    
    case 32:
    if (Is32BitProcessOn64BitProcessor())
    osbits = SoftwareArchitecture.Bit64;
    else
    osbits = SoftwareArchitecture.Bit32;
    break;
    
    default:
    osbits = SoftwareArchitecture.Unknown;
    break;
    }
    
    return osbits;
    }
    }
    
    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;
    }

    如果IntPtr是64.操作系统必然也是64位,因为你不能在32位的操作系统上运行64位的程序
    如果程序在32位模式下运行,代码会检测是否是64位的处理器,而程序在32位模式下运行来判断是32位还是64位。
    如果返回的是64,那么操作系统是64位,但是程序以32位的模式运行,如果是32,那么操作系统也是32.

    最后,我在lib里还加入了一些方法。以便区分程序/操作系统/处理器的位数。
    译自http://www.codeproject.com/Articles/73000/Getting-Operating-System-Version-Info-Even-for-Win,有删减。

  • 相关阅读:
    Delphi 日期函数的单元 DateUtils
    学习官方示例 SysUtils.DecodeDate、DecodeTime
    msp430的常量可以这样定义
    学习官方示例 SysUtils.EncodeDate、EncodeTime、StrToDate、StrToTime、StrToDateTime
    Delphi中Format与FormatDateTime函数详解
    csdn太慢了搬到园子里来
    .net 2.0 真的能与1.1 安全正确地运行在同一台电脑上吗?
    照着这些做,生活自然很开心
    【转】SQL中取当前记录的ID>SCOPE_IDENTITY()
    [转]Windows XP Service Pack 2中弹出窗口拦截器的研究
  • 原文地址:https://www.cnblogs.com/lazycoding/p/2784283.html
Copyright © 2020-2023  润新知