处理 Windows 相机隐私设置

Windows 允许用户在 Windows“设置”应用中的“隐私和安全”->“相机”下授予或拒绝访问 设备的相机。 可以针对整个设备、所有未打包的应用或单个打包的应用禁用相机访问。 本文介绍了检查应用是否有权访问相机并处理用户拒绝访问的情况的最佳做法。

在初始化相机之前检查访问权限

对于打包的应用,应在初始化相机之前检查应用是否具有相机访问权限。 使用 AppCapability 类来确定你的应用是否具有访问权限。

bool cameraCapabilityAccess = false;
private void CheckCameraAccessStatus()
{
    var status = AppCapability.Create("Webcam").CheckAccess();
    
    if (status == AppCapabilityAccessStatus.Allowed)
    {
        cameraCapabilityAccess = true;
        cameraButton.IsEnabled = true;
    }
    else
    {
        cameraCapabilityAccess = false;
        cameraButton.IsEnabled = false;
    }
}

处理访问被拒绝错误

如果用户在相机隐私设置页中禁用了相机,则 Windows 相机捕获 API 将返回错误 E_ACCESSDENIED应用尝试访问相机捕获设备。 应用应在初始化捕获设备时检查此错误。 如果初始化失败并出现此错误,建议将用户定向到相机隐私设置页面,并可能启用对应用的访问权限。 可以使用 URI ms-settings:privacy-webcam启动相机隐私设置页。

以下示例演示如何在调用 MediaCapture.InitializeAsync 时检查E_ACCESSDENIED。

try
{
    await mediaCapture.InitializeAsync(mediaCaptureInitializationSettings);
}
catch (System.UnauthorizedAccessException ex)
{
    // E_ACCESSDENIED, 0x80070005 in hexadecimal, -2147024891 in decimal
    if (ex.HResult == -2147024891)
    {
        StatusTextBlock.Text = "Access to the camera has been denied." +
            "Click the Settings button to check the camera privacy settings";               
    }

    return;
}
...
// Launch the camera privacy Settings page
private async void LaunchSettingsButton_Click(object sender, RoutedEventArgs e)
{
    bool result = await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-webcam"));
}

以下示例演示了在初始化捕获设备的 IMFMediaSource 时从 IMFActivate::ActivateObject 返回的E_ACCESSDENIED错误。

IMFMediaSource* pSource = NULL;
IMFAttributes* pAttributes = NULL;
IMFActivate** ppDevices = NULL;

// Create an attribute store to specify the enumeration parameters.
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
if (FAILED(hr))
{
    goto done;
}

// Source type: video capture devices
hr = pAttributes->SetGUID(
    MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
    MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
);
if (FAILED(hr))
{
    goto done;
}

// Enumerate devices.
UINT32 count;
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
if (FAILED(hr))
{
    goto done;
}

if (count == 0)
{
    hr = E_FAIL;
    goto done;
}

// Create the media source object.
hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(&pSource));
if (FAILED(hr))
{
    if (hr == E_ACCESSDENIED)
    {
        int response = MessageBox(hWnd, L"Access to the camera was denied. Open the camera privacy settings?", L"Error", MB_YESNO);
        if (response == IDYES)
        {
            ShellExecute(NULL, L"open", L"ms-settings:privacy-webcam", L"", L".", SW_SHOWDEFAULT);
        }
    } 
    goto done;
}

实现回退行为

应用应实施前面的步骤,以提醒用户检测和提醒用户由于隐私设置而限制相机访问,并将用户定向到相机隐私设置页面以允许他们更新其设置。 执行这些步骤后,应用应重试相机初始化,以查看是否已授予访问权限。 如果用户拒绝更新其设置以允许应用访问相机,请考虑提供替代功能。 例如,可以禁用相机功能、切换到其他模式或显示占位符图像来代替相机预览。