summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Knight <andrew.knight@digia.com>2013-05-18 13:01:57 +0300
committerOswald Buddenhagen <oswald.buddenhagen@digia.com>2013-07-19 10:47:18 +0200
commitfc878f1a7b09a849659e050cf6f14e77354a48cb (patch)
treeb558d0aa60958c3f03b2d210a051a67b5787b91e
parent66d724b693b575a8d0c0cc499ee1d4a05b234132 (diff)
downloadqt-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.cpp54
-rw-r--r--src/plugins/winrt/packagemanager.h15
-rw-r--r--src/plugins/winrt/winrt.pro2
-rw-r--r--src/plugins/winrt/winrtplugin.cpp2
-rw-r--r--src/plugins/winrt/winrtselectappdialog.cpp19
-rw-r--r--src/plugins/winrt/winrtselectappdialog.h5
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();