Search code examples
qtc++-winrt

Exception is thrown at requesting instance of winrt::Windows::UI::Shell::TaskbarManager::GetDefault()


I'm developing a qt5 windows 11 application and i want to be able to request to user to pin it to the taskbar, using winRT language projection i request and instance of the current taskbar and it crashed with the following exception:

onecoreuap\base\appmodel\tiledatarepository\tiledevapi\src\taskbarmanagerimpl.cpp(111)\wpnapps.dll!00007FFA67F1B526: (caller: 00007FFA67F1B3B1) Exception(2) tid(7350) 80070005 Access denied.

Any idea what could i do to solve the situation?

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include <QDebug>

#include <Windows.h>

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.UI.Shell.h>

#include <iostream>

namespace winrt 
{
      using namespace Windows::UI::Shell;
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    try
    {
        auto taskbarManager = winrt::TaskbarManager::GetDefault(); // <- exception here
        
        if (taskbarManager.IsSupported())
        {
            taskbarManager.RequestPinCurrentAppAsync().get();
        }
    }
    catch (const winrt::hresult_error &error)
    {
        std::cerr << error.message().c_str() << std::endl;
    }
}
#include "mainwindow.h"

#include <QApplication>
#include <winrt/base.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    winrt::uninit_apartment();
    winrt::init_apartment();

    MainWindow w;
    w.show();
    
    return a.exec();
}

Solution

  • At last i've managed to make it work in a packaged app using unlocking the feature:

    auto result = winrt::Windows::ApplicationModel::LimitedAccessFeatures::TryUnlockFeature(c_lafFeature, c_lafToken, c_lafAttestation);
    if (result.Status() == winrt::Windows::ApplicationModel::LimitedAccessFeatureStatus::Available ||
        result.Status() == winrt::Windows::ApplicationModel::LimitedAccessFeatureStatus::AvailableWithoutToken)
    {
        auto taskbarManager = winrt::Windows::UI::Shell::TaskbarManager::GetDefault();
        if (taskbarManager.IsSupported() && taskbarManager.IsPinningAllowed() &&
            !taskbarManager.IsCurrentAppPinnedAsync().get())
        {
            taskbarManager.RequestPinCurrentAppAsync().get();
        }                
    }