Index: src/chext/TContextMenuHandler.cpp
===================================================================
diff -u -r5b53476be2173282f99dd5d72207de90317bacad -r3791a028b55dabb72c22d01c93a04794d8091fa4
--- src/chext/TContextMenuHandler.cpp	(.../TContextMenuHandler.cpp)	(revision 5b53476be2173282f99dd5d72207de90317bacad)
+++ src/chext/TContextMenuHandler.cpp	(.../TContextMenuHandler.cpp)	(revision 3791a028b55dabb72c22d01c93a04794d8091fa4)
@@ -232,7 +232,8 @@
 			spMenuItem->SetLocalName(wstrItemName.c_str());
 	}
 
-	return wstrItemName;
+	// NOTE: don't use wstrItemName here as there is an additional processing hidden in SetLocalName()
+	return spMenuItem->GetLocalName().c_str();
 }
 
 void TContextMenuHandler::Clear()
Index: src/common/TShellExtMenuConfig.cpp
===================================================================
diff -u -r3921d82d9605d98b2281f3f42d9f9c8385b89a3e -r3791a028b55dabb72c22d01c93a04794d8091fa4
--- src/common/TShellExtMenuConfig.cpp	(.../TShellExtMenuConfig.cpp)	(revision 3921d82d9605d98b2281f3f42d9f9c8385b89a3e)
+++ src/common/TShellExtMenuConfig.cpp	(.../TShellExtMenuConfig.cpp)	(revision 3791a028b55dabb72c22d01c93a04794d8091fa4)
@@ -267,7 +267,7 @@
 
 void TShellMenuItem::SetLocalName(const string::TString& strLocalName)
 {
-	m_strLocalName = strLocalName;
+	m_strLocalName = strLocalName + m_strWorkaroundSuffix.c_str();
 }
 
 void TShellMenuItem::InitSeparatorItem()
@@ -302,6 +302,44 @@
 	m_strItemTip = wstrItemTip;
 }
 
+// function tries to make item names unique by setting a text suffix composed of spaces that will be used
+// to display shell context menu;
+// This workaround is required due to specific way of handling menus for more than 16 items (files/folders)
+// selected in explorer - when invoking specific menu item, explorer forces shell extension to re-add all
+// menu items to a menu, and then invokes the first one with the name matching the one clicked by user.
+// Final effect was that a wrong menu item was selected when there were duplicate names in menu.
+void TShellMenuItem::CalculateWorkaroundSuffixes()
+{
+	std::map<std::wstring, std::wstring> mapNames;
+	std::list<TShellMenuItemPtr> listToProcess;
+	listToProcess.insert(listToProcess.end(), m_vChildItems.begin(), m_vChildItems.end());
+
+	while(!listToProcess.empty())
+	{
+		TShellMenuItemPtr spItem = listToProcess.front();
+		listToProcess.pop_front();
+
+		if(spItem->GetItemType() == eStandardItem)
+		{
+			auto iterFnd = mapNames.find(spItem->GetName().c_str());
+			if(iterFnd == mapNames.end())
+			{
+				mapNames.emplace(spItem->GetName().c_str(), L"");
+				spItem->SetWorkaroundSuffix(L"");
+			}
+			else
+			{
+				iterFnd->second += L" ";
+				spItem->SetWorkaroundSuffix(iterFnd->second);
+			}
+		}
+		else if(spItem->GetItemType() == eGroupItem)
+		{
+			listToProcess.insert(listToProcess.end(), spItem->m_vChildItems.begin(), spItem->m_vChildItems.end());
+		}
+	}
+}
+
 bool TShellMenuItem::SpecifiesDestinationPath() const
 {
 	return !IsGroupItem() && (m_tDestinationPath.GetDstPathSource() == TDestinationPathInfo::eDstType_Specified);
@@ -529,8 +567,11 @@
 
 	if(!m_spDragAndDropRoot->ReadFromConfig(rConfig, Concat(strBuffer, pszNodeName, _T("DragAndDropRootItem"))))
 		return false;
+	m_spDragAndDropRoot->CalculateWorkaroundSuffixes();
+
 	if(!m_spNormalRoot->ReadFromConfig(rConfig, Concat(strBuffer, pszNodeName, _T("NormalRootItem"))))
 		return false;
+	m_spNormalRoot->CalculateWorkaroundSuffixes();
 
 	return true;
 }
Index: src/common/TShellExtMenuConfig.h
===================================================================
diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r3791a028b55dabb72c22d01c93a04794d8091fa4
--- src/common/TShellExtMenuConfig.h	(.../TShellExtMenuConfig.h)	(revision 0d5b67ee96b435d63f7bf075dc8e28603793b187)
+++ src/common/TShellExtMenuConfig.h	(.../TShellExtMenuConfig.h)	(revision 3791a028b55dabb72c22d01c93a04794d8091fa4)
@@ -150,6 +150,8 @@
 	// initializer for group item
 	void InitGroupItem(const string::TString& wstrName, const string::TString& wstrItemTip);
 
+	void CalculateWorkaroundSuffixes();
+	
 	// clears everything
 	void Clear();
 
@@ -179,6 +181,9 @@
 	// helper - retrieves info if this command requires some paths present in clipboard to be enabled
 	bool RequiresClipboardPaths() const;
 
+	std::wstring GetWorkaroundSuffix() const { return m_strWorkaroundSuffix; }
+	void SetWorkaroundSuffix(std::wstring val) { m_strWorkaroundSuffix = val; }
+
 	// operations on children
 	size_t GetChildrenCount() const;
 	TShellMenuItemPtr GetChildAt(size_t stIndex) const;
@@ -216,6 +221,8 @@
 	// hints that this item is to be made default (bold), when detected operation type is equal to this operation type
 	chengine::EOperationType m_eDefaultItemHint;
 
+	std::wstring m_strWorkaroundSuffix;
+
 	std::vector<TShellMenuItemPtr> m_vChildItems;
 };