From 224627515a20231499f65c16089b07d363d64586 Mon Sep 17 00:00:00 2001 From: Tannin Date: Thu, 5 Sep 2013 21:04:20 +0200 Subject: [PATCH] - bugfix: automatically removes a file from old NCC release that was interfering with the current version - bugfix: fomod installer didn't find fomod files in nested folder - bugfix: python proxy will now not even try to initialize python if python_dir contains no python. This is necessary because the python interpreter crashes the application if the path is invalid --- src/proxy/proxyPython.pro | 5 ++- src/proxy/proxypython.cpp | 65 +++++++++++++++++++++++++++---------- src/proxy/proxypython.h | 4 +++ src/runner/pythonrunner.cpp | 16 +++++++-- src/runner/pythonrunner.h | 10 +++++- 5 files changed, 75 insertions(+), 25 deletions(-) diff --git a/src/proxy/proxyPython.pro b/src/proxy/proxyPython.pro index a8db273..74551f4 100644 --- a/src/proxy/proxyPython.pro +++ b/src/proxy/proxyPython.pro @@ -14,7 +14,6 @@ contains(QT_VERSION, "^5.*") { CONFIG += plugins CONFIG += dll -CONFIG += warn_on CONFIG(release, debug|release) { QMAKE_CXXFLAGS += /Zi @@ -46,5 +45,5 @@ WINPWD ~= s,/,$$QMAKE_DIR_SEP,g QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\sip.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n) -QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtCore.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n) -QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtGui.pyd $$quote($$DSTDIR)\\plugins\\data\\ $$escape_expand(\\n) +QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtCore.pyd $$quote($$DSTDIR)\\plugins\\data\\PyQt4\\ $$escape_expand(\\n) +QMAKE_POST_LINK += copy $$(PYTHONPATH)\\lib\\site-packages\\PyQt4\\QtGui.pyd $$quote($$DSTDIR)\\plugins\\data\\PyQt4\\ $$escape_expand(\\n) diff --git a/src/proxy/proxypython.cpp b/src/proxy/proxypython.cpp index d6df84b..63a30ee 100644 --- a/src/proxy/proxypython.cpp +++ b/src/proxy/proxypython.cpp @@ -88,6 +88,14 @@ bool ProxyPython::init(IOrganizer *moInfo) m_LoadFailure = FAIL_OTHER; + QString pythonPath = m_MOInfo->pluginSetting(name(), "python_dir").toString(); + + if (!pythonPath.isEmpty() && !QFile::exists(pythonPath + "/python.exe")) { + m_LoadFailure = FAIL_WRONGPYTHONPATH; + return true; + } + + m_TempRunnerFile = ExtractResource(IDR_LOADER_DLL, "__pythonRunner.dll"); m_RunnerLib = ::LoadLibraryW(ToWString(m_TempRunnerFile).c_str()); if (m_RunnerLib != NULL) { @@ -95,8 +103,12 @@ bool ProxyPython::init(IOrganizer *moInfo) if (CreatePythonRunner == NULL) { throw MyException("embedded dll is invalid: " + windowsErrorString(::GetLastError())); } - m_Runner = CreatePythonRunner(moInfo, m_MOInfo->pluginSetting(name(), "python_dir").toString()); - m_LoadFailure = FAIL_NONE; + m_Runner = CreatePythonRunner(moInfo, pythonPath); + if (m_Runner != NULL) { + m_LoadFailure = FAIL_NONE; + } else { + m_LoadFailure = FAIL_INITFAIL; + } return true; } else { DWORD error = ::GetLastError(); @@ -156,7 +168,8 @@ QStringList ProxyPython::pluginList(const QString &pluginPath) const QObject *ProxyPython::instantiate(const QString &pluginName) { if (m_Runner != NULL) { - return m_Runner->instantiate(pluginName); + QObject *result = m_Runner->instantiate(pluginName); + return result; } else { return NULL; } @@ -168,6 +181,10 @@ std::vector ProxyPython::activeProblems() const std::vector result; if (m_LoadFailure == FAIL_MISSINGDEPENDENCIES) { result.push_back(PROBLEM_PYTHONMISSING); + } else if (m_LoadFailure == FAIL_WRONGPYTHONPATH) { + result.push_back(PROBLEM_WRONGPYTHONPATH); + } else if (m_LoadFailure == FAIL_INITFAIL) { + result.push_back(PROBLEM_INITFAIL); } else if (m_Runner != NULL) { if (!m_Runner->isPythonInstalled()) { // don't know how this could happen but wth @@ -185,11 +202,17 @@ QString ProxyPython::shortDescription(unsigned int key) const { switch (key) { case PROBLEM_PYTHONMISSING: { - return tr("Python not installed or not found"); - } break; + return tr("Python not installed or not found"); + } break; case PROBLEM_PYTHONWRONGVERSION: { - return tr("Python version is incompatible"); - } break; + return tr("Python version is incompatible"); + } break; + case PROBLEM_WRONGPYTHONPATH: { + return tr("Invalid python path"); + } break; + case PROBLEM_INITFAIL: { + return tr("Initializing Python failed"); + } break; default: throw MyException(tr("invalid problem key %1").arg(key)); } @@ -200,24 +223,30 @@ QString ProxyPython::fullDescription(unsigned int key) const { switch (key) { case PROBLEM_PYTHONMISSING: { - return tr("Some plugins require the python interpreter to be installed. " - "These plugins will not even show up in settings->plugins.
" - "If you want to use those plugins, please install the 32-bit version of Python 2.7.x from %1.").arg(s_DownloadPythonURL); - } break; + return tr("Some plugins require the python interpreter to be installed. " + "These plugins will not even show up in settings->plugins.
" + "If you want to use those plugins, please install the 32-bit version of Python 2.7.x from %1.").arg(s_DownloadPythonURL); + } break; case PROBLEM_PYTHONWRONGVERSION: { - return tr("Your installed python version has a different version than 2.7. " - "Some plugins may not work.
" - "If you have multiple versions of python installed you may have to configure the path to 2.7 " - "in the settings dialog."); - } break; + return tr("Your installed python version has a different version than 2.7. " + "Some plugins may not work.
" + "If you have multiple versions of python installed you may have to configure the path to 2.7 " + "in the settings dialog."); + } break; + case PROBLEM_WRONGPYTHONPATH: { + return tr("Please set python_dir in Settings->Plugins->ProxyPython to the path of your python 2.7 installation."); + } break; + case PROBLEM_INITFAIL: { + return tr("Sorry, I don't know any details. Most likely your python installation is not supported."); + } break; default: throw MyException(tr("invalid problem key %1").arg(key)); } } -bool ProxyPython::hasGuidedFix(unsigned int) const +bool ProxyPython::hasGuidedFix(unsigned int key) const { - return true; + return (key == PROBLEM_PYTHONMISSING) || (key == PROBLEM_PYTHONWRONGVERSION); } void ProxyPython::startGuidedFix(unsigned int) const diff --git a/src/proxy/proxypython.h b/src/proxy/proxypython.h index 3be83a4..f2d15c6 100644 --- a/src/proxy/proxypython.h +++ b/src/proxy/proxypython.h @@ -50,6 +50,8 @@ private: static const unsigned int PROBLEM_PYTHONMISSING = 1; static const unsigned int PROBLEM_PYTHONWRONGVERSION = 2; + static const unsigned int PROBLEM_WRONGPYTHONPATH = 3; + static const unsigned int PROBLEM_INITFAIL = 4; static const char *s_DownloadPythonURL; const MOBase::IOrganizer *m_MOInfo; @@ -61,6 +63,8 @@ private: FAIL_NONE, FAIL_NOTINIT, FAIL_MISSINGDEPENDENCIES, + FAIL_INITFAIL, + FAIL_WRONGPYTHONPATH, FAIL_OTHER } m_LoadFailure; diff --git a/src/runner/pythonrunner.cpp b/src/runner/pythonrunner.cpp index 982b6e4..7b50dbb 100644 --- a/src/runner/pythonrunner.cpp +++ b/src/runner/pythonrunner.cpp @@ -1,5 +1,7 @@ #include "pythonrunner.h" +#pragma warning( disable : 4100 ) +#pragma warning( disable : 4996 ) #include #include @@ -8,6 +10,7 @@ #include "proxypluginwrappers.h" #include #include +#include // sip and qt slots seems to conflict #include @@ -16,6 +19,7 @@ #include #endif + MOBase::IOrganizer *s_Organizer = NULL; @@ -44,8 +48,12 @@ private: IPythonRunner *CreatePythonRunner(const MOBase::IOrganizer *moInfo, const QString &pythonDir) { PythonRunner *result = new PythonRunner(moInfo); - result->initPython(pythonDir); - return result; + if (result->initPython(pythonDir)) { + return result; + } else { + delete result; + return NULL; + } } @@ -624,7 +632,9 @@ static char* argv0 = "ModOrganizer.exe"; bool PythonRunner::initPython(const QString &pythonPath) { try { - //QString pythonPath = m_MOInfo->pluginSetting(name(), "python_dir").toString(); + if (!pythonPath.isEmpty() && !QFile::exists(pythonPath + "/python.exe")) { + return false; + } strncpy(m_PythonHome, pythonPath.toUtf8().constData(), MAX_PATH); if (!pythonPath.isEmpty()) { Py_SetPythonHome(m_PythonHome); diff --git a/src/runner/pythonrunner.h b/src/runner/pythonrunner.h index b6435fc..f5cf752 100644 --- a/src/runner/pythonrunner.h +++ b/src/runner/pythonrunner.h @@ -15,7 +15,15 @@ public: virtual bool isPythonVersionSupported() const = 0; }; -extern "C" QDLLEXPORT IPythonRunner *CreatePythonRunner(const MOBase::IOrganizer *moInfo, const QString &pythonDir); + +#ifdef PYTHONRUNNER_LIBRARY +#define PYDLLEXPORT Q_DECL_EXPORT +#else // PYTHONRUNNER_LIBRARY +#define PYDLLEXPORT Q_DECL_IMPORT +#endif // PYTHONRUNNER_LIBRARY + +extern "C" PYDLLEXPORT IPythonRunner *CreatePythonRunner(const MOBase::IOrganizer *moInfo, const QString &pythonDir); + #endif // PYTHONRUNNER_H