Add error notification on run dialog

1. GetLastErrorAsString is moved from PluginsManager.cpp to Common.h and common.cpp and also function signature is changed
2. Below method were already defined in common.cpp, but not declared in common.h
       generic_string intToString(int val);
       generic_string uintToString(unsigned int val);
3. Updated RunDlg.cpp to show error if ShellExecute fails

Closes #2626, Fixes #2179
This commit is contained in:
SinghRajenM 2016-11-29 11:31:18 +05:30 committed by Don Ho
parent 6c340a3189
commit 7f98067c12
4 changed files with 50 additions and 21 deletions

View File

@ -911,3 +911,24 @@ bool matchInList(const TCHAR *fileName, const std::vector<generic_string> & patt
return false; return false;
} }
generic_string GetLastErrorAsString(DWORD errorCode)
{
generic_string errorMsg(_T(""));
// Get the error message, if any.
// If both error codes (passed error n GetLastError) are 0, then return empty
if (errorCode == 0)
errorCode = GetLastError();
if (errorCode == 0)
return errorMsg; //No error message has been recorded
LPWSTR messageBuffer = nullptr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
errorMsg += messageBuffer;
//Free the buffer.
LocalFree(messageBuffer);
return errorMsg;
}

View File

@ -182,3 +182,8 @@ generic_string stringTakeWhileAdmissable(const generic_string& input, const gene
double stodLocale(const generic_string& str, _locale_t loc, size_t* idx = NULL); double stodLocale(const generic_string& str, _locale_t loc, size_t* idx = NULL);
bool str2Clipboard(const generic_string &str2cpy, HWND hwnd); bool str2Clipboard(const generic_string &str2cpy, HWND hwnd);
generic_string GetLastErrorAsString(DWORD errorCode = 0);
generic_string intToString(int val);
generic_string uintToString(unsigned int val);

View File

@ -75,25 +75,6 @@ bool PluginsManager::unloadPlugin(int index, HWND nppHandle)
return true; return true;
} }
static std::wstring GetLastErrorAsString()
{
//Get the error message, if any.
DWORD errorMessageID = ::GetLastError();
if (errorMessageID == 0)
return std::wstring(); //No error message has been recorded
LPWSTR messageBuffer = nullptr;
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
std::wstring message(messageBuffer, size);
//Free the buffer.
LocalFree(messageBuffer);
return message;
}
static WORD GetBinaryArchitectureType(const TCHAR *filePath) static WORD GetBinaryArchitectureType(const TCHAR *filePath)
{ {
WORD machine_type = IMAGE_FILE_MACHINE_UNKNOWN; WORD machine_type = IMAGE_FILE_MACHINE_UNKNOWN;
@ -151,9 +132,9 @@ int PluginsManager::loadPlugin(const TCHAR *pluginFilePath, vector<generic_strin
pi->_hLib = ::LoadLibrary(pluginFilePath); pi->_hLib = ::LoadLibrary(pluginFilePath);
if (!pi->_hLib) if (!pi->_hLib)
{ {
const std::wstring& lastErrorMsg = GetLastErrorAsString(); generic_string lastErrorMsg = GetLastErrorAsString();
if (lastErrorMsg.empty()) if (lastErrorMsg.empty())
throw generic_string(TEXT("Load Library is failed.\nMake \"Runtime Library\" setting of this project as \"Multi-threaded(/MT)\" may cure this problem.")); throw generic_string(TEXT("Load Library has failed.\nChanging the project's \"Runtime Library\" setting to \"Multi-threaded(/MT)\" might solve this problem."));
else else
throw generic_string(lastErrorMsg.c_str()); throw generic_string(lastErrorMsg.c_str());
} }

View File

@ -195,6 +195,28 @@ HINSTANCE Command::run(HWND hWnd)
expandNppEnvironmentStrs(argsIntermediate, args2Exec, args2ExecLen, hWnd); expandNppEnvironmentStrs(argsIntermediate, args2Exec, args2ExecLen, hWnd);
HINSTANCE res = ::ShellExecute(hWnd, TEXT("open"), cmd2Exec, args2Exec, TEXT("."), SW_SHOW); HINSTANCE res = ::ShellExecute(hWnd, TEXT("open"), cmd2Exec, args2Exec, TEXT("."), SW_SHOW);
// As per MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx)
// If the function succeeds, it returns a value greater than 32.
// If the function fails, it returns an error value that indicates the cause of the failure.
int retResult = reinterpret_cast<int>(res);
if (retResult <= 32)
{
generic_string errorMsg;
errorMsg += GetLastErrorAsString(retResult);
errorMsg += TEXT("An attempt was made to execute the below command.");
errorMsg += TEXT("\n----------------------------------------------------------");
errorMsg += TEXT("\nCommand: ");
errorMsg += cmd2Exec;
errorMsg += TEXT("\nArguments: ");
errorMsg += args2Exec;
errorMsg += TEXT("\nError Code: ");
errorMsg += intToString(retResult);
errorMsg += TEXT("\n----------------------------------------------------------");
::MessageBox(hWnd, errorMsg.c_str(), TEXT("ShellExecute - ERROR"), MB_ICONINFORMATION | MB_APPLMODAL);
}
return res; return res;
} }