桌面复制屏幕捕获 - DuplicateOutput返回E_ACCESSDENIED错误

时间:2017-09-16 19:04:35

标签: visual-c++ directx-11 screen-capture dxgi desktop-duplication

我使用桌面复制API(DirectX11)捕获屏幕。 DuplicateOutput API返回访问被拒绝错误,并且在登录屏幕上的Windows 8.1计算机上发生这种情况非常罕见(可能是10%),尽管我的应用程序正在以SYSTEM级别权限运行并正确调用SetThreadDesktop。我曾经在我收到的每一个错误之后重置并调用SetThreadDesktop,但是即使在多个设备重置和插入之后,应用程序也无法从错误中恢复。在多次重试或重启应用程序之后,我不得不回退到GDI(应用程序在从directx切换到GDI之后工作正常),但这个想法看起来很糟糕。

注意:我确实在Windows 10 / Windows 8计算机上遇到了同样的问题,但与特定的Windows 8.1计算机相比并不常见。

here是E_ACCESSDENIED错误的描述,该错误仅告知此错误可能的情况(没有系统级权限或SetThreadDesktop未正确调用)。我尝试了所有可能的方法来找出问题,但无法解决。

任何帮助将不胜感激,提前致谢。

以下是启动设备的代码:

    //
// Initialize duplication interfaces
//
HRESULT cDuplicationManager::InitDupl(_In_ ID3D11Device* Device, _In_ IDXGIAdapter *_pAdapter, _In_ IDXGIOutput *_pOutput, _In_ UINT Output)
{
    HRESULT hr = E_FAIL;

    if(!_pOutput || !_pAdapter || !Device)
    {
        return hr;
    }

    m_OutputNumber = Output;

    // Take a reference on the device
    m_Device = Device;
    m_Device->AddRef();

    _pOutput->GetDesc(&m_OutputDesc);
     // QI for Output 1
    IDXGIOutput1* DxgiOutput1 = nullptr;
    hr = _pOutput->QueryInterface(__uuidof(DxgiOutput1), reinterpret_cast<void**>(&DxgiOutput1));

    if (FAILED(hr))
    {
        return ProcessFailure(nullptr, _T("Failed to QI for DxgiOutput1 in DUPLICATIONMANAGER"), _T("Error"), hr);
    }

    // Create desktop duplication
    hr = DxgiOutput1->DuplicateOutput(m_Device, &m_DeskDupl);

    DxgiOutput1->Release();
    DxgiOutput1 = nullptr;


    if (FAILED(hr) || !m_DeskDupl)
    {
        if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
        {
            return ProcessFailure(nullptr, _T("Maximum number of applications using Desktop Duplication API"), _T("Error"), hr);
        }

        return ProcessFailure(m_Device, _T("Failed to get duplicate output in DUPLICATIONMANAGER"), _T("Error"), hr);//, CreateDuplicationExpectedErrors);
    }

    return S_OK;
}

将桌面设置为当前线程的代码:

    DWORD setCurrentInputDesktop()
{
    DWORD errorCode = ERROR_ACCESS_DENIED;


    HDESK currentInputDesktop = OpenInputDesktop(0, false, GENERIC_ALL);

    if(currentInputDesktop != NULL)
    {
        if(!SetThreadDesktop(currentInputDesktop))
        {
            errorCode = GetLastError();
            cout << ("setCurrentInputDesktop: SetThreadDesktop failed. Error code: ") << errorCode;
        }
        else
        {
            errorCode = ERROR_SUCCESS;

            cout << ("setCurrentInputDesktop: SetThreadDesktop succeeded.");
        }

        CloseDesktop(currentInputDesktop);
    }
    else
    {
        errorCode = GetLastError();

        cout << "setCurrentInputDesktop: OpenInputDesktop failed. Error code: " << errorCode;
    }

    return errorCode;
}

以下是处理错误代码后返回的错误消息:

  

Id3d11DuplicationManager :: ProcessFailure - 错误:无法获取   DUPLICATIONMANAGER中的重复输出,详细信息:访问被拒绝。

0 个答案:

没有答案