none
如何在win8应用中判断系统是8还是8.1? RRS feed

  • 问题

  • 目前发现app在windows 8.1中运行有些问题,需要针对系统版本做不同处理,但现在没有发现有获取系统版本号的api,不知有什么其他办法?谢谢!
    2013年7月8日 9:04

答案

  • hi,

    可以用如下方法:

    const string DeviceClassKey = "{A45C254E-DF1C-4EFD-8020-67D146A850E0},10";
            const string DeviceDriverVersionKey = "{A8B865DD-2E3D-4094-AD97-E593A70C75D6},3";
            const string RootContainer = "{00000000-0000-0000-FFFF-FFFFFFFFFFFF}";
            const string RootQuery = "System.Devices.ContainerId:=\"" + RootContainer + "\"";
            const string HalDeviceClass = "4d36e966-e325-11ce-bfc1-08002be10318";
    
            public static async Task<string> GetWindowsVersionAsync()
            {
                var hal = await GetHalDevice(DeviceDriverVersionKey);
                if (hal == null || !hal.Properties.ContainsKey(DeviceDriverVersionKey))
                    return null;
    
                var versionParts = hal.Properties[DeviceDriverVersionKey].ToString().Split('.');
                return string.Join(".", versionParts.Take(2).ToArray());
            }
            
            private static async Task<PnpObject> GetHalDevice(params string[] properties)
            {
                var actualProperties = properties.Concat(new[] { DeviceClassKey });
                var rootDevices = await PnpObject.FindAllAsync(PnpObjectType.Device,
                    actualProperties, RootQuery);
    
                foreach (var rootDevice in rootDevices.Where(d => d.Properties != null && d.Properties.Any()))
                {
                    var lastProperty = rootDevice.Properties.Last();
                    if (lastProperty.Value != null)
                        if (lastProperty.Value.ToString().Equals(HalDeviceClass))
                            return rootDevice;
                }
                return null;
            }

    8返回的值是6.2,8.1返回的是6.3

    http://attackpattern.com/2013/03/device-information-in-windows-8-store-apps/
    2013年7月29日 10:07

