Make plugin installer threadable.

This commit is contained in:
Don HO 2018-09-29 17:12:19 +02:00
parent b662bcf5ae
commit f0d130bbc5
2 changed files with 111 additions and 48 deletions

View File

@ -41,6 +41,7 @@
#include "PluginsManager.h" #include "PluginsManager.h"
#include "md5.h" #include "md5.h"
#include "verifySignedFile.h" #include "verifySignedFile.h"
#include "LongRunningOperation.h"
using namespace std; using namespace std;
using nlohmann::json; using nlohmann::json;
@ -486,54 +487,47 @@ generic_string PluginsAdminDlg::getPluginsPath() const
return nppPluginsDir; return nppPluginsDir;
} }
bool PluginsAdminDlg::installPlugins()
DWORD WINAPI PluginsAdminDlg::launchPluginInstallerThread(void* params)
{ {
vector<size_t> indexes = _availableList.getCheckedIndexes(); auto lwp = static_cast<LaunchWingupParams*>(params);
vector<PluginUpdateInfo*> puis = _availableList.fromUiIndexesToPluginInfos(indexes);
generic_string nppPluginsDir = getPluginsPath(); Process updater(lwp->_updaterFullPath.c_str(), lwp->_updaterParams.c_str(), lwp->_updaterDir.c_str());
generic_string quoted_nppPluginsDir = TEXT("\"");
quoted_nppPluginsDir += nppPluginsDir;
quoted_nppPluginsDir += TEXT("\"");
for (auto i : puis)
{
generic_string updaterParams = TEXT("-unzipTo ");
updaterParams += quoted_nppPluginsDir;
// add zipFile's url
updaterParams += TEXT(" ");
updaterParams += i->_repository;
Process updater(_updaterFullPath.c_str(), updaterParams.c_str(), _updaterDir.c_str());
int result = updater.runSync(); int result = updater.runSync();
if (result == 0) // wingup return 0 -> OK if (result == 0) // wingup return 0 -> OK
{ {
generic_string installedPluginFolder = nppPluginsDir; generic_string installedPluginFolder = lwp->_nppPluginsDir;
PathAppend(installedPluginFolder, i->_folderName); PathAppend(installedPluginFolder, lwp->_pluginUpdateInfo->_folderName);
generic_string installedPluginPath = installedPluginFolder; generic_string installedPluginPath = installedPluginFolder;
PathAppend(installedPluginPath, i->_folderName + TEXT(".dll")); PathAppend(installedPluginPath, lwp->_pluginUpdateInfo->_folderName + TEXT(".dll"));
// check installed id to prevent from MITMA // check installed id to prevent from MITMA
MD5 md5; MD5 md5;
char *md5Result = md5.digestFile(ws2s(installedPluginPath).c_str()); char *md5Result = md5.digestFile(ws2s(installedPluginPath).c_str());
if (ws2s(i->_id) == md5Result)
if (ws2s(lwp->_pluginUpdateInfo->_id) == md5Result)
{ {
// Critical section
WaitForSingleObject(lwp->_mutex, INFINITE);
// Remove (Hide) installed plugin from available list // Remove (Hide) installed plugin from available list
_availableList.hideFromPluginInfoPtr(i); lwp->_uiAvailableList->hideFromPluginInfoPtr(lwp->_pluginUpdateInfo);
// Add installed plugin into insttalled list // Add installed plugin into insttalled list
PluginUpdateInfo* installedPui = new PluginUpdateInfo(*i); PluginUpdateInfo* installedPui = new PluginUpdateInfo(*(lwp->_pluginUpdateInfo));
installedPui->_isVisible = true; installedPui->_isVisible = true;
_installedList.pushBack(installedPui); lwp->_uiInstalledList->pushBack(installedPui);
// Load installed plugin // Load installed plugin
vector<generic_string> dll2Remove; vector<generic_string> dll2Remove;
int index = _pPluginsManager->loadPlugin(installedPluginPath.c_str(), dll2Remove); int index = lwp->_pPluginsManager->loadPlugin(installedPluginPath.c_str(), dll2Remove);
_pPluginsManager->addInMenuFromPMIndex(index); lwp->_pPluginsManager->addInMenuFromPMIndex(index);
// End of Critical section
ReleaseMutex(lwp->_mutex);
} }
else else
{ {
@ -545,18 +539,59 @@ bool PluginsAdminDlg::installPlugins()
TEXT("Plugin ID missmathed"), TEXT("Plugin ID missmathed"),
MB_OK | MB_APPLMODAL, MB_OK | MB_APPLMODAL,
0, 0,
i->_displayName.c_str()); lwp->_pluginUpdateInfo->_displayName.c_str());
deleteFileOrFolder(installedPluginFolder); deleteFileOrFolder(installedPluginFolder);
} }
} }
else // wingup return non-zero (-1) -> Not OK else // wingup return non-zero (-1) -> Not OK
{ {
// just move on // just move on
} }
return TRUE;
} }
bool PluginsAdminDlg::installPlugins()
{
vector<size_t> indexes = _availableList.getCheckedIndexes();
vector<PluginUpdateInfo*> puis = _availableList.fromUiIndexesToPluginInfos(indexes);
generic_string nppPluginsDir = getPluginsPath();
generic_string quoted_nppPluginsDir = TEXT("\"");
quoted_nppPluginsDir += nppPluginsDir;
quoted_nppPluginsDir += TEXT("\"");
HANDLE mutex = ::CreateMutex(NULL, false, TEXT("nppPluginInstaller"));
for (auto i : puis)
{
generic_string updaterParams = TEXT("-unzipTo ");
updaterParams += quoted_nppPluginsDir;
// add zipFile's url
updaterParams += TEXT(" ");
updaterParams += i->_repository;
LaunchWingupParams* lwp = new LaunchWingupParams;
lwp->_nppPluginsDir = nppPluginsDir;
lwp->_pluginUpdateInfo = i;
lwp->_pPluginsManager = _pPluginsManager;
lwp->_uiAvailableList = &_availableList;
lwp->_uiInstalledList = &_installedList;
lwp->_updaterDir = _updaterDir;
lwp->_updaterFullPath = _updaterFullPath;
lwp->_updaterParams = updaterParams;
lwp->_mutex = mutex;
_lwps.push_back(lwp);
//ReleaseMutex(mutex);
HANDLE hThread = ::CreateThread(NULL, 0, launchPluginInstallerThread, lwp, 0, NULL);
::CloseHandle(hThread);
}
return true; return true;
} }

