diff options
author | Andrew Knight <andrew.knight@digia.com> | 2013-05-18 13:01:57 +0300 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@digia.com> | 2013-07-19 10:47:18 +0200 |
commit | fc878f1a7b09a849659e050cf6f14e77354a48cb (patch) | |
tree | b558d0aa60958c3f03b2d210a051a67b5787b91e | |
parent | 66d724b693b575a8d0c0cc499ee1d4a05b234132 (diff) | |
download | qt-creator-fc878f1a7b09a849659e050cf6f14e77354a48cb.tar.gz |
Prompt developer registration when package addition fails
Additional error handling so that situations like missing developer
registrations can be handled. If the developer license is missing,
launch the developer license registration window.
Change-Id: I9988422984a902a9df3607db9038a91c90d2a897
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
-rw-r--r-- | src/plugins/winrt/packagemanager.cpp | 54 | ||||
-rw-r--r-- | src/plugins/winrt/packagemanager.h | 15 | ||||
-rw-r--r-- | src/plugins/winrt/winrt.pro | 2 | ||||
-rw-r--r-- | src/plugins/winrt/winrtplugin.cpp | 2 | ||||
-rw-r--r-- | src/plugins/winrt/winrtselectappdialog.cpp | 19 | ||||
-rw-r--r-- | src/plugins/winrt/winrtselectappdialog.h | 5 |
6 files changed, 74 insertions, 23 deletions
diff --git a/src/plugins/winrt/packagemanager.cpp b/src/plugins/winrt/packagemanager.cpp index 0d17744c52..2385559e99 100644 --- a/src/plugins/winrt/packagemanager.cpp +++ b/src/plugins/winrt/packagemanager.cpp @@ -44,6 +44,7 @@ # include <windows.foundation.collections.h> # include <windows.system.userprofile.h> # include <sddl.h> +# include <shellapi.h> using namespace Microsoft::WRL; using namespace ABI::Windows; @@ -101,34 +102,45 @@ static IUriRuntimeClass *createUriRunTimeClass(const QString &url, QString *erro return result; } -static bool evaluateDeploymentResult(AsyncDeployOperationProgress *asyncInfo, - ABI::Windows::Foundation::AsyncStatus status, - QString *errorMessage) +static PackageManager::Error evaluateDeploymentResult( + AsyncDeployOperationProgress *asyncInfo, + ABI::Windows::Foundation::AsyncStatus status, + QString *errorMessage) { - bool ok = true; + PackageManager::Error error = PackageManager::NoError; errorMessage->clear(); switch (status) { case ABI::Windows::Foundation::AsyncStatus::Started: case ABI::Windows::Foundation::AsyncStatus::Completed: break; case ABI::Windows::Foundation::AsyncStatus::Canceled: - ok = false; // Should not occur, deployment cannot be canceled. + error = PackageManager::Canceled; // Should not occur, deployment cannot be canceled. *errorMessage = PackageManager::tr("Operation canceled."); break; case ABI::Windows::Foundation::AsyncStatus::Error: { - ok = false; + error = PackageManager::UnknownError; ABI::Windows::Management::Deployment::IDeploymentResult *result; if (SUCCEEDED(asyncInfo->GetResults(&result))) { HSTRING hError; if (SUCCEEDED(result->get_ErrorText(&hError))) *errorMessage = hStringToQString(hError); + HRESULT errorCode; + if (SUCCEEDED(result->get_ExtendedErrorCode(&errorCode))) { + switch (HRESULT_CODE(errorCode)) { + case ERROR_INSTALL_POLICY_FAILURE: + error = PackageManager::DeveloperLicenseRequired; + break; + default: + break; // TODO: handle more error cases + } + } } if (errorMessage->isEmpty()) *errorMessage = PackageManager::tr("Unknown error."); } break; } - return ok; + return error; } // ---------- PackageManagerPrivate @@ -332,16 +344,16 @@ bool PackageManager::startAddPackage(const QString &manifestFile, HRESULT PackageManagerPrivate::packageAdded(AsyncDeployOperationProgress *asyncInfo, ABI::Windows::Foundation::AsyncStatus status) { QString errorMessage; - const bool ok = evaluateDeploymentResult(asyncInfo, status, &errorMessage); + const PackageManager::Error error = evaluateDeploymentResult(asyncInfo, status, &errorMessage); const ProgressManifestHash::Iterator it = pendingInstalls.find(asyncInfo); if (it == pendingInstalls.end()) { qWarning("%s: asyncInfo not found", Q_FUNC_INFO); return S_OK; } - if (ok) { + if (error == PackageManager::NoError) { emit q->packageAdded(it.value()); } else { - emit q->packageAddFailed(it.value(), errorMessage); + emit q->packageAddFailed(it.value(), errorMessage, error); } pendingInstalls.erase(it); return S_OK; @@ -372,16 +384,16 @@ bool PackageManager::startRemovePackage(const QString &fullName, QString *errorM HRESULT PackageManagerPrivate::packageRemoved(AsyncDeployOperationProgress *asyncInfo, ABI::Windows::Foundation::AsyncStatus status) { QString errorMessage; - const bool ok = evaluateDeploymentResult(asyncInfo, status, &errorMessage); + const PackageManager::Error error = evaluateDeploymentResult(asyncInfo, status, &errorMessage); const ProgressNameHash::Iterator it = pendingRemoves.find(asyncInfo); if (it == pendingRemoves.end()) { qWarning("%s: asyncInfo not found", Q_FUNC_INFO); return S_OK; } - if (ok) { + if (error == PackageManager::NoError) { emit q->packageRemoved(it.value()); } else { - emit q->packageRemovalFailed(it.value(), errorMessage); + emit q->packageRemovalFailed(it.value(), errorMessage, error); } pendingRemoves.erase(it); return S_OK; @@ -392,6 +404,18 @@ bool PackageManager::operationInProgress() const return !d->pendingInstalls.isEmpty() || !d->pendingRemoves.isEmpty(); } +void PackageManager::launchDeveloperRegistration() +{ + // Must run elevated, so we use the native API + SHELLEXECUTEINFO shExecInfo; + shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); + shExecInfo.lpVerb = L"runas"; + shExecInfo.lpFile = L"powershell"; + shExecInfo.lpParameters = L"-windowstyle hidden -command show-windowsdeveloperlicenseregistration"; + shExecInfo.nShow = SW_MINIMIZE; + ShellExecuteEx(&shExecInfo); +} + #else // defined(_MSC_VER) && _MSC_VER >= 1700 namespace WinRt { @@ -427,6 +451,10 @@ bool PackageManager::operationInProgress() const return false; } +void PackageManager::launchDeveloperRegistration() +{ +} + #endif // !defined(_MSC_VER) && _MSC_VER >= 1700 } // namespace Internal diff --git a/src/plugins/winrt/packagemanager.h b/src/plugins/winrt/packagemanager.h index 6f70ea7e57..792eca1300 100644 --- a/src/plugins/winrt/packagemanager.h +++ b/src/plugins/winrt/packagemanager.h @@ -63,6 +63,13 @@ public: DevelopmentMode = 0x1 }; + enum Error { + NoError, + UnknownError, + Canceled, + DeveloperLicenseRequired + }; + explicit PackageManager(QObject *parent = 0); ~PackageManager(); @@ -74,21 +81,25 @@ public: bool operationInProgress() const; + static void launchDeveloperRegistration(); + signals: void packageAdded(const QString &manifestFile); - void packageAddFailed(const QString &manifestFile, const QString &message); + void packageAddFailed(const QString &manifestFile, const QString &message, PackageManager::Error error); void packageRemoved(const QString &fullName); - void packageRemovalFailed(const QString &fullName, const QString &message); + void packageRemovalFailed(const QString &fullName, const QString &message, PackageManager::Error error); private: friend class PackageManagerPrivate; PackageManagerPrivate *d; }; +Q_DECLARE_METATYPE(PackageManager::Error) } // namespace Internal } // namespace WinRt Q_DECLARE_METATYPE(WinRt::Internal::WinRtPackagePtr) + #endif // WINRT_INTERNAL_PACKAGEMANAGER_H diff --git a/src/plugins/winrt/winrt.pro b/src/plugins/winrt/winrt.pro index 14d917d679..ce06d46cc4 100644 --- a/src/plugins/winrt/winrt.pro +++ b/src/plugins/winrt/winrt.pro @@ -29,7 +29,7 @@ SOURCES += \ DEFINES += WINRT_LIBRARY -win32-msvc2012:LIBS += -lruntimeobject -ladvapi32 +win32-msvc2012:LIBS += -lruntimeobject -ladvapi32 -lshell32 FORMS += \ winrtrunconfigurationwidget.ui \ diff --git a/src/plugins/winrt/winrtplugin.cpp b/src/plugins/winrt/winrtplugin.cpp index 51582803c9..95d51e46f5 100644 --- a/src/plugins/winrt/winrtplugin.cpp +++ b/src/plugins/winrt/winrtplugin.cpp @@ -29,6 +29,7 @@ #include "winrtplugin.h" #include "winrtrunfactories.h" +#include "packagemanager.h" #include <QtPlugin> #include <QSysInfo> @@ -39,6 +40,7 @@ namespace Internal { WinRtPlugin::WinRtPlugin() //: m_registerAction(new QAction(tr("Register Appx Package"))) { setObjectName(QLatin1String("WinRtPlugin")); + qRegisterMetaType<PackageManager::Error>(); } WinRtPlugin::~WinRtPlugin() diff --git a/src/plugins/winrt/winrtselectappdialog.cpp b/src/plugins/winrt/winrtselectappdialog.cpp index 90828d9eb0..d758832616 100644 --- a/src/plugins/winrt/winrtselectappdialog.cpp +++ b/src/plugins/winrt/winrtselectappdialog.cpp @@ -61,12 +61,12 @@ WinRtSelectAppDialog::WinRtSelectAppDialog(QWidget *parent) { connect(m_packageManager, SIGNAL(packageRemoved(QString)), this, SLOT(packageRemoved(QString))); - connect(m_packageManager, SIGNAL(packageRemovalFailed(QString,QString)), + connect(m_packageManager, SIGNAL(packageRemovalFailed(QString,QString,PackageManager::Error)), this, SLOT(packageRemovalFailed(QString,QString))); connect(m_packageManager, SIGNAL(packageAdded(QString)), this, SLOT(packageAdded(QString))); - connect(m_packageManager, SIGNAL(packageAddFailed(QString,QString)), - this, SLOT(packageAddFailed(QString,QString))); + connect(m_packageManager, SIGNAL(packageAddFailed(QString,QString,PackageManager::Error)), + this, SLOT(packageAddFailed(QString,QString,PackageManager::Error))); m_ui->setupUi(this); m_ui->table->setUniformRowHeights(true); @@ -173,11 +173,20 @@ void WinRtSelectAppDialog::packageAdded(const QString &) refresh(); } -void WinRtSelectAppDialog::packageAddFailed(const QString &manifestFile, const QString &message) +void WinRtSelectAppDialog::packageAddFailed(const QString &manifestFile, const QString &message, PackageManager::Error error) { setEnabled(true); QApplication::restoreOverrideCursor(); - QMessageBox::warning(this, tr("Error Adding \"%1\"").arg(manifestFile), message); + + if (error == PackageManager::DeveloperLicenseRequired) { + QString prompt = message + QLatin1String("\n\n") + + tr("\nWould you like to launch the developer registration tool?"); + if (QMessageBox::question(this, tr("Error: Developer License Required"), + prompt) == QMessageBox::Yes) + PackageManager::launchDeveloperRegistration(); + } else { + QMessageBox::warning(this, tr("Package Registration Error").arg(manifestFile), message); + } } void WinRtSelectAppDialog::contextMenuEvent(QContextMenuEvent *e) diff --git a/src/plugins/winrt/winrtselectappdialog.h b/src/plugins/winrt/winrtselectappdialog.h index 9b87925cbc..200190b862 100644 --- a/src/plugins/winrt/winrtselectappdialog.h +++ b/src/plugins/winrt/winrtselectappdialog.h @@ -38,9 +38,10 @@ class QPushButton; class QSortFilterProxyModel; QT_END_NAMESPACE +#include "packagemanager.h" + namespace WinRt { namespace Internal { -class PackageManager; namespace Ui { class WinRtSelectAppDialog; } @@ -66,7 +67,7 @@ private slots: void currentIndexChanged(); void refresh(); void packageAdded(const QString &manifestFile); - void packageAddFailed(const QString &manifestFile, const QString &message); + void packageAddFailed(const QString &manifestFile, const QString &message, PackageManager::Error error); void packageRemoved(const QString &fullName); void packageRemovalFailed(const QString &fullName, const QString &message); void addPackage(); |