如何检测Windows 10 S?

时间:2017-11-18 16:24:34

标签: c# .net uwp windows-10 desktop-bridge

Windows 10 S是一个特殊的Windows版本,streamlined for security and superior performance。基本上,您只能从Microsoft Store安装应用程序。

您可以通过桌面桥接器将正常的桌面应用程序传送到商店,这样本身就不是一个大问题。但是,Windows 10 S对Store应用程序施加了额外的限制,这可能会导致它们在启动期间崩溃。

我收到了商店申请审核结果的反馈。

  

应用政策:10.1.2.1不准确的功能:Windows 10S

     

开发人员注意事项:

     

您的应用无法在Windows 10 S和应用程序上运行   终止,恕不另行通知用户。在Windows上无法使用的应用程序   10 S必须支持正常关机。

     

重现的步骤:   1.在Windows 10S上启动应用程序。   2.请注意,您的应用程序在Windows 10 S上不起作用,应用程序终止,恕不另行通知用户。

     

请务必测试适用于Windows 10 S的应用:   https://docs.microsoft.com/windows/uwp/porting/desktop-to-uwp-test-windows-s   经测试的设备:Windows 10桌面

基本上我需要做的是检测Windows 10 S并通知用户它不受支持。

4 个答案:

答案 0 :(得分:6)

使用GetProductInfo Win32 API调用并检查返回值PRODUCT_CLOUD0x000000B2)和PRODUCT_CLOUDN0x000000B3)。这2个值是Windows 10 S的SKU检测代码。

答案 1 :(得分:1)

我只是把它扔出去,作为另一种想法。这完全没有记载!

我纯粹偶然地了解到,如果您尝试documentation 10 S中不允许的某个Windows默认应用程序,例如%WinDir%\System32\cmd.exe,它将失败并显示错误代码我没见过的ERROR_SYSTEM_NEEDS_REMEDIATION(或15623)从任何其他电话中返回。

答案 2 :(得分:1)

受magicandre1981检查SKU的解决方案的启发,我将其作为具体解决方案实施。它包含一个解决方法,用于解决GetVersionEx()在Windows 10中不推荐使用的问题,并且包含对Windows 10 S开发模式的检查,以便进行正确的测试。

一个免责声明是,此检查在我的环境(真实的10 S和开发模式)下均按预期工作。但是最终用户报告说该检查不可靠,我无法验证最终用户是否实际运行10 S或只是认为自己运行了10S。尽管它通过了Microsoft的审核过程。

运行检查的C ++中的示例控制台应用程序:

// Windows10SCheck.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include "pch.h"
#include <iostream>
#include <Windows.h>

// Function to get the OS version number
//
// Uses RtlGetVersion() is available, otherwise falls back to GetVersionEx()
//
// Returns false if the check fails, true if success
bool GetOSVersion(OSVERSIONINFOEX* osversion) {
    NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEX);
    *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");

    if (RtlGetVersion != NULL)
    {
        // RtlGetVersion uses 0 (STATUS_SUCCESS)
        // as return value when succeeding
        return RtlGetVersion(osversion) == 0;
    }
    else {
        // GetVersionEx was deprecated in Windows 10
        // Only use it as fallback
#pragma warning(suppress : 4996)
        return GetVersionEx((LPOSVERSIONINFO)osversion);
    }
}

// Function to check if the product type is Windows 10 S
//
// The product type values are from: https://stackoverflow.com/a/47368738/959140
//
// Output parameter bool iswin10s indicates if running 10 S or not
//
// Returns false if the check fails, true if success
bool IsWindows10S(bool *iswin10s) {
    OSVERSIONINFOEX osinfo;
    osinfo.dwOSVersionInfoSize = sizeof(osinfo);
    osinfo.szCSDVersion[0] = L'\0';

    if (!GetOSVersion(&osinfo)) {
        return false;
    }

    DWORD dwReturnedProductType = 0;

    if (!GetProductInfo(osinfo.dwMajorVersion, osinfo.dwMinorVersion, 0, 0, &dwReturnedProductType)) {
        return false;
    }

    *iswin10s = dwReturnedProductType == PRODUCT_CLOUD || dwReturnedProductType == PRODUCT_CLOUDN;

    return true;
}

bool IsWindows10SDevMode() {
    // Checks for the policy file mentioned in the docs:
    // https://docs.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-test-windows-s
    struct stat buffer;

    // x64 applications
    std::string filePathName64 = "C:\\Windows\\system32\\CodeIntegrity\\SIPolicy.P7B";
    if (stat(filePathName64.c_str(), &buffer) == 0) {
        return true;
    }

    // x86 applications
    std::string filePathName86 = "C:\\Windows\\sysnative\\CodeIntegrity\\SIPolicy.P7B";
    if (stat(filePathName86.c_str(), &buffer) == 0) {
        return true;
    }


    return false;
}

int main() {
    bool is10s = false;
    if (!IsWindows10S(&is10s)) {
        std::cout << "Windows 10 S check failed";
    }

    std::cout << "\nIs 10 S: " << (is10s ? "true" : "false");
    std::cout << "\nIs 10 S Dev Mode: " << (IsWindows10SDevMode() ? "true" : "false");
}

答案 3 :(得分:0)

如果是 Windows 10 1803或更高版本,请检查以下DWORD注册表值:

  • 注册表项(路径):HKLM \ System \ CurrentControlSet \ Control \ CI \ Policy
  • 注册表值名称:SkuPolicyRequired
  • 注册表值(DWORD):1

(来源:https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-codeintegrity-skupolicyrequired

1803之前的Windows 10 版本中,Windows 10 S(和Windows 10 S N)是它们自己的SKU。要检查这一点,请使用WMI查询以下内容: Win32_OperatingSystem-> OperatingSystemSKU 并寻找178(Windows 10 S)或179(Windows 10 S N)的整数值。

无论运行哪个版本的Windows 10,查询S模式/ Windows 10 S / Windows 10 S N都非常棘手,因为将阻止诸如cmd,powershell,regedit,reg,wmic和wbemtest之类的通用工具。要启用这些工具,需要通过将注册表项放置到位(使用WinPE脱机),然后启动计算机,使设备进入“制造模式”。供参考,请参见:https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-10-s-manufacturing-mode

假设设备处于“制造模式”并且您可以访问命令提示符,以下是几种查询S模式/ Windows 10 S / Windows 10 S N的方法:

对于 Windows 10 1803和更高版本,一种简单的查询S模式的方法是在命令提示符下键入以下内容:

  

reg查询HKLM \ SYSTEM \ CurrentControlSet \ Control \ CI \ Policy / v SkuPolicyRequired

(如果收到消息,提示系统无法找到指定的注册表项或值,或者收到 REG_DWORD 以外的结果> 0x1 ,则表示未启用S模式()

对于 1803之前的Windows 10版本,在命令提示符下进行查询的一种简便方法是:

  

wmic os get operatingsystemsku