Index: .gitignore
===================================================================
diff -u -N -r4a481bbe77043e0bda2435c6d62a02700b3e46c5 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- .gitignore	(.../.gitignore)	(revision 4a481bbe77043e0bda2435c6d62a02700b3e46c5)
+++ .gitignore	(.../.gitignore)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -8,6 +8,7 @@
 *.opendb
 *.aps
 *.db
+*.bak
 src/ch/help/HTMLDefines.h
 src/ch/help/*/HTMLDefines.h
 src/ch/help/*/*.chm
Index: src/chext/DropMenuExt.cpp
===================================================================
diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/DropMenuExt.cpp	(.../DropMenuExt.cpp)	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/chext/DropMenuExt.cpp	(.../DropMenuExt.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -25,22 +25,20 @@
 #include "ShellPathsHelpers.h"
 #include "../common/TShellExtMenuConfig.h"
 #include "../libchcore/TSharedMemory.h"
-#include "TLogger.h"
+#include "Logger.h"
 #include "ShellExtensionVerifier.h"
 #include "HResultFormatter.h"
 
 /////////////////////////////////////////////////////////////////////////////
 // CDropMenuExt
 
 CDropMenuExt::CDropMenuExt() :
-	m_piShellExtControl(nullptr)
+	m_piShellExtControl(nullptr),
+	m_spLog(GetLogger(L"CDropMenuExt"))
 {
-	BOOST_LOG_FUNC();
-
 	HRESULT hResult = CoCreateInstance(CLSID_CShellExtControl, nullptr, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl);
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_HRESULT(rLogger, hResult) << L"CoCreateInstance()";
+	LOG_HRESULT(m_spLog, hResult) << L"Create instance of ShellExtControl";
 }
 
 CDropMenuExt::~CDropMenuExt()
@@ -54,28 +52,25 @@
 
 STDMETHODIMP CDropMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Initializing";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	// When called:
 	// 1. R-click on a directory
 	// 2. R-click on a directory background
 	// 3. Pressed Ctrl+C, Ctrl+X on a specified file/directory
 
 	if(!pidlFolder && !piDataObject)
 	{
-		BOOST_LOG_SEV(rLogger, error) << L"Missing both pointers.";
+		LOG_ERROR(m_spLog) << L"Missing both pointers.";
 		return E_FAIL;
 	}
 
 	if(!pidlFolder || !piDataObject)
-		BOOST_LOG_SEV(rLogger, warning) << L"Missing at least one parameter - it's unexpected.";
+		LOG_WARNING(m_spLog) << L"Missing at least one parameter - it's unexpected.";
 
 	if(!piDataObject)
 	{
-		BOOST_LOG_SEV(rLogger, error) << L"Missing piDataObject.";
+		LOG_ERROR(m_spLog) << L"Missing piDataObject.";
 		return E_FAIL;
 	}
 
@@ -85,21 +80,20 @@
 		return E_FAIL;
 
 	HRESULT hResult = ReadShellConfig();
+	LOG_HRESULT(m_spLog, hResult) << L"Read shell config";
 	if(SUCCEEDED(hResult))
+	{
 		hResult = m_tShellExtData.GatherDataFromInitialize(pidlFolder, piDataObject);
+		LOG_HRESULT(m_spLog, hResult) << L"Gather data from initialize";
+	}
 
-	BOOST_LOG_HRESULT(rLogger, hResult) << L"";
-
 	return hResult;
 }
 
 STDMETHODIMP CDropMenuExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Querying context menu";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	// check options
 	HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl);
 	if(!hWnd)
@@ -124,11 +118,8 @@
 
 STDMETHODIMP CDropMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Invoking command";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl);
 	if(hWnd == nullptr)
 		return E_FAIL;
@@ -176,11 +167,8 @@
 
 STDMETHODIMP CDropMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Retrieving command string for cmd: " << idCmd;
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	memset(pszName, 0, cchMax);
 
 	if(uFlags != GCS_HELPTEXTW && uFlags != GCS_HELPTEXTA)
@@ -231,10 +219,6 @@
 
 HRESULT CDropMenuExt::ReadShellConfig()
 {
-	BOOST_LOG_FUNC();
-
-	TLogger& rLogger = Logger::get();
-
 	try
 	{
 		HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl);
@@ -245,7 +229,7 @@
 		unsigned long ulSHMID = GetTickCount();
 		if(::SendMessage(hWnd, WM_GETCONFIG, eLocation_DragAndDropMenu, ulSHMID) != TRUE)
 		{
-			BOOST_LOG_SEV(rLogger, error) << L"Failed to retrieve configuration from Copy Handler";
+			LOG_ERROR(m_spLog) << L"Failed to retrieve configuration from Copy Handler";
 			return E_FAIL;
 		}
 
Index: src/chext/DropMenuExt.h
===================================================================
diff -u -N -r633a533cb6e741d44fe28aa56339e1d2709b1b27 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/DropMenuExt.h	(.../DropMenuExt.h)	(revision 633a533cb6e741d44fe28aa56339e1d2709b1b27)
+++ src/chext/DropMenuExt.h	(.../DropMenuExt.h)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -23,6 +23,7 @@
 #include "TContextMenuHandler.h"
 #include "..\common\TShellExtMenuConfig.h"
 #include "TShellExtData.h"
+#include "..\liblogger\TLogger.h"
 
 /////////////////////////////////////////////////////////////////////////////
 // CDropMenuExt
@@ -66,10 +67,10 @@
 
 	TContextMenuHandler m_tContextMenuHandler;
 
-//	TActionSelector m_asSelector;
-
 	chcore::TPathContainer m_vPaths;
 	chcore::TSmartPath m_pathPidl;
+
+	logger::TLoggerPtr m_spLog;
 };
 
 #endif //__DROPMENUEXT_H_