View File

@ -151,11 +151,35 @@ private:
ListView _ui; ListView _ui;
}; };
//
// The parameters used for plugin installer thread
//
struct LaunchWingupParams
{
generic_string _updaterFullPath;
generic_string _updaterDir;
generic_string _updaterParams;
generic_string _nppPluginsDir;
PluginUpdateInfo* _pluginUpdateInfo;
PluginViewList* _uiAvailableList;
PluginViewList* _uiInstalledList;
PluginsManager *_pPluginsManager;
HANDLE _mutex;
};
class PluginsAdminDlg final : public StaticDialog class PluginsAdminDlg final : public StaticDialog
{ {
public : public :
PluginsAdminDlg(); PluginsAdminDlg();
~PluginsAdminDlg() {} ~PluginsAdminDlg() {
for (auto i : _lwps)
delete i;
};
void init(HINSTANCE hInst, HWND parent) { void init(HINSTANCE hInst, HWND parent) {
Window::init(hInst, parent); Window::init(hInst, parent);
}; };
@ -206,6 +230,8 @@ private :
PluginsManager *_pPluginsManager = nullptr; PluginsManager *_pPluginsManager = nullptr;
NppCurrentStatus _nppCurrentStatus; NppCurrentStatus _nppCurrentStatus;
std::vector<LaunchWingupParams*> _lwps; // Add each new instanciate plugin installer parameter object of the thread for cleaning up afterward
void collectNppCurrentStatusInfos(); void collectNppCurrentStatusInfos();
bool searchInPlugins(bool isNextMode) const; bool searchInPlugins(bool isNextMode) const;
const bool _inNames = true; const bool _inNames = true;
@ -220,6 +246,8 @@ private :
return searchFromCurrentSel(str2search, _inDescs, isNextMode); return searchFromCurrentSel(str2search, _inDescs, isNextMode);
}; };
static DWORD WINAPI launchPluginInstallerThread(void *params);
bool loadFromPluginInfos(); bool loadFromPluginInfos();
bool checkUpdates(); bool checkUpdates();
bool exitToUpdateRemovePlugins(bool isUpdate, const std::vector<PluginUpdateInfo*>& puis); bool exitToUpdateRemovePlugins(bool isUpdate, const std::vector<PluginUpdateInfo*>& puis);