在WinRT Metro应用程序中获取操作系统版本的方法(C#)

27

我正在使用C#和Visual Studio 11 Beta编写Metro风格的应用程序。 现在我想获取操作系统的版本。 我该如何获取?

我已经找到了在“普通”应用程序中执行此操作的方法。 您可以使用具有OSVersion属性的Environment-Class,但在.NET Core中没有此属性。


1
我将其发送到 WebService,然后在那里按操作系统版本对请求进行排序。 - SwissPrime
我在API文档中没有看到任何明显的东西,所以也许你可以先在你的Metro应用程序版本中硬编码它? - Tomas McGuinness
5
有意地没有提供获取操作系统版本的方式。历史上,应用程序曾经滥用操作系统版本,而不是依赖各种形式的功能检测,这导致了开发团队遇到了重大的应用兼容性问题。对于Windows 8,开发团队决定完全避免这个问题,因此没有提供GetVersion API。 - Larry Osterman
@LarryOsterman - 你能展示一下如何在C#/XAML应用程序中进行特性检测的例子吗?我们需要使用反射吗? - Robert Levy
目前,在C#/Xaml中没有针对特性检测的语言投影支持,这是因为只有一个版本(因此所有特性都可用)。WinRT平台支持版本控制和特性检测,但语言投影尚未实现它(因为无法测试其实现)。我甚至不能推测特性检测将如何实施,因为我不参与这些特性的设计。 - Larry Osterman
Winrt平台版本控制的工作方式如下:每个winrt类型都有它被引入的版本。除了运行时类和枚举,winrt类型是不可变的。运行时类和枚举可以进行增量版本控制,新条目指示了它们被引入的版本。语言投影可以使用这些信息来确定哪些API和值在哪个操作系统版本上可用。如何实现取决于语言投影。Martyn在这里的演讲:http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/The-Windows-Runtime提供了更多关于版本控制的信息。 - Larry Osterman
4个回答

11

您可以使用设备API获取低级系统组件的驱动程序版本号,以获得操作系统版本号,并有一定风险不正确。

接受的答案是正确的,因为您不应该将功能绑定到版本号,但使用它有合法的原因,例如分析 - 知道很多用户已经使用新版本很有用,并且您应该考虑更新应用程序以利用它。

https://github.com/AttackPattern/CSharpAnalytics/blob/master/Source/CSharpAnalytics/SystemInfo/WindowsStoreSystemInfo.cs提供更多信息和示例代码(声明,我编写了该代码)

注意:该代码已更新,现在处理自定义/多个HAL等。


此外,这个人正在询问操作系统版本信息,而你却链接到了有关CPU架构的答案。 - DamienG
同时在Windows 8.1上进行了验证 - 正确返回6.3作为操作系统版本号。(Windows 8的内核版本为6.2) - DamienG
使用HAL方法的一个棘手问题是某些机器实际上会报告多个HAL驱动程序,例如Surface RT将报告不少于四个!其中两个具有与Windows相同的版本号,但是另外两个(均来自NVidia)的版本号始于9。 - Ian Griffiths
@DamienG,感谢您提供的代码示例 - 它非常好用!我唯一的问题是 - x86怎么办?在GetSystemUserAgentAsync()中,您似乎只跟踪x64或AMD架构,我不确定我是否能够从ProcessorArchitecture枚举中选择适当的成员来处理x86。有什么建议吗? - Sevenate
在该示例中使用GetProcessorArchitecture直接检测CPU。GetSystemUserAgent不会为x86格式化,因为浏览器也不会 - 在用户代理术语中,缺少x64或ARM等于x86。 - DamienG
显示剩余6条评论

5

对于新的应用程序,您应该检查特定功能,而不是操作系统版本。

据我所知,没有理由检查操作系统版本,因为 Metro 应用程序仅适用于 Windows 8。

编辑:现在 Store 应用程序可用于多个 Windows 版本,但仍建议测试功能而不是操作系统版本。创建项目时,最低操作系统版本设置为构建目标。

编辑#2:如果您有兴趣跟踪应用程序安装基数中的操作系统版本,则可以从针对 Windows 8.1 的应用程序开始将 Application Insights 集成到您的项目中。以下是有关如何入门的说明:

http://azure.microsoft.com/en-us/documentation/articles/app-insights-windows-get-started/


3
我想这是为了未来考虑。Metro风格的应用程序很可能也能在Windows 9上运行。 - svick
2
@RobertLevy,正如OP在评论中所说,将操作系统版本发送到一个Web服务。 - svick
21
你怎么就这么确定没有理由去检查操作系统版本呢?如果出于统计目的,获取应用程序正在运行的确切操作系统版本是相关的(它可能不会永远固定在6.2.9200.0上,难道你不这么认为吗?)。我很抱歉,但这不是一个实际的答案,这只是一种回避它的居高临下的方式。 - Gabriel S.
5
了解用户正在运行的操作系统版本对于提供支持非常有用。如果您在应用程序中提供了向支持部门发送电子邮件的功能,将操作系统版本详细信息嵌入该电子邮件中是很有用的。 - Ian Griffiths
@GabrielS。我特地登录了账号只是为了给你点赞。“你不应该这么做”的回答并不算作真正的答案。 - YasharBahman
显示剩余3条评论

5
事实上,有一个简单的解决方法可以获取Windows版本字符串,它以其用户代理形式出现(Windows NT 6.x)。
对于想知道为什么我们要这样做的人:为了收集关于我们用户的Windows版本的统计信息,并做出关于向后兼容性的明智决策。
public class OsVersion
{
    public static Task<string> GetAsync()
    {
        var t = new TaskCompletionSource<string>();
        var w = new WebView();
        w.AllowedScriptNotifyUris = WebView.AnyScriptNotifyUri;
        w.NavigateToString("<html />");
        NotifyEventHandler h = null;
        h = (s, e) =>
        {
            try
            {
                var match = Regex.Match(e.Value, @"Windows\s+NT\s+\d+(\.\d+)?");
                if (match.Success)
                    t.SetResult(match.Value);
                else
                    t.SetResult("Unknowm");
            }
            catch (Exception ex) { t.SetException(ex); }
            finally { /* release */ w.ScriptNotify -= h; }
        };
        w.ScriptNotify += h;
        w.InvokeScript("execScript", new[] { "window.external.notify(navigator.appVersion); " });
        return t.Task;
    }

这只会告诉你它是否是WP8.1。它不会告诉你操作系统版本号,例如手机是否处于开发者预览状态。对我来说,知道手机的操作系统版本号非常重要。某些版本存在错误,而其他版本则不存在,我想制作一个错误报告并说明操作系统版本号。 - Quincy
是的,这在Windows手机上不起作用:),但问题是关于Windows 8的。恐怕除非微软允许我们使用版本助手API,否则我们将没有更好的选择:(。 - Cyprien Autexier
很高兴知道这应该适用于平板电脑。当时的问题是针对win8的,但现在WP/W8.1有通用项目,可以共享所有代码。 - Quincy
它不起作用。它总是返回Windows NT 6.2,但我有Windows 10。 - palota
我还没有在Windows 10上测试过它,但我相信你的话。新内核应该被命名为Windows NT 10,但由于它仍处于预览阶段,可能还没有出现在用户代理中。希望在新闻API中会有一个替代品!也许可以访问环境变量?谁知道呢。 - Cyprien Autexier
你应该看一下下面的解决方案,它似乎是现在做这件事情的更好方式。 - Cyprien Autexier

0

根据其他帖子的答案 - 没有API可以测试操作系统版本,但将会有API来查询特定类型的版本。这意味着您可能无法使用当前代码确定未来发布的Windows版本,但如果您不断更新代码,则可以根据特定类型是否可用来确定操作系统版本。现在,您应该假设正在使用当前版本的Windows 8。

此外,我没有尝试过,但通过与JavaScript进行互操作并解析“navigator.appVersion”可能是可能的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接