From 45e79757ee98c2dca6c04e7f7322a062c5a10884 Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 18 Jun 2016 22:40:02 +0200 Subject: [PATCH] Fixed: Create links under Windows --- .../client/ryzom_installer/src/configfile.cpp | 25 ++++- .../client/ryzom_installer/src/configfile.h | 1 + .../client/ryzom_installer/src/operation.h | 3 +- .../ryzom_installer/src/operationdialog.cpp | 93 +++++++++++++++++-- .../ryzom_installer/src/operationdialog.h | 3 +- .../client/ryzom_installer/src/utils.cpp | 36 ++++--- .../tools/client/ryzom_installer/src/utils.h | 3 + 7 files changed, 138 insertions(+), 26 deletions(-) diff --git a/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp b/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp index 5839643e8..594bf9d1c 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp @@ -608,9 +608,24 @@ bool CConfigFile::foundTemporaryFiles(const QString &directory) const bool CConfigFile::shouldCreateDesktopShortcut() const { +#ifdef Q_OS_WIN32 const CProfile &profile = getProfile(); - return profile.desktopShortcut && !QFile::exists(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Ryzom.lnk"); + return profile.desktopShortcut && !NLMISC::CFile::isExists(qToUtf8(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Ryzom.lnk")); +#else + return false; +#endif +} + +bool CConfigFile::shouldCreateMenuShortcut() const +{ +#ifdef Q_OS_WIN32 + const CProfile &profile = getProfile(); + + return profile.menuShortcut && !NLMISC::CFile::isExists(qToUtf8(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/Ryzom/Ryzom.lnk")); +#else + return false; +#endif } QString CConfigFile::getProfileClientFullPath(int profileIndex) const @@ -799,8 +814,12 @@ OperationStep CConfigFile::getInstallNextStep() const if (shouldCreateDesktopShortcut()) { - // TODO: check they point to getClientFullPath() - return CreateShortcuts; + return CreateDesktopShortcut; + } + + if (shouldCreateMenuShortcut()) + { + return CreateMenuShortcut; } #ifdef Q_OS_WIN diff --git a/code/ryzom/tools/client/ryzom_installer/src/configfile.h b/code/ryzom/tools/client/ryzom_installer/src/configfile.h index 2ecd3e211..dd00b94e8 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/configfile.h +++ b/code/ryzom/tools/client/ryzom_installer/src/configfile.h @@ -153,6 +153,7 @@ public: bool foundTemporaryFiles(const QString &directory) const; bool shouldCreateDesktopShortcut() const; + bool shouldCreateMenuShortcut() const; // installation choices bool use64BitsClient() const; diff --git a/code/ryzom/tools/client/ryzom_installer/src/operation.h b/code/ryzom/tools/client/ryzom_installer/src/operation.h index e8e0af678..4c3a88c07 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operation.h +++ b/code/ryzom/tools/client/ryzom_installer/src/operation.h @@ -62,7 +62,8 @@ enum OperationStep CopyInstaller, UninstallOldClient, CreateProfile, - CreateShortcuts, + CreateDesktopShortcut, + CreateMenuShortcut, CreateAddRemoveEntry, Done }; diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp index 3f593dae0..ed40abe31 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp @@ -21,6 +21,7 @@ #include "configfile.h" #include "config.h" #include "profilesmodel.h" +#include "utils.h" #include "filescopier.h" #include "filesextractor.h" @@ -167,8 +168,12 @@ void COperationDialog::processInstallNextStep() createDefaultProfile(); break; - case CreateShortcuts: - createDefaultShortcuts(); + case CreateDesktopShortcut: + createClientDesktopShortcut(0); + break; + + case CreateMenuShortcut: + createClientMenuShortcut(0); break; case CreateAddRemoveEntry: @@ -673,6 +678,8 @@ void COperationDialog::copyInstaller() } } + // TODO: create shortcuts for installer + emit done(); } @@ -745,14 +752,42 @@ bool COperationDialog::createDefaultProfile() profile.name = QString("Ryzom (%1)").arg(server.name); profile.server = server.id; profile.comments = "Default profile created by Ryzom Installer"; + profile.desktopShortcut = false; + profile.menuShortcut = false; #ifdef Q_OS_WIN32 -// C:\Users\Public\Desktop - profile.desktopShortcut = QFile::exists(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Ryzom.lnk"); -#endif + QStringList paths; - // TODO - // profile.menuShortcut + // desktop + + // Windows XP + paths << "C:/Documents and Settings/All Users/Desktop"; + // since Windows Vista + paths << "C:/Users/Public/Desktop"; + // new location + paths << QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + + foreach(const QString &path, paths) + { + if (QFile::exists(path + "/Ryzom.lnk")) profile.desktopShortcut = true; + } + + paths.clear(); + + // start menu + + // Windows XP + paths << "C:/Documents and Settings/All Users/Start Menu/Programs"; + // since Windows Vista + paths << "C:/ProgramData/Microsoft/Windows/Start Menu/Programs"; + // new location + paths << QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation); + + foreach(const QString &path, paths) + { + if (QFile::exists(path + "/Ryzom/Ryzom.lnk")) profile.menuShortcut = true; + } +#endif config->addProfile(profile); config->save(); @@ -762,11 +797,51 @@ bool COperationDialog::createDefaultProfile() return true; } -bool COperationDialog::createDefaultShortcuts() +bool COperationDialog::createClientDesktopShortcut(int profileIndex) { CConfigFile *config = CConfigFile::getInstance(); - CServer server = config->getServer(); + const CProfile &profile = config->getProfile(profileIndex); + const CServer &server = config->getServer(profile.server); + + m_currentOperation = tr("Create desktop shortcut for profile %1").arg(profile.id); + +#ifdef Q_OS_WIN32 + if (profile.desktopShortcut) + { + QString shortcut = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Ryzom.lnk"; + CreateLink(config->getProfileClientFullPath(), shortcut, QString("--profile %1 %2").arg(profile.id).arg(profile.arguments), server.getDirectory(), "Default Ryzom client"); + } +#endif + + emit done(); + + return true; +} + +bool COperationDialog::createClientMenuShortcut(int profileIndex) +{ + CConfigFile *config = CConfigFile::getInstance(); + + const CProfile &profile = config->getProfile(profileIndex); + const CServer &server = config->getServer(profile.server); + + m_currentOperation = tr("Create menu shortcut for profile %1").arg(profile.id); + +#ifdef Q_OS_WIN32 + if (profile.menuShortcut) + { + QString path = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/Ryzom"; + + QDir dir; + + if (dir.mkpath(path)) + { + QString shortcut = path + "/Ryzom.lnk"; + CreateLink(config->getProfileClientFullPath(), shortcut, QString("--profile %1 %2").arg(profile.id).arg(profile.arguments), server.getDirectory(), "Default Ryzom client"); + } + } +#endif emit done(); diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h index 732e0afad..a170c30a0 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h +++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h @@ -102,7 +102,8 @@ protected: void copyInstaller(); void uninstallOldClient(); bool createDefaultProfile(); - bool createDefaultShortcuts(); + bool createClientDesktopShortcut(int profileIndex); + bool createClientMenuShortcut(int profileIndex); bool createAddRemoveEntry(); bool deleteAddRemoveEntry(); void deleteComponentsServers(); diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp index 5ab73f298..d9ebda4c0 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp @@ -111,22 +111,22 @@ wchar_t* qToWide(const QString &str) // Shell link, stored in the Comment field of the link // properties. -HRESULT CreateLink(const QString &pathObj, const QString &pathLink, const QString &desc) +bool CreateLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc) { IShellLinkW* psl; // Get a pointer to the IShellLink interface. It is assumed that CoInitialize // has already been called. - HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // Set the path to the shortcut target and add the description. - psl->SetPath(qToWide(pathObj)); + psl->SetPath(qToWide(QDir::toNativeSeparators(pathObj))); psl->SetDescription(qToWide(desc)); - psl->SetArguments(L"--profil "); - psl->SetWorkingDirectory(L""); + psl->SetArguments(qToWide(arguments)); + psl->SetWorkingDirectory(qToWide(QDir::toNativeSeparators(workingDir))); // Query IShellLink for the IPersistFile interface, used for saving the // shortcut in persistent storage. @@ -138,12 +138,12 @@ HRESULT CreateLink(const QString &pathObj, const QString &pathLink, const QStrin // for success. // Save the link by calling IPersistFile::Save. - hres = ppf->Save(qToWide(pathLink), TRUE); + hres = ppf->Save(qToWide(QDir::toNativeSeparators(pathLink)), TRUE); ppf->Release(); } psl->Release(); } - return hres; + return SUCCEEDED(hres); } // ResolveIt - Uses the Shell's IShellLink and IPersistFile interfaces @@ -163,7 +163,7 @@ HRESULT CreateLink(const QString &pathObj, const QString &pathLink, const QStrin // Shell link, stored in the Comment field of the link // properties. -HRESULT ResolveIt(HWND hwnd, const QString &linkFile, QString &path) +bool ResolveLink(const QWidget &window, const QString &linkFile, QString &path) { IShellLinkW* psl; WIN32_FIND_DATAW wfd; @@ -186,12 +186,12 @@ HRESULT ResolveIt(HWND hwnd, const QString &linkFile, QString &path) // for success. // Load the shortcut. - hres = ppf->Load(qToWide(linkFile), STGM_READ); + hres = ppf->Load(qToWide(QDir::toNativeSeparators(linkFile)), STGM_READ); if (SUCCEEDED(hres)) { // Resolve the link. - hres = psl->Resolve(hwnd, 0); + hres = psl->Resolve((HWND)window.winId(), 0); if (SUCCEEDED(hres)) { @@ -210,7 +210,7 @@ HRESULT ResolveIt(HWND hwnd, const QString &linkFile, QString &path) if (SUCCEEDED(hres)) { // Handle success - path = qFromWide(szGotPath); + path = QDir::fromNativeSeparators(qFromWide(szGotPath)); } else { @@ -227,7 +227,19 @@ HRESULT ResolveIt(HWND hwnd, const QString &linkFile, QString &path) psl->Release(); } - return hres; + return SUCCEEDED(hres); +} + +#else + +bool CreateLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc) +{ + return false; +} + +bool ResolveLink(const QWidget &window, const QString &pathLink, QString &pathObj) +{ + return false; } #endif diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.h b/code/ryzom/tools/client/ryzom_installer/src/utils.h index 8e760b400..6c2533076 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/utils.h +++ b/code/ryzom/tools/client/ryzom_installer/src/utils.h @@ -48,4 +48,7 @@ QString qFromWide(const wchar_t *str); wchar_t* qToWide(const QString &str); +bool CreateLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc); +bool ResolveLink(const QWidget &window, const QString &pathLink, QString &pathObj); + #endif