Index: src/chext/Logger.cpp
===================================================================
diff -u -N
--- src/chext/Logger.cpp	(revision 0)
+++ src/chext/Logger.cpp	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -0,0 +1,98 @@
+// ============================================================================
+//  Copyright (C) 2001-2015 by Jozef Starosczyk
+//  ixen@copyhandler.com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#include "stdafx.h"
+#include "Logger.h"
+
+#include <boost/algorithm/string/replace.hpp>
+#include "../liblogger/TMultiLoggerConfig.h"
+#include "../liblogger/TAsyncMultiLogger.h"
+
+namespace
+{
+	struct LoggerInfo
+	{
+		std::wstring strLogPath;
+		DWORD dwMinLogLevel = 0;
+	};
+
+	bool ReadLoggerConfig(LoggerInfo& rInfo)
+	{
+		HKEY hKeyShellExt = nullptr;
+		LSTATUS lStatus = RegOpenKeyEx(HKEY_CURRENT_USER, _T("SOFTWARE\\CopyHandler\\ShellExtension"), 0, KEY_QUERY_VALUE, &hKeyShellExt);
+		if(lStatus != ERROR_SUCCESS)
+			return false;
+
+		// log path
+		DWORD dwType = REG_SZ;
+		const DWORD stMaxBuffer = 1024;
+		std::unique_ptr<wchar_t[]> buf(new wchar_t[stMaxBuffer]);
+
+		DWORD dwCount = stMaxBuffer;
+		lStatus = RegQueryValueEx(hKeyShellExt, L"LogPath", nullptr, &dwType, (BYTE*)buf.get(), &dwCount);
+		if(lStatus != ERROR_SUCCESS)
+		{
+			RegCloseKey(hKeyShellExt);
+			return false;
+		}
+
+		buf[ dwCount / 2 ] = L'\0';
+		rInfo.strLogPath = buf.get();
+
+		// log level
+		dwType = REG_DWORD;
+		dwCount = sizeof(DWORD);
+		DWORD dwValue = 0;
+		lStatus = RegQueryValueEx(hKeyShellExt, L"MinLogLevel", nullptr, &dwType, (BYTE*)&dwValue, &dwCount);
+		if(lStatus != ERROR_SUCCESS)
+		{
+			RegCloseKey(hKeyShellExt);
+			return false;
+		}
+
+		rInfo.dwMinLogLevel = dwValue;
+
+		RegCloseKey(hKeyShellExt);
+
+		return true;
+	}
+
+	logger::TLogFileDataPtr CreateLoggerData()
+	{
+		LoggerInfo li;
+		if(ReadLoggerConfig(li))
+		{
+			logger::TMultiLoggerConfigPtr spConfig(std::make_shared<logger::TMultiLoggerConfig>());
+			spConfig->SetLogLevel(L"default", (logger::ESeverityLevel)li.dwMinLogLevel);
+
+			DWORD dwProcessId = GetProcessId(GetCurrentProcess());
+			boost::replace_all(li.strLogPath, L"%pid%", boost::lexical_cast<std::wstring>(dwProcessId));
+
+			return logger::TAsyncMultiLogger::GetInstance()->CreateLoggerData(li.strLogPath.c_str(), spConfig);
+		}
+
+		logger::TLogFileDataPtr spLogData(std::make_shared<logger::TLogFileData>());
+		return spLogData;
+	}
+}
+
+logger::TLoggerPtr GetLogger(PCTSTR pszChannel)
+{
+	static logger::TLogFileDataPtr spLogFileData = CreateLoggerData();
+	return logger::MakeLogger(spLogFileData, pszChannel);
+}
Index: src/chext/Logger.h
===================================================================
diff -u -N
--- src/chext/Logger.h	(revision 0)
+++ src/chext/Logger.h	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -0,0 +1,62 @@
+// ============================================================================
+//  Copyright (C) 2001-2015 by Jozef Starosczyk
+//  ixen@copyhandler.com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#ifndef __LOGGER_H__
+#define __LOGGER_H__
+
+#include "HResultFormatter.h"
+#include "../liblogger/SeverityLevels.h"
+#include "../liblogger/TLogger.h"
+
+// logging helpers
+namespace details
+{
+	inline logger::ESeverityLevel HRESULT2Severity(HRESULT hResult)
+	{
+		return (SUCCEEDED(hResult)) ? logger::debug : logger::error;
+	}
+}
+
+logger::TLoggerPtr GetLogger(PCTSTR pszChannel);
+
+#define LOG_HRESULT(lg, hr)\
+	LOG(lg, details::HRESULT2Severity(hr)) << L" <" << HResultFormatter::FormatHResult(hr) << L"> "
+
+#define LOG_PARAM(param)\
+	#param << "=" << param
+
+#define LOG_PARAMS2(a1, a2)\
+	LOG_PARAM(a1) << ", " << LOG_PARAM(a2)
+#define LOG_PARAMS3(a1, a2, a3)\
+	LOG_PARAMS2(a1, a2) << ", " << LOG_PARAM(a3)
+#define LOG_PARAMS4(a1, a2, a3, a4)\
+	LOG_PARAMS3(a1, a2, a3) << ", " << LOG_PARAM(a4)
+#define LOG_PARAMS5(a1, a2, a3, a4, a5)\
+	LOG_PARAMS4(a1, a2, a3, a4) << ", " << LOG_PARAM(a5)
+#define LOG_PARAMS6(a1, a2, a3, a4, a5, a6)\
+	LOG_PARAMS5(a1, a2, a3, a4, a5) << ", " << LOG_PARAM(a6)
+#define LOG_PARAMS7(a1, a2, a3, a4, a5, a6, a7)\
+	LOG_PARAMS6(a1, a2, a3, a4, a5, a6) << ", " << LOG_PARAM(a7)
+#define LOG_PARAMS8(a1, a2, a3, a4, a5, a6, a7, a8)\
+	LOG_PARAMS7(a1, a2, a3, a4, a5, a6, a7) << ", " << LOG_PARAM(a8)
+#define LOG_PARAMS9(a1, a2, a3, a4, a5, a6, a7, a8, a9)\
+	LOG_PARAMS8(a1, a2, a3, a4, a5, a6, a7, a8) << ", " << LOG_PARAM(a9)
+#define LOG_PARAMS10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)\
+	LOG_PARAMS9(a1, a2, a3, a4, a5, a6, a7, a8, a9) << ", " << LOG_PARAM(a10)
+
+#endif
Index: src/chext/TLogger.h
===================================================================
diff -u -N
--- src/chext/TLogger.h	(revision bfc7a8378a96c5b58def559b343918fca32f05a6)
+++ src/chext/TLogger.h	(revision 0)
@@ -1,69 +0,0 @@
-// ============================================================================
-//  Copyright (C) 2001-2015 by Jozef Starosczyk
-//  ixen@copyhandler.com
-//
-//  This program is free software; you can redistribute it and/or modify
-//  it under the terms of the GNU Library General Public License
-//  (version 2) as published by the Free Software Foundation;
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU Library General Public
-//  License along with this program; if not, write to the
-//  Free Software Foundation, Inc.,
-//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// ============================================================================
-#ifndef __TLOGGER_H__
-#define __TLOGGER_H__
-
-#include <boost/log/sources/global_logger_storage.hpp>
-#include <boost/log/sources/severity_logger.hpp>
-#include <boost/log/trivial.hpp>
-#include <boost/log/attributes/named_scope.hpp>
-#include "HResultFormatter.h"
-
-// ugly way to include severity_level in the global namespace
-using namespace boost::log::trivial;
-
-typedef boost::log::sources::wseverity_logger_mt<severity_level> TLogger;
-
-BOOST_LOG_GLOBAL_LOGGER(Logger, TLogger)
-
-// logging helpers
-namespace details
-{
-	inline severity_level HRESULT2Severity(HRESULT hResult)
-	{
-		return (SUCCEEDED(hResult)) ? debug : error;
-	}
-}
-
-#define BOOST_LOG_HRESULT(lg, hr)\
-	BOOST_LOG_SEV(lg, details::HRESULT2Severity(hr)) << L" <" << HResultFormatter::FormatHResult(hr) << L"> "
-
-#define LOG_PARAM(param)\
-	#param << "=" << param
-
-#define LOG_PARAMS2(a1, a2)\
-	LOG_PARAM(a1) << ", " << LOG_PARAM(a2)
-#define LOG_PARAMS3(a1, a2, a3)\
-	LOG_PARAMS2(a1, a2) << ", " << LOG_PARAM(a3)
-#define LOG_PARAMS4(a1, a2, a3, a4)\
-	LOG_PARAMS3(a1, a2, a3) << ", " << LOG_PARAM(a4)
-#define LOG_PARAMS5(a1, a2, a3, a4, a5)\
-	LOG_PARAMS4(a1, a2, a3, a4) << ", " << LOG_PARAM(a5)
-#define LOG_PARAMS6(a1, a2, a3, a4, a5, a6)\
-	LOG_PARAMS5(a1, a2, a3, a4, a5) << ", " << LOG_PARAM(a6)
-#define LOG_PARAMS7(a1, a2, a3, a4, a5, a6, a7)\
-	LOG_PARAMS6(a1, a2, a3, a4, a5, a6) << ", " << LOG_PARAM(a7)
-#define LOG_PARAMS8(a1, a2, a3, a4, a5, a6, a7, a8)\
-	LOG_PARAMS7(a1, a2, a3, a4, a5, a6, a7) << ", " << LOG_PARAM(a8)
-#define LOG_PARAMS9(a1, a2, a3, a4, a5, a6, a7, a8, a9)\
-	LOG_PARAMS8(a1, a2, a3, a4, a5, a6, a7, a8) << ", " << LOG_PARAM(a9)
-#define LOG_PARAMS10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)\
-	LOG_PARAMS9(a1, a2, a3, a4, a5, a6, a7, a8, a9) << ", " << LOG_PARAM(a10)
-
-#endif
Index: src/chext/MenuExt.cpp
===================================================================
diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/MenuExt.cpp	(.../MenuExt.cpp)	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/chext/MenuExt.cpp	(.../MenuExt.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -29,7 +29,7 @@
 #include "../libchcore/TTaskDefinition.h"
 #include <boost/numeric/conversion/cast.hpp>
 #include "ShellExtensionVerifier.h"
-#include "TLogger.h"
+#include "Logger.h"
 
 // globals
 static void CutAmpersands(LPTSTR lpszString)
@@ -50,13 +50,11 @@
 /////////////////////////////////////////////////////////////////////////////
 // CMenuExt
 CMenuExt::CMenuExt() :
-	m_piShellExtControl(nullptr)
+	m_piShellExtControl(nullptr),
+	m_spLog(GetLogger(L"CMenuExt"))
 {
-	BOOST_LOG_FUNC();
-
 	HRESULT hResult = CoCreateInstance(CLSID_CShellExtControl, nullptr, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl);
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_HRESULT(rLogger, hResult) << LOG_PARAM(m_piShellExtControl);
+	LOG_HRESULT(m_spLog, hResult) << L"Creation of ShellExtControl " << LOG_PARAM(m_piShellExtControl);
 }
 
 CMenuExt::~CMenuExt()
@@ -70,14 +68,11 @@
 
 STDMETHODIMP CMenuExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject* piDataObject, HKEY /*hkeyProgID*/)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Initializing";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	if(!pidlFolder && !piDataObject)
 	{
-		BOOST_LOG_SEV(rLogger, error) << L"Missing both pointers.";
+		LOG_ERROR(m_spLog) << L"Missing both pointers.";
 		return E_INVALIDARG;
 	}
 