全部回复

  • 我是读映射到进程内存里的kernel32.dll文件版本号判断的, 8.0是Minor Version Number 是2, 8.1是3.

    Win8 Developer QQ Group 95331609

    2013年7月9日 2:36
  • 可以通过kernel32.dll EntryPoint为GetVersionEx 来获取版本信息


    认真的活,认真的爱!

    2013年7月9日 3:46
  • hi      chenrensong
    可以共享一下代码吗?谢谢~
    2013年7月10日 6:58
  • hi zailushang

    我也遇到了和你一样的问题

    获取系统信息及调用系统API的代码如下:

    namespace GetSysVersion
    {
        /// <summary>
        /// 可用于自身或导航至 Frame 内部的空白页。
        /// </summary>
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            /// <summary>
            /// 在此页将要在 Frame 中显示时进行调用。
            /// </summary>
            /// <param name="e">描述如何访问此页的事件数据。Parameter
            /// 属性通常用于配置页。</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
    
            }
    
            private async void Button_Click(object sender, RoutedEventArgs e)
            {
                OSVersionInfo osvi = new OSVersionInfo();
                osvi.OSVersionInfoSize = Marshal.SizeOf(osvi);
                //调用API
                LibWrap.GetVersionEx(osvi);
                var s = osvi.BuildNumber; 
            }
        }
    
        //声明原型
        [StructLayout(LayoutKind.Sequential)]
        public class OSVersionInfo
        {
    
            public int OSVersionInfoSize;
            public int MajorVersion;
            public int MinorVersion;
            public int BuildNumber;
            public int PlatformId;
    
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public String CSDVersion;
        }
    
        public class LibWrap
        {
            [DllImport("kernel32")]
    
            public static extern bool GetVersionEx([In, Out] OSVersionInfo osvi);
        }
    
    }

    下面是运行截图:

    但是当我通过Windows App Certification Kit(打开方法http://dev.21tx.com/2012/09/25/10893.html)验证之后得到下面的结果如下:

    错误详细如下:

    =============================================================

    支持的 API 测试
    失败
    支持的 API
    • 发现错误: 支持的 API 测试检测到以下错误:
      • 此应用程序类型不支持 kernel32.dll 中的 API GetVersionEx。GetSysVersion.exe 调用此 API。
    • 未修复时会产生影响: 使用不在用于 Windows 应用商店应用的 Windows SDK 中的 API 与 Windows 应用商店认证要求冲突。
    • 如何修复: 查看错误消息以识别不在用于 Windows 应用商店应用的 Windows SDK 中的 API。请注意,在调试配置中生成的 C++ 应用不会通过此测试,即使它仅使用来自用于 Windows 应用商店应用的 Windows SDK 的 API。 有关详细信息,请参阅下面的链接:
      Windows 应用商店应用中 Windows API 的替代选择。   

    ===================================================

    悲了个催的,居然不让调,还是去找找其他方法吧。

    Metro支持的.Net环境的API限于 http://msdn.microsoft.com/en-us/library/windows/apps/br230232.aspx ,其他如Metro支持的Win32 API,在此页面也有列出http://msdn.microsoft.com/en-us/library/windows/apps/br211369.aspx,所以是否你的这个第三方 lumisoft.dll 是否能够被使用,请咨询第三方这个dll的发布者,如果你确定她并没有专为Metro设计,那么很遗憾告诉你,他不能被Metr应用使用。(原引:http://social.msdn.microsoft.com/Forums/zh-CN/a05916b6-7e8f-4f38-ad10-edb1c03f530d/metro-style-applumisoftdll

    关于获取系统版本号的其他回答

    http://social.msdn.microsoft.com/Forums/zh-CN/7da871c1-6178-47d3-a77d-ec87927e288a/metro-bob-xue-come-here

    希望对你有帮助~

    • 已建议为答案 Andy_Li_ 2013年7月10日 9:41
    2013年7月10日 8:47
  • 更正一下一楼的错误,两者的结果是一样的。我分别在8.1和8上运行得到如下结果:完全一样

    2013年7月10日 9:09
  • 关于调用kernel32.dll EntryPoint为GetVersionEx的API方法我参考的下面这个网址:http://msdn.microsoft.com/zh-cn/express/795sy883(v=vs.90)

    • 已编辑 Andy_Li_ 2013年7月11日 2:58 有贴错了
    2013年7月10日 9:22
  • 您可以为Windows 8/8.1分别编写应用,在Windows 8.1 GA时可为一个应用同时发布针对Windows 8和Windows 8.1的包。
    2013年7月10日 9:57
  • 我没有调用API,直接读内存的,MinorVersion确实是3,已经用于实际统计了,发现目前8.1用户还是有一些的


    Win8 Developer QQ Group 95331609

    2013年7月10日 10:25
  • 跪求你的代码啊。老大,你共享出来吧
    2013年7月11日 6:48
  • 你是群里那个andy么,不是已经给你主要代码了么,剩下PE分析代码网上一大堆,完整代码不便公开,你懂的


    Win8 Developer QQ Group 95331609

    2013年7月12日 7:43
  • 话说8.1的GetVerionEx居然得到的是 6.2.9200,真是....

    Win8 Developer QQ Group 95331609

    2013年7月12日 7:46
  • hi,

    可以用如下方法:

    const string DeviceClassKey = "{A45C254E-DF1C-4EFD-8020-67D146A850E0},10";
            const string DeviceDriverVersionKey = "{A8B865DD-2E3D-4094-AD97-E593A70C75D6},3";
            const string RootContainer = "{00000000-0000-0000-FFFF-FFFFFFFFFFFF}";
            const string RootQuery = "System.Devices.ContainerId:=\"" + RootContainer + "\"";
            const string HalDeviceClass = "4d36e966-e325-11ce-bfc1-08002be10318";
    
            public static async Task<string> GetWindowsVersionAsync()
            {
                var hal = await GetHalDevice(DeviceDriverVersionKey);
                if (hal == null || !hal.Properties.ContainsKey(DeviceDriverVersionKey))
                    return null;
    
                var versionParts = hal.Properties[DeviceDriverVersionKey].ToString().Split('.');
                return string.Join(".", versionParts.Take(2).ToArray());
            }
            
            private static async Task<PnpObject> GetHalDevice(params string[] properties)
            {
                var actualProperties = properties.Concat(new[] { DeviceClassKey });
                var rootDevices = await PnpObject.FindAllAsync(PnpObjectType.Device,
                    actualProperties, RootQuery);
    
                foreach (var rootDevice in rootDevices.Where(d => d.Properties != null && d.Properties.Any()))
                {
                    var lastProperty = rootDevice.Properties.Last();
                    if (lastProperty.Value != null)
                        if (lastProperty.Value.ToString().Equals(HalDeviceClass))
                            return rootDevice;
                }
                return null;
            }

    8返回的值是6.2,8.1返回的是6.3

    http://attackpattern.com/2013/03/device-information-in-windows-8-store-apps/
    2013年7月29日 10:07
  • 你也可以参考这个我写的博客,里面有四种方法获取版本号  http://www.cnblogs.com/lyandy/p/3225372.html
    2013年7月31日 1:51