在 WinRT Metro App C# 中获取操作系统版本

Posted

技术标签:

【中文标题】在 WinRT Metro App C# 中获取操作系统版本【英文标题】:Get OS-Version in WinRT Metro App C# 【发布时间】:2012-04-24 21:39:20 【问题描述】:

我正在使用 C# 和 Visual Studio 11 Beta 编写 Metro Style 应用程序。 现在我想获得操作系统的操作系统版本。我怎样才能得到这个?

我发现了如何在“普通”应用程序中做到这一点。 在那里,您使用属性 O​​SVersion 的 Environment-Class,但在 .NET Core 中没有此属性

【问题讨论】:

我将它发送到一个 WebService 并在那里按 OS-Version 对请求进行排序。 我在 API 文档中看不到任何明显的内容,因此您也许可以在您的 Metro 应用程序版本中对其进行硬编码? 故意无法获取操作系统版本。历史上,应用程序误用了操作系统版本,而不是依赖于各种形式的功能检测,这给开发团队带来了严重的 appcompat 问题。对于 Windows 8,开发团队决定通过不提供 GetVersion API 来完全避免该问题。 @LarryOsterman - 你能举例说明如何对 c#/xaml 应用程序进行特征检测吗?我们必须使用反射吗? 目前 C#/Xaml 中没有对特征检测的语言投影支持,因为只有一个版本(因此所有功能都可用)。 WinRT 平台支持版本控制和功能检测,但语言预测没有实现它(因为没有办法测试它们的实现)。我什至无法推测如何实现特征检测,因为我没有参与这些特征的设计。 【参考方案1】:

事实上,有一个简单的解决方法可以在其用户代理形式 (Windows NT 6.x) 中获取 Windows 版本字符串。

对于想知道我们为什么要这样做的人:收集有关我们用户 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。它不会告诉您操作系统内部版本号是什么,例如手机是否处于开发预览状态。这对我了解手机的操作系统非常重要。某些版本中存在错误,而其他版本中不存在错误,我想做一个错误报告,说明操作系统版本号 是的,这不适用于 windows phone :),但问题是关于 windows 8。恐怕除非微软允许我们使用版本助手 api,否则我们将没有更好的选择: (. 很高兴知道这应该适用于平板电脑。当时的问题是针对 win8 的,但现在 WP/W8.1 有共享所有代码的通用项目 它不起作用。它总是返回 Windows NT 6.2,但我有 Windows 10。 我没有在windows 10上测试过,但我相信你。新内核应该命名为 Windows NT 10,但由于它仍然是预览版,它可能还没有找到用户代理的方式。让我们希望在新闻 api 中会有一个替代方案!也许访问环境变量?谁知道呢。【参考方案2】:

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

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

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

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

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

【讨论】:

我想它是面向未来的。 Metro 风格的应用很可能也可以在 Windows 9 上运行。 @svick - 他要做什么?如果在未来的操作系统上运行,显示错误消息?这不是未来的证明。 @RobertLevy,正如 OP 在评论中所说,将操作系统版本发送到 WebService。 你怎么能预料到“没有理由”检查操作系统版本?如果出于统计目的,获取应用程序运行的确切操作系统版本实际上是相关的(它可能不会永远固定在 6.2.9200.0,你不觉得吗?)?对不起,但这不是一个实际的答案,这只是一种避免它的傲慢方式。 了解某人正在运行的操作系统版本对于支持目的非常有用。如果您提供了一种直接从应用程序内向支持部门发送电子邮件的方法,那么在该电子邮件中嵌入操作系统版本详细信息会很有用。【参考方案3】:

您可以通过使用设备 API 获取低级系统组件的驱动程序版本号来获取操作系统版本号,但可能存在不正确的风险。

公认的答案是正确的,因为您不应该将功能与版本号联系起来,但有正当理由使用它,例如分析 - 了解您的许多用户何时已经使用新版本以及您应该考虑更新应用以利用它。

https://github.com/AttackPattern/CSharpAnalytics/blob/master/Source/CSharpAnalytics/SystemInfo/WindowsStoreSystemInfo.cs 有更多信息和示例代码(披露,我写了那个代码)

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

【讨论】:

我向你保证确实如此,我在 CSharpAnalytics 中使用它,并且我看到安装了数千个操作系统版本。 那么你应该发布你的版本。那个版本对我不起作用。但我会犯错误。对不起。 我只是将博客中的代码直接复制到了一个全新的 Windows 应用商店项目中,并从 MainPage.xaml.cs 中调用了每个方法。监视窗口显示它工作正常。如果您仍然没有看到,请告诉我发生了什么,以便我们确定它是否是特定于机器的。 此外,此人要求提供操作系统版本信息,您链接到 CPU 架构的答案。 也刚刚在 Windows 8.1 上验证 - 正确返回 6.3 作为操作系统版本号。 (Windows 8 是内核 6.2)【参考方案4】:

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

另外,我还没有尝试过,但是您可以通过与 javascript 进行互操作并解析“navigator.appVersion”来获得它。

【讨论】:

以上是关于在 WinRT Metro App C# 中获取操作系统版本的主要内容,如果未能解决你的问题,请参考以下文章

不能在 Metro 风格项目(WINRT)中使用 opencl

WinRT/Metro 风格应用程序中基于 ATL 的 COM 对象

Metro / Windows Store App:相对图像源绑定不起作用?

使用 C# 在 Windows 8 Metro App 上发送 POST 请求

WinRT:WebAuthenticationBroker For OAuth认证

无法使用 c# 导航到 Windows Metro App 上的页面