@@ -87,21 +82,21 @@
 		return S_OK;
 
 	HRESULT hResult = ReadShellConfig();
+	LOG_HRESULT(m_spLog, hResult) << L"Read shell config";
+
 	if(SUCCEEDED(hResult))
+	{
 		hResult = m_tShellExtData.GatherDataFromInitialize(pidlFolder, piDataObject);
+		LOG_HRESULT(m_spLog, hResult) << L"Gather data from initialize";
+	}
 
-	BOOST_LOG_HRESULT(rLogger, hResult) << L"";
-
 	return hResult;
 }
 
 STDMETHODIMP CMenuExt::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Querying context menu";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	// check options
 	HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl);
 	if(!hWnd)
@@ -156,11 +151,8 @@
 
 STDMETHODIMP CMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Invoking command";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	// textual verbs are not supported by this extension
 	if(HIWORD(lpici->lpVerb) != 0)
 		return E_FAIL;
@@ -218,11 +210,8 @@
 
 HRESULT CMenuExt::HandleMenuMsg2(UINT uMsg, WPARAM /*wParam*/, LPARAM lParam, LRESULT* /*plResult*/)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Handle menu message (2)";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	switch(uMsg)
 	{
 	case WM_INITMENUPOPUP:
@@ -279,14 +268,11 @@
 
 HRESULT CMenuExt::DrawMenuItem(LPDRAWITEMSTRUCT lpdis)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Drawing menu item";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	if(!lpdis)
 	{
-		BOOST_LOG_SEV(rLogger, error) << L"Missing argument";
+		LOG_ERROR(m_spLog) << L"Missing argument";
 		return E_FAIL;
 	}
 
@@ -346,11 +332,8 @@
 
 STDMETHODIMP CMenuExt::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Retrieving command string for cmd " << idCmd;
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	memset(pszName, 0, cchMax);
 
 	if(uFlags != GCS_HELPTEXTW && uFlags != GCS_HELPTEXTA)
@@ -388,10 +371,6 @@
 
 HRESULT CMenuExt::ReadShellConfig()
 {
-	BOOST_LOG_FUNC();
-
-	TLogger& rLogger = Logger::get();
-
 	try
 	{
 		HWND hWnd = ShellExtensionVerifier::VerifyShellExt(m_piShellExtControl);
@@ -402,7 +381,7 @@
 		unsigned long ulSHMID = GetTickCount();
 		if(::SendMessage(hWnd, WM_GETCONFIG, eLocation_ContextMenu, ulSHMID) != TRUE)
 		{
-			BOOST_LOG_SEV(rLogger, error) << L"Failed to retrieve configuration from Copy Handler";
+			LOG_ERROR(m_spLog) << L"Failed to retrieve configuration from Copy Handler";
 			return E_FAIL;
 		}
 
Index: src/chext/MenuExt.h
===================================================================
diff -u -N -r633a533cb6e741d44fe28aa56339e1d2709b1b27 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/MenuExt.h	(.../MenuExt.h)	(revision 633a533cb6e741d44fe28aa56339e1d2709b1b27)
+++ src/chext/MenuExt.h	(.../MenuExt.h)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -23,6 +23,7 @@
 #include "TContextMenuHandler.h"
 #include "..\common\TShellExtMenuConfig.h"
 #include "TShellExtData.h"
+#include "..\liblogger\TLogger.h"
 
 class TShellMenuItem;
 
@@ -71,6 +72,7 @@
 	TContextMenuHandler m_tContextMenuHandler;
 
 	IShellExtControl* m_piShellExtControl;
+	logger::TLoggerPtr m_spLog;
 };
 
 #endif //__MENUEXT_H_
Index: src/chext/ShellExtControl.cpp
===================================================================
diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/ShellExtControl.cpp	(.../ShellExtControl.cpp)	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/chext/ShellExtControl.cpp	(.../ShellExtControl.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -21,30 +21,28 @@
 #include <comutil.h>
 #include "ShellExtControl.h"
 #include "../common/version.h"
-#include "TLogger.h"
+#include "Logger.h"
 
 CShellExtControl::CShellExtControl() :
 	m_pShellExtData(nullptr),
 	m_hMemory(nullptr),
-	m_hMutex(nullptr)
+	m_hMutex(nullptr),
+	m_spLog(GetLogger(L"ShellExtControl"))
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Constructing CShellExtControl";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	// create protection mutex
 	m_hMutex = ::CreateMutex(nullptr, FALSE, _T("CHShellExtControlDataMutex"));
 	if(!m_hMutex)
 	{
-		BOOST_LOG_SEV(rLogger, error) << L"Cannot create mutex.";
+		LOG_ERROR(m_spLog) << L"Cannot create mutex.";
 		return;
 	}
 
 	DWORD dwRes = WaitForSingleObject(m_hMutex, 10000);
 	if(dwRes != WAIT_OBJECT_0)
 	{
-		BOOST_LOG_SEV(rLogger, error) << L"Timeout or fail waiting for mutex.";
+		LOG_ERROR(m_spLog) << L"Timeout or fail waiting for mutex.";
 		ReleaseMutex(m_hMutex);
 		return;
 	}
@@ -54,7 +52,7 @@
 	DWORD dwLastError = GetLastError();	// NOTE: last error is needed also for success case (for already exists status)
 	if(!m_hMemory)
 	{
-		BOOST_LOG_HRESULT(rLogger, dwLastError) << L"Cannot create file mapping.";
+		LOG_HRESULT(m_spLog, dwLastError) << L"Cannot create file mapping.";
 		ReleaseMutex(m_hMutex);
 		CloseHandle(m_hMutex);
 		return;
@@ -65,7 +63,7 @@
 	{
 		DWORD dwError = GetLastError();		// NOTE: do not overwrite dwLastError, as the value is needed later
 
-		BOOST_LOG_HRESULT(rLogger, dwError) << L"Cannot map view of file.";
+		LOG_HRESULT(m_spLog, dwError) << L"Cannot map view of file.";
 		ReleaseMutex(m_hMutex);
 		CloseHandle(m_hMutex);
 		CloseHandle(m_hMemory);
@@ -77,11 +75,11 @@
 	{
 		if(dwLastError == ERROR_SUCCESS)
 		{
-			BOOST_LOG_SEV(rLogger, debug) << L"Copy Handler is not running. Disabling shell extension.";
+			LOG_DEBUG(m_spLog) << L"Copy Handler is not running. Disabling shell extension.";
 		}
 		else
 		{
-			BOOST_LOG_HRESULT(rLogger, dwLastError) << L"Copy Handler is not running. Disabling shell extension.";
+			LOG_HRESULT(m_spLog, dwLastError) << L"Copy Handler is not running. Disabling shell extension.";
 		}
 		m_pShellExtData->m_lFlags = 0;
 		m_pShellExtData->m_lID = GetTickCount();
@@ -106,48 +104,42 @@
 
 STDMETHODIMP CShellExtControl::GetVersion(LONG* plVersion, BSTR* pbstrVersion)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << "Retrieving version";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << "";
-
 	if(!plVersion || !pbstrVersion || (*pbstrVersion))
 	{
-		BOOST_LOG_SEV(rLogger, error) << "Invalid arguments.";
+		LOG_ERROR(m_spLog) << "Invalid arguments.";
 		return E_INVALIDARG;
 	}
 
 	(*plVersion) = PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4;
 	_bstr_t strVer(SHELLEXT_PRODUCT_FULL_VERSION);
 	*pbstrVersion = strVer.Detach();
 
-	BOOST_LOG_SEV(rLogger, debug) << LOG_PARAMS2(*plVersion, *pbstrVersion);
+	LOG_DEBUG(m_spLog) << LOG_PARAMS2(*plVersion, *pbstrVersion);
 
 	return S_OK;
 }
 
 STDMETHODIMP CShellExtControl::SetFlags(LONG lFlags, LONG lMask)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << L"Setting flags: " << LOG_PARAMS2(lFlags, lMask);
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << LOG_PARAMS2(lFlags, lMask);
-
 	if(!m_hMutex || !m_pShellExtData)
 	{
-		BOOST_LOG_SEV(rLogger, error) << "Wrong internal state.";
+		LOG_ERROR(m_spLog) << "Wrong internal state.";
 		return E_FAIL;
 	}
 
 	DWORD dwRes = WaitForSingleObject(m_hMutex, 10000);
 	if(dwRes != WAIT_OBJECT_0)
 	{
-		BOOST_LOG_SEV(rLogger, error) << "Failed waiting for mutex.";
+		LOG_ERROR(m_spLog) << "Failed waiting for mutex.";
 		return E_FAIL;
 	}
 	m_pShellExtData->m_lFlags = (m_pShellExtData->m_lFlags & ~lMask) | (lFlags & lMask);
 
-	BOOST_LOG_SEV(rLogger, debug) << LOG_PARAM(m_pShellExtData->m_lFlags);
+	LOG_DEBUG(m_spLog) << L"Set flags: " << LOG_PARAM(m_pShellExtData->m_lFlags);
 
 	ReleaseMutex(m_hMutex);
 
@@ -156,33 +148,30 @@
 
 STDMETHODIMP CShellExtControl::GetFlags(LONG* plFlags)
 {
-	BOOST_LOG_FUNC();
+	LOG_DEBUG(m_spLog) << "Retrieving flags";
 
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << "";
-
 	if(!m_hMutex || !m_pShellExtData)
 	{
-		BOOST_LOG_SEV(rLogger, error) << "Wrong internal state.";
+		LOG_ERROR(m_spLog) << "Wrong internal state.";
 		return E_FAIL;
 	}
 
 	if(!plFlags)
 	{
-		BOOST_LOG_SEV(rLogger, error) << "Invalid argument.";
+		LOG_ERROR(m_spLog) << "Invalid argument.";
 		return E_INVALIDARG;
 	}
 
 	DWORD dwRes = WaitForSingleObject(m_hMutex, 10000);
 	if(dwRes != WAIT_OBJECT_0)
 	{
-		BOOST_LOG_SEV(rLogger, error) << "Failed waiting for mutex.";
+		LOG_ERROR(m_spLog) << "Failed waiting for mutex.";
 		return E_FAIL;
 	}
 
 	(*plFlags) = m_pShellExtData->m_lFlags;
 
-	BOOST_LOG_SEV(rLogger, debug) << "Returning flags. " << LOG_PARAM(m_pShellExtData->m_lFlags);
+	LOG_DEBUG(m_spLog) << "Returning flags: " << LOG_PARAM(m_pShellExtData->m_lFlags);
 
 	ReleaseMutex(m_hMutex);
 
Index: src/chext/ShellExtControl.h
===================================================================
diff -u -N -rd5c3edd0d167db9b5d47d04248820fda49499a5e -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/ShellExtControl.h	(.../ShellExtControl.h)	(revision d5c3edd0d167db9b5d47d04248820fda49499a5e)
+++ src/chext/ShellExtControl.h	(.../ShellExtControl.h)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -20,6 +20,7 @@
 #define __SHELLEXTCONTROL_H_
 
 #include "resource.h"       // main symbols
+#include "..\liblogger\TLogger.h"
 
 /////////////////////////////////////////////////////////////////////////////
 // CDropMenuExt
@@ -55,6 +56,7 @@
 	} *m_pShellExtData;
 
 	CComAutoCriticalSection m_lock;
+	logger::TLoggerPtr m_spLog;
 };
 
 #endif //__SHELLEXTCONTROL_H_
Index: src/chext/ShellExtensionVerifier.cpp
===================================================================
diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/ShellExtensionVerifier.cpp	(.../ShellExtensionVerifier.cpp)	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/chext/ShellExtensionVerifier.cpp	(.../ShellExtensionVerifier.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -18,24 +18,24 @@
 // ============================================================================
 #include "stdafx.h"
 #include "ShellExtensionVerifier.h"
-#include "TLogger.h"
+#include "Logger.h"
 
 HWND ShellExtensionVerifier::VerifyShellExt(IShellExtControl* piShellExtControl)
 {
-	TLogger& rLogger = Logger::get();
+	logger::TLoggerPtr rLogger = GetLogger(L"ShellExtVerifier");
 
 	HRESULT hResult = IsShellExtEnabled(piShellExtControl);
 	if(FAILED(hResult) || hResult == S_FALSE)
 	{
-		BOOST_LOG_SEV(rLogger, debug) << L"Shell extension is disabled.";
+		LOG_DEBUG(rLogger) << L"Shell extension is disabled.";
 		return nullptr;
 	}
 
 	// find CH's window
 	HWND hWnd = ::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler"));
 	if(!hWnd)
 	{
-		BOOST_LOG_SEV(rLogger, debug) << L"Cannot find Copy Handler's window.";
+		LOG_DEBUG(rLogger) << L"Cannot find Copy Handler's window.";
 		return nullptr;
 	}
 
@@ -54,6 +54,6 @@
 
 	if(lFlags & eShellExt_Enabled)
 		return S_OK;
-	else
-		return S_FALSE;
+	
+	return S_FALSE;
 }
Index: src/chext/TLogger.cpp
===================================================================
diff -u -N
--- src/chext/TLogger.cpp	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/chext/TLogger.cpp	(revision 0)
@@ -1,137 +0,0 @@
-// ============================================================================
-//  Copyright (C) 2001-2015 by Jozef Starosczyk
-//  ixen@copyhandler.com
-//
-//  This program is free software; you can redistribute it and/or modify
-//  it under the terms of the GNU Library General Public License
-//  (version 2) as published by the Free Software Foundation;
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU Library General Public
-//  License along with this program; if not, write to the
-//  Free Software Foundation, Inc.,
-//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// ============================================================================
-#include "stdafx.h"
-#include "TLogger.h"
-
-#include <boost/log/core.hpp>
-#include <boost/log/trivial.hpp>
-#include <boost/log/expressions.hpp>
-#include <boost/log/sinks/text_file_backend.hpp>
-#include <boost/log/utility/setup/file.hpp>
-#include <boost/log/utility/setup/common_attributes.hpp>
-#include <boost/log/sources/record_ostream.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <boost/log/support/date_time.hpp>
-#include <boost/log/support/exception.hpp>
-#include <boost/locale.hpp>
-
-namespace logging = boost::log;
-namespace src = boost::log::sources;
-namespace sinks = boost::log::sinks;
-namespace keywords = boost::log::keywords;
-namespace expr = boost::log::expressions;
-namespace attrs = boost::log::attributes;
-
-namespace
-{
-	struct LoggerInfo
-	{
-		std::wstring strLogPath;
-		DWORD dwMinLogLevel = 0;
-	};
-
-	bool ReadLoggerConfig(LoggerInfo& rInfo)
-	{
-		HKEY hKeyShellExt = nullptr;
-		LSTATUS lStatus = RegOpenKeyEx(HKEY_CURRENT_USER, _T("SOFTWARE\\CopyHandler\\ShellExtension"), 0, KEY_QUERY_VALUE, &hKeyShellExt);
-		if(lStatus != ERROR_SUCCESS)
-			return false;
-
-		// log path
-		DWORD dwType = REG_SZ;
-		const DWORD stMaxBuffer = 1024;
-		std::unique_ptr<wchar_t[]> buf(new wchar_t[stMaxBuffer]);
-
-		DWORD dwCount = stMaxBuffer;
-		lStatus = RegQueryValueEx(hKeyShellExt, L"LogPath", nullptr, &dwType, (BYTE*)buf.get(), &dwCount);
-		if(lStatus != ERROR_SUCCESS)
-		{
-			RegCloseKey(hKeyShellExt);
-			return false;
-		}
-
-		buf[ dwCount / 2 ] = L'\0';
-		rInfo.strLogPath = buf.get();
-
-		// log level
-		dwType = REG_DWORD;
-		dwCount = sizeof(DWORD);
-		DWORD dwValue = 0;
-		lStatus = RegQueryValueEx(hKeyShellExt, L"MinLogLevel", nullptr, &dwType, (BYTE*)&dwValue, &dwCount);
-		if(lStatus != ERROR_SUCCESS)
-		{
-			RegCloseKey(hKeyShellExt);
-			return false;
-		}
-
-		rInfo.dwMinLogLevel = dwValue;
-
-		RegCloseKey(hKeyShellExt);
-
-		return true;
-	}
-}
-
-BOOST_LOG_GLOBAL_LOGGER_INIT(Logger, TLogger)
-{
-	LoggerInfo li;
-	if(ReadLoggerConfig(li))
-	{
-		DWORD dwProcessId = GetProcessId(GetCurrentProcess());
-		boost::replace_all(li.strLogPath, L"%pid%", boost::lexical_cast<std::wstring>(dwProcessId));
-
-		logging::add_common_attributes();
-		logging::core::get()->add_global_attribute("Scope", attrs::named_scope());
-
-		auto sink = logging::add_file_log(
-			keywords::file_name = li.strLogPath,
-			keywords::rotation_size = 10 * 1024 * 1024,
-			keywords::open_mode = (std::ios::out | std::ios::app),
-			keywords::format =
-			(
-				expr::stream 
-					<< expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "[%Y-%m-%d %H:%M:%S]")
-					<< "[" << severity << "]: "
-					<< expr::wmessage
-					<< expr::if_(expr::has_attr("Scope"))
-					[
-						expr::stream
-						<< " ("
-						<< expr::format_named_scope("Scope",
-							keywords::format = "%n",
-							keywords::depth = 1,
-							keywords::iteration = expr::forward)
-						<< ")"
-					]
-			)
-		);
-
-		std::locale loc = boost::locale::generator()("en_EN.UTF-8");
-		sink->imbue(loc);
-
-		severity_level eSeverity = (severity_level)li.dwMinLogLevel;
-		logging::core::get()->set_filter(
-			severity >= eSeverity
-		);
-	}
-
-	boost::log::sources::wseverity_logger_mt<severity_level> lg;
-	return lg;
-}
Index: src/chext/chext.cpp
===================================================================
diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/chext.cpp	(.../chext.cpp)	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/chext/chext.cpp	(.../chext.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -24,23 +24,16 @@
 #include "resource.h"
 #include "chext.h"
 #include "dllmain.h"
-#include "TLogger.h"
+#include "Logger.h"
 #include "GuidFormatter.h"
 
 /////////////////////////////////////////////////////////////////////////////
 // Used to determine whether the DLL can be unloaded by OLE
 
 STDAPI DllCanUnloadNow()
 {
-	BOOST_LOG_FUNC();
-
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	HRESULT hResult = _AtlModule.DllCanUnloadNow();
 
-	BOOST_LOG_HRESULT(rLogger, hResult) << L"";
-
 	return hResult;
 }
 
@@ -49,15 +42,8 @@
 
 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
 {
-	BOOST_LOG_FUNC();
-
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	HRESULT hResult = _AtlModule.DllGetClassObject(rclsid, riid, ppv);
 
-	BOOST_LOG_HRESULT(rLogger, hResult) << L"clsid=" << GuidFormatter::FormatGuid(rclsid) << ", riid=" << GuidFormatter::FormatGuid(riid) << ", ppv=" << ppv;
-
 	return hResult;
 }
 
@@ -66,16 +52,9 @@
 
 STDAPI DllRegisterServer()
 {
-	BOOST_LOG_FUNC();
-
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	// registers object, typelib and all interfaces in typelib
 	HRESULT hResult = _AtlModule.DllRegisterServer();
 
-	BOOST_LOG_HRESULT(rLogger, hResult) << L"";
-
 	return hResult;
 }
 
@@ -84,28 +63,15 @@
 
 STDAPI DllUnregisterServer()
 {
-	BOOST_LOG_FUNC();
-
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
 	HRESULT hResult = _AtlModule.DllUnregisterServer();
 
-	BOOST_LOG_HRESULT(rLogger, hResult) << L"";
-
 	return hResult;
 }
 
 // DllInstall - Adds/Removes entries to the system registry per user
 //              per machine.	
 STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
 {
-	BOOST_LOG_FUNC();
-
-	TLogger& rLogger = Logger::get();
-	BOOST_LOG_SEV(rLogger, debug) << L"";
-
-	HRESULT hr = E_FAIL;
 	static const wchar_t szUserSwitch[] = _T("user");
 
 	if (pszCmdLine != nullptr)
@@ -114,23 +80,15 @@
 			AtlSetPerUserRegistration(true);
 	}
 
+	HRESULT hResult = E_FAIL;
 	if (bInstall)
 	{
-		hr = DllRegisterServer();
-		if (FAILED(hr))
+		hResult = DllRegisterServer();
+		if (FAILED(hResult))
 			DllUnregisterServer();
 	}
 	else
-		hr = DllUnregisterServer();
+		hResult = DllUnregisterServer();
 
-	if(pszCmdLine)
-	{
-		BOOST_LOG_HRESULT(rLogger, hr) << LOG_PARAMS2(bInstall, pszCmdLine);
-	}
-	else
-	{
-		BOOST_LOG_HRESULT(rLogger, hr) << LOG_PARAM(bInstall);
-	}
-
-	return hr;
+	return hResult;
 }
Index: src/chext/chext.vc140.vcxproj
===================================================================
diff -u -N -r4a481bbe77043e0bda2435c6d62a02700b3e46c5 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/chext.vc140.vcxproj	(.../chext.vc140.vcxproj)	(revision 4a481bbe77043e0bda2435c6d62a02700b3e46c5)
+++ src/chext/chext.vc140.vcxproj	(.../chext.vc140.vcxproj)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -553,7 +553,7 @@
     <ClCompile Include="ShellExtensionVerifier.cpp" />
     <ClCompile Include="ShellPathsHelpers.cpp" />
     <ClCompile Include="TContextMenuHandler.cpp" />
-    <ClCompile Include="TLogger.cpp" />
+    <ClCompile Include="Logger.cpp" />
     <ClCompile Include="TShellExtData.cpp" />
     <ClCompile Include="..\common\TShellExtMenuConfig.cpp" />
     <ClCompile Include="chext.cpp" />
@@ -596,7 +596,7 @@
     <ClInclude Include="ShellExtensionVerifier.h" />
     <ClInclude Include="ShellPathsHelpers.h" />
     <ClInclude Include="TContextMenuHandler.h" />
-    <ClInclude Include="TLogger.h" />
+    <ClInclude Include="Logger.h" />
     <ClInclude Include="TShellExtData.h" />
     <ClInclude Include="..\common\ipcstructs.h" />
     <ClInclude Include="..\common\TShellExtMenuConfig.h" />
@@ -654,6 +654,9 @@
     <ProjectReference Include="..\libchcore\libchcore.vc140.vcxproj">
       <Project>{cbbf380b-7b16-4a1e-8194-758dad7d8011}</Project>
     </ProjectReference>
+    <ProjectReference Include="..\liblogger\liblogger.vc140.vcxproj">
+      <Project>{df9957d4-3d95-4ac3-ad3f-dcbea058f79d}</Project>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
Index: src/chext/chext.vc140.vcxproj.filters
===================================================================
diff -u -N -r3d1de44762647618faf9b5b3a87f89b293899d8d -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/chext.vc140.vcxproj.filters	(.../chext.vc140.vcxproj.filters)	(revision 3d1de44762647618faf9b5b3a87f89b293899d8d)
+++ src/chext/chext.vc140.vcxproj.filters	(.../chext.vc140.vcxproj.filters)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -65,9 +65,6 @@
     <ClCompile Include="..\..\tests\tests_shared\TestsExports.cpp">
       <Filter>Tests</Filter>
     </ClCompile>
-    <ClCompile Include="TLogger.cpp">
-      <Filter>Source Files\Tools</Filter>
-    </ClCompile>
     <ClCompile Include="GuidFormatter.cpp">
       <Filter>Source Files\Tools</Filter>
     </ClCompile>
@@ -77,6 +74,9 @@
     <ClCompile Include="HResultFormatter.cpp">
       <Filter>Source Files\Tools</Filter>
     </ClCompile>
+    <ClCompile Include="Logger.cpp">
+      <Filter>Source Files\Tools</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="DropMenuExt.h">
@@ -115,9 +115,6 @@
     <ClInclude Include="resource.h">
       <Filter>Resource Files</Filter>
     </ClInclude>
-    <ClInclude Include="TLogger.h">
-      <Filter>Source Files\Tools</Filter>
-    </ClInclude>
     <ClInclude Include="GuidFormatter.h">
       <Filter>Source Files\Tools</Filter>
     </ClInclude>
@@ -127,6 +124,9 @@
     <ClInclude Include="HResultFormatter.h">
       <Filter>Source Files\Tools</Filter>
     </ClInclude>
+    <ClInclude Include="Logger.h">
+      <Filter>Source Files\Tools</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="chext.def">
Index: src/chext/dllmain.cpp
===================================================================
diff -u -N -r8068e0c351055554340ac9755d1bc846893bf2b8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/chext/dllmain.cpp	(.../dllmain.cpp)	(revision 8068e0c351055554340ac9755d1bc846893bf2b8)
+++ src/chext/dllmain.cpp	(.../dllmain.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -4,7 +4,6 @@
 #include "MenuExt.h"
 #include "DropMenuExt.h"
 #include "ShellExtControl.h"
-#include "TLogger.h"
 
 CCHExtModule _AtlModule;
 
@@ -15,31 +14,8 @@
 extern "C"
 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
 {
-	if (dwReason == DLL_PROCESS_ATTACH)
-	{
+	if(dwReason == DLL_PROCESS_ATTACH)
 		DisableThreadLibraryCalls(hInstance);
 
-		try
-		{
-			TLogger lg;
-			BOOST_LOG_SEV(lg, debug) << L"DllMain - attaching to process: " << hInstance << L", " << dwReason << L", " << lpReserved;
-		}
-		catch (const std::exception&)
-		{
-		}
-	}
-	else if (dwReason == DLL_PROCESS_DETACH)
-	{
-		try
-		{
-			TLogger lg;
-			BOOST_LOG_SEV(lg, debug) << L"DllMain - detaching from process: " << hInstance << L", " << dwReason << L", " << lpReserved;
-		}
-		catch (const std::exception&)
-		{
-
-		}
-	}
-
 	return _AtlModule.DllMain(dwReason, lpReserved);
 }
Index: src/liblogger/TAsyncMultiLogger.cpp
===================================================================
diff -u -N -ra08ca9e12d93e9a036a5cf739348ff3ef2a58be8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/liblogger/TAsyncMultiLogger.cpp	(.../TAsyncMultiLogger.cpp)	(revision a08ca9e12d93e9a036a5cf739348ff3ef2a58be8)
+++ src/liblogger/TAsyncMultiLogger.cpp	(.../TAsyncMultiLogger.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -32,32 +32,33 @@
 
 	TAsyncMultiLogger::TAsyncMultiLogger() :
 		m_spStopEvent(CreateEvent(nullptr, TRUE, FALSE, nullptr), CloseHandle),
+		m_spStoppedEvent(CreateEvent(nullptr, TRUE, TRUE, nullptr), CloseHandle),
 		m_spGlobalRotationInfo(std::make_shared<TLoggerRotationInfo>())
 	{
 		if (!m_spStopEvent)
 			throw std::runtime_error("Cannot create stop event");
 	}
 
-	void TAsyncMultiLogger::FinishLogging()
+	TAsyncMultiLogger::~TAsyncMultiLogger()
 	{
-		std::unique_ptr<std::thread> spThread;
+		FinishLogging();
+	}
 
+	void TAsyncMultiLogger::FinishLogging()
+	{
+		SetEvent(m_spStopEvent.get());
+		if(m_hThread)
 		{
-			boost::unique_lock<boost::shared_mutex> lock(m_mutex);
-			SetEvent(m_spStopEvent.get());
-			std::swap(m_spThread, spThread);
-		}
+			WaitForSingleObject(m_spStoppedEvent.get(), INFINITE);
 
-		if(spThread)
-		{
-			if(spThread->joinable())
-				spThread->join();
+			// NOTE: for some unknown reason we can't wait for the thread event in shell extension even when the thread
+			// exited successfully. For that reason we're synchronizing thread exit with m_spStoppedEvent.
+			//WaitForSingleObject(m_hThread, INFINITE);
+			CloseHandle(m_hThread);
+			m_hThread = nullptr;
 		}
 
-		{
-			boost::unique_lock<boost::shared_mutex> lock(m_mutex);
-			m_setLoggerData.clear();
-		}
+		m_setLoggerData.clear();
 	}
 
 	TLogFileDataPtr TAsyncMultiLogger::CreateLoggerData(PCTSTR pszLogPath, const TMultiLoggerConfigPtr& spLoggerConfig)
@@ -67,8 +68,8 @@
 		boost::unique_lock<boost::shared_mutex> lock(m_mutex);
 		m_setLoggerData.insert(spLogFileData);
 
-		if(!m_spThread)
-			m_spThread.reset(new std::thread(&TAsyncMultiLogger::LoggingThread, this));
+		if(!m_hThread)
+			m_hThread = CreateThread(nullptr, 0, &LoggingThread, this, 0, nullptr);
 
 		return spLogFileData;
 	}
@@ -88,19 +89,23 @@
 		m_spGlobalRotationInfo->SetRotatedCount(uiMaxRotatedCount);
 	}
 
-	void TAsyncMultiLogger::LoggingThread()
+	DWORD TAsyncMultiLogger::LoggingThread(void* pParam)
 	{
+		TAsyncMultiLogger* pAsyncLogger = (TAsyncMultiLogger*)pParam;
+
+		ResetEvent(pAsyncLogger->m_spStoppedEvent.get());
+
 		std::vector<HANDLE> vHandles;
 
 		bool bStopProcessing = false;
 		do
 		{
 			{
-				boost::unique_lock<boost::shared_mutex> lock(m_mutex);
+				boost::unique_lock<boost::shared_mutex> lock(pAsyncLogger->m_mutex);
 				vHandles.clear();
-				vHandles.push_back(m_spStopEvent.get());
+				vHandles.push_back(pAsyncLogger->m_spStopEvent.get());
 
-				std::transform(m_setLoggerData.begin(), m_setLoggerData.end(), std::back_inserter(vHandles), [](const TLogFileDataPtr& rData) { return rData->GetEntriesEvent().get(); });
+				std::transform(pAsyncLogger->m_setLoggerData.begin(), pAsyncLogger->m_setLoggerData.end(), std::back_inserter(vHandles), [](const TLogFileDataPtr& rData) { return rData->GetEntriesEvent().get(); });
 			}
 
 			DWORD dwWaitResult = WaitForMultipleObjectsEx(boost::numeric_cast<DWORD>(vHandles.size()), &vHandles[ 0 ], FALSE, 500, FALSE);
@@ -112,8 +117,8 @@
 
 			std::vector<TLogFileDataPtr> vLogs;
 			{
-				boost::shared_lock<boost::shared_mutex> lock(m_mutex);
-				vLogs.insert(vLogs.begin(), m_setLoggerData.begin(), m_setLoggerData.end());
+				boost::shared_lock<boost::shared_mutex> lock(pAsyncLogger->m_mutex);
+				vLogs.insert(vLogs.begin(), pAsyncLogger->m_setLoggerData.begin(), pAsyncLogger->m_setLoggerData.end());
 			}
 
 			for (const TLogFileDataPtr& spLogData : vLogs)
@@ -131,5 +136,8 @@
 			}
 		}
 		while(!bStopProcessing);
+
+		SetEvent(pAsyncLogger->m_spStoppedEvent.get());
+		return 0;
 	}
 }
Index: src/liblogger/TAsyncMultiLogger.h
===================================================================
diff -u -N -ra08ca9e12d93e9a036a5cf739348ff3ef2a58be8 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/liblogger/TAsyncMultiLogger.h	(.../TAsyncMultiLogger.h)	(revision a08ca9e12d93e9a036a5cf739348ff3ef2a58be8)
+++ src/liblogger/TAsyncMultiLogger.h	(.../TAsyncMultiLogger.h)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -38,6 +38,7 @@
 
 	public:
 		TAsyncMultiLogger();
+		~TAsyncMultiLogger();
 
 		void FinishLogging();
 		TLogFileDataPtr CreateLoggerData(PCTSTR pszLogPath, const TMultiLoggerConfigPtr& spLoggerConfig);
@@ -47,7 +48,7 @@
 		void SetMaxRotatedCount(unsigned int uiMaxRotatedCount);
 
 	private:
-		void LoggingThread();
+		static DWORD LoggingThread(void* pParam);
 
 	private:
 #pragma warning(push)
@@ -56,7 +57,8 @@
 		boost::shared_mutex m_mutex;
 
 		std::shared_ptr<void> m_spStopEvent;
-		std::unique_ptr<std::thread> m_spThread;
+		std::shared_ptr<void> m_spStoppedEvent;
+		HANDLE m_hThread = nullptr;
 
 		TLoggerRotationInfoPtr m_spGlobalRotationInfo;
 #pragma warning(pop)
Index: src/liblogger/TLogFileData.cpp
===================================================================
diff -u -N -rd89ed8602b3992f26835fe68cb6e89c6d1270044 -rebc7fabbd2d59f9a0f723ea480b5374cc393ec12
--- src/liblogger/TLogFileData.cpp	(.../TLogFileData.cpp)	(revision d89ed8602b3992f26835fe68cb6e89c6d1270044)
+++ src/liblogger/TLogFileData.cpp	(.../TLogFileData.cpp)	(revision ebc7fabbd2d59f9a0f723ea480b5374cc393ec12)
@@ -51,18 +51,28 @@
 
 	void TLogFileData::PushLogEntry(std::wstring strLine)
 	{
-		boost::unique_lock<boost::shared_mutex> lock(m_mutex);
 		if(m_spLogFile)
 		{
-			m_listEntries.emplace_back(strLine);
+			boost::unique_lock<boost::shared_mutex> lock(m_mutex);
+			m_listEntries.push_back(strLine);
 			SetEvent(m_spHasEntriesEvent.get());
 		}
 	}
 
 	void TLogFileData::StoreLogEntries()
 	{
 		if(m_spLogFile)
-			m_spLogFile->Write(m_listEntries);
+		{
+			std::list<std::wstring> listEntries;
+
+			{
+				boost::unique_lock<boost::shared_mutex> lock(m_mutex);
+				std::swap(listEntries, m_listEntries);
+				ResetEvent(m_spHasEntriesEvent.get());
+			}
+
+			m_spLogFile->Write(listEntries);
+		}
 	}
 
 	void TLogFileData::CloseUnusedFile()