diff --git a/PowerEditor/bin/NppShell.dll b/PowerEditor/bin/NppShell.dll index 9c1ece20c..d34d3eac9 100644 Binary files a/PowerEditor/bin/NppShell.dll and b/PowerEditor/bin/NppShell.dll differ diff --git a/PowerEditor/bin/NppShell64.dll b/PowerEditor/bin/NppShell64.dll index 03d8463ef..cf6f8f6c5 100644 Binary files a/PowerEditor/bin/NppShell64.dll and b/PowerEditor/bin/NppShell64.dll differ diff --git a/PowerEditor/installer/nppSetup.nsi b/PowerEditor/installer/nppSetup.nsi index 83ccb090a..3667ddd7d 100644 --- a/PowerEditor/installer/nppSetup.nsi +++ b/PowerEditor/installer/nppSetup.nsi @@ -28,10 +28,10 @@ ; Define the application name !define APPNAME "Notepad++" -!define APPVERSION "6.6.2" +!define APPVERSION "6.6.3" !define APPNAMEANDVERSION "${APPNAME} v${APPVERSION}" !define VERSION_MAJOR 6 -!define VERSION_MINOR 62 +!define VERSION_MINOR 63 !define APPWEBSITE "http://notepad-plus-plus.org/" @@ -606,6 +606,10 @@ Section -"Notepad++" mainSection Exec 'regsvr32 /u /s "$INSTDIR\NppShell_04.dll"' Delete "$INSTDIR\NppShell_04.dll" + IfFileExists "$INSTDIR\NppShell_05.dll" 0 +3 + Exec 'regsvr32 /u /s "$INSTDIR\NppShell_05.dll"' + Delete "$INSTDIR\NppShell_05.dll" + ; detect the right of UserInfo::GetAccountType Pop $1 @@ -635,12 +639,12 @@ Section "Context Menu Entry" explorerContextMenu SetOverwrite try SetOutPath "$INSTDIR\" ${If} ${RunningX64} - File /oname=$INSTDIR\NppShell_05.dll "..\bin\NppShell64_05.dll" + File /oname=$INSTDIR\NppShell_06.dll "..\bin\NppShell64_06.dll" ${Else} - File "..\bin\NppShell_05.dll" + File "..\bin\NppShell_06.dll" ${EndIf} - Exec 'regsvr32 /s "$INSTDIR\NppShell_05.dll"' + Exec 'regsvr32 /s "$INSTDIR\NppShell_06.dll"' SectionEnd SectionGroup "Auto-completion Files" autoCompletionComponent @@ -1768,11 +1772,13 @@ Section un.explorerContextMenu Exec 'regsvr32 /u /s "$INSTDIR\NppShell_03.dll"' Exec 'regsvr32 /u /s "$INSTDIR\NppShell_04.dll"' Exec 'regsvr32 /u /s "$INSTDIR\NppShell_05.dll"' + Exec 'regsvr32 /u /s "$INSTDIR\NppShell_06.dll"' Delete "$INSTDIR\NppShell_01.dll" Delete "$INSTDIR\NppShell_02.dll" Delete "$INSTDIR\NppShell_03.dll" Delete "$INSTDIR\NppShell_04.dll" Delete "$INSTDIR\NppShell_05.dll" + Delete "$INSTDIR\NppShell_06.dll" SectionEnd Section un.UnregisterFileExt diff --git a/PowerEditor/src/tools/NppShell/src/NppShell.cpp b/PowerEditor/src/tools/NppShell/src/NppShell.cpp index df4627b10..60239f8d8 100644 --- a/PowerEditor/src/tools/NppShell/src/NppShell.cpp +++ b/PowerEditor/src/tools/NppShell/src/NppShell.cpp @@ -955,9 +955,12 @@ void InvalidateIcon(HICON * iconSmall, HICON * iconLarge) { STDMETHODIMP CShellExt::InvokeNPP(HWND /*hParent*/, LPCSTR /*pszWorkingDir*/, LPCSTR /*pszCmd*/, LPCSTR /*pszParam*/, int iShowCmd) { TCHAR szFilename[MAX_PATH]; TCHAR szCustom[MAX_PATH]; + TCHAR szNotepadExecutableFilename[3 * MAX_PATH]; // Should be able to contain szFilename plus szCustom plus some additional characters. LPTSTR pszCommand; size_t bytesRequired = 1; + memset(szNotepadExecutableFilename, 0, sizeof(TCHAR) * 3 * MAX_PATH); + TCHAR szKeyTemp[MAX_PATH + GUID_STRING_SIZE]; DWORD regSize = 0; DWORD pathSize = MAX_PATH; @@ -1002,46 +1005,61 @@ STDMETHODIMP CShellExt::InvokeNPP(HWND /*hParent*/, LPCSTR /*pszWorkingDir*/, LP regSize = (DWORD)MAX_PATH*sizeof(TCHAR); result = RegQueryValueEx(settingKey, TEXT("Path"), NULL, NULL, (LPBYTE)(szFilename), ®Size); szFilename[MAX_PATH-1] = 0; - lstrcat(pszCommand, TEXT("\"")); - lstrcat(pszCommand, szFilename); - lstrcat(pszCommand, TEXT("\"")); + lstrcat(szNotepadExecutableFilename, TEXT("\"")); + lstrcat(szNotepadExecutableFilename, szFilename); + lstrcat(szNotepadExecutableFilename, TEXT("\"")); result = RegQueryValueEx(settingKey, TEXT("Custom"), NULL, NULL, (LPBYTE)(szCustom), &pathSize); if (result == ERROR_SUCCESS) { - lstrcat(pszCommand, TEXT(" ")); - lstrcat(pszCommand, szCustom); + lstrcat(szNotepadExecutableFilename, TEXT(" ")); + lstrcat(szNotepadExecutableFilename, szCustom); } RegCloseKey(settingKey); - for (UINT i = 0; i < m_cbFiles; i++) { - DragQueryFile((HDROP)m_stgMedium.hGlobal, i, szFilename, MAX_PATH); - lstrcat(pszCommand, TEXT(" \"")); - lstrcat(pszCommand, szFilename); - lstrcat(pszCommand, TEXT("\"")); - } + // We have to open the files in batches. A command on the command-line can be at most + // 2048 characters in XP and 32768 characters in Win7. In the degenerate case where all + // paths are of length MAX_PATH, we can open at most x files at once, where: + // 260 * (x + 2) = 2048 or 32768 <=> x = 5 or x = 124. + // Note the +2 to account for the path to notepad++.exe. + // http://stackoverflow.com/questions/3205027/maximum-length-of-command-line-string - STARTUPINFO si; - PROCESS_INFORMATION pi; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - si.dwFlags = STARTF_USESHOWWINDOW; - si.wShowWindow = (WORD)iShowCmd; //SW_RESTORE; - if (!CreateProcess (NULL, pszCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { - DWORD errorCode = GetLastError(); - if (errorCode == ERROR_ELEVATION_REQUIRED) { //Fallback to shellexecute - CoInitializeEx(NULL, 0); - HINSTANCE execVal = ShellExecute(NULL, TEXT("runas"), pszCommand, NULL, NULL, iShowCmd); - CoUninitialize(); - if (execVal <= (HINSTANCE)32) { + const UINT kiBatchSize = m_winVer > WINVER_XP ? 100 : 4; + + UINT iFileIndex = 0; + while(iFileIndex < m_cbFiles) { + memset(pszCommand, 0, bytesRequired); + lstrcat(pszCommand, szNotepadExecutableFilename); + for (UINT iBatchSizeCounter = 0; iFileIndex < m_cbFiles && iBatchSizeCounter < kiBatchSize; iBatchSizeCounter++) { + DragQueryFile((HDROP)m_stgMedium.hGlobal, iFileIndex, szFilename, MAX_PATH); + lstrcat(pszCommand, TEXT(" \"")); + lstrcat(pszCommand, szFilename); + lstrcat(pszCommand, TEXT("\"")); + iFileIndex++; + } + + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = (WORD)iShowCmd; //SW_RESTORE; + if (!CreateProcess (NULL, pszCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + DWORD errorCode = GetLastError(); + if (errorCode == ERROR_ELEVATION_REQUIRED) { //Fallback to shellexecute + CoInitializeEx(NULL, 0); + HINSTANCE execVal = ShellExecute(NULL, TEXT("runas"), pszCommand, NULL, NULL, iShowCmd); + CoUninitialize(); + if (execVal <= (HINSTANCE)32) { + TCHAR * message = new TCHAR[512+bytesRequired]; + wsprintf(message, TEXT("ShellExecute failed (%d): Is this command correct?\r\n%s"), execVal, pszCommand); + MsgBoxError(message); + delete [] message; + } + } else { TCHAR * message = new TCHAR[512+bytesRequired]; - wsprintf(message, TEXT("ShellExecute failed (%d): Is this command correct?\r\n%s"), execVal, pszCommand); + wsprintf(message, TEXT("Error in CreateProcess (%d): Is this command correct?\r\n%s"), errorCode, pszCommand); MsgBoxError(message); delete [] message; } - } else { - TCHAR * message = new TCHAR[512+bytesRequired]; - wsprintf(message, TEXT("Error in CreateProcess (%d): Is this command correct?\r\n%s"), errorCode, pszCommand); - MsgBoxError(message); - delete [] message; } } diff --git a/PowerEditor/src/tools/NppShell/src/NppShell.h b/PowerEditor/src/tools/NppShell/src/NppShell.h index aa9158567..a98bdd48b 100644 --- a/PowerEditor/src/tools/NppShell/src/NppShell.h +++ b/PowerEditor/src/tools/NppShell/src/NppShell.h @@ -17,6 +17,7 @@ #include #define WINVER_VISTA 0x600 +#define WINVER_XP 0x0501 //This is not ideal, but missing from current mingw #ifndef ERROR_ELEVATION_REQUIRED