Index: .gitignore
===================================================================
diff -u -r1601e7fb2633a9f8fd22b8e95e434540245320df -rd5fd15320ef765fd5225b10e764bca458c2e317c
--- .gitignore	(.../.gitignore)	(revision 1601e7fb2633a9f8fd22b8e95e434540245320df)
+++ .gitignore	(.../.gitignore)	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -3,6 +3,7 @@
 .vs
 ipch
 *.sdf
+*.user
 src/ch/help/HTMLDefines.h
 src/ch/help/*/HTMLDefines.h
 src/ch/help/*/*.chm
Index: src/ch/TRegistry.cpp
===================================================================
diff -u
--- src/ch/TRegistry.cpp	(revision 0)
+++ src/ch/TRegistry.cpp	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -0,0 +1,64 @@
+// ============================================================================
+//  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 "TRegistry.h"
+
+TRegistry::TRegistry(HKEY key, const wchar_t* pszKey)
+{
+	LSTATUS lStatus = RegOpenKeyEx(key, pszKey, 0, KEY_QUERY_VALUE, &m_hKey);
+	if (lStatus != ERROR_SUCCESS || m_hKey == nullptr)
+		throw std::runtime_error("Cannot open registry key");
+}
+
+TRegistry::~TRegistry()
+{
+	if(m_hKey)
+		RegCloseKey(m_hKey);
+}
+
+bool TRegistry::QueryString(const wchar_t* pszValueKey, std::wstring& wstrValue)
+{
+	DWORD dwType = REG_SZ;
+	const DWORD stMaxBuffer = 1024;
+	std::unique_ptr<wchar_t[]> buf(new wchar_t[stMaxBuffer]);
+
+	DWORD dwCount = stMaxBuffer;
+	LSTATUS lStatus = RegQueryValueEx(m_hKey, pszValueKey, NULL, &dwType, (BYTE*)buf.get(), &dwCount);
+	if (lStatus != ERROR_SUCCESS)
+		return false;
+
+	buf[dwCount / 2] = L'\0';
+	wstrValue = buf.get();
+
+	return true;
+}
+
+bool TRegistry::QueryDword(const wchar_t* pszValueKey, DWORD& dwOutValue)
+{
+	DWORD dwType = REG_DWORD;
+	DWORD dwCount = sizeof(DWORD);
+	DWORD dwValue = 0;
+	LSTATUS lStatus = RegQueryValueEx(m_hKey, pszValueKey, NULL, &dwType, (BYTE*)&dwValue, &dwCount);
+	if (lStatus != ERROR_SUCCESS)
+		return false;
+
+	dwOutValue = dwValue;
+
+	return true;
+}
Index: src/ch/TRegistry.h
===================================================================
diff -u
--- src/ch/TRegistry.h	(revision 0)
+++ src/ch/TRegistry.h	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -0,0 +1,35 @@
+// ============================================================================
+//  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 __TREGISTRY_H__
+#define __TREGISTRY_H__
+
+class TRegistry
+{
+public:
+	TRegistry(HKEY key, const wchar_t* pszKey);
+	~TRegistry();
+
+	bool QueryString(const wchar_t* pszValueKey, std::wstring& wstrValue);
+	bool QueryDword(const wchar_t* pszValueKey, DWORD& dwOutValue);
+
+private:
+	HKEY m_hKey;
+};
+
+#endif
Index: src/ch/UpdateChecker.cpp
===================================================================
diff -u -r8ef3d7626821ec49c5cad75fd8176e492884bc7b -rd5fd15320ef765fd5225b10e764bca458c2e317c
--- src/ch/UpdateChecker.cpp	(.../UpdateChecker.cpp)	(revision 8ef3d7626821ec49c5cad75fd8176e492884bc7b)
+++ src/ch/UpdateChecker.cpp	(.../UpdateChecker.cpp)	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -29,6 +29,8 @@
 #include "../libicpf/exception.h"
 #include "../libicpf/circ_buffer.h"
 #include "../libchcore/TWin32ErrorFormatter.h"
+#include "WindowsVersion.h"
+#include <boost/lexical_cast.hpp>
 
 // timeout used with waiting for events (avoiding hangs)
 #define FORCE_TIMEOUT 60000
@@ -74,7 +76,7 @@
 /// @param[in] pszPath		Url to be opened (full path to file).
 /// @return    S_OK if opened, S_FALSE if wait for result is needed, E_* for errors.
 // ============================================================================
-HRESULT CAsyncHttpFile::Open(const tchar_t* pszPath)
+HRESULT CAsyncHttpFile::Open(const tchar_t* pszPath, const wchar_t* pszUserAgent)
 {
 	if(!pszPath)
 	{
@@ -99,7 +101,7 @@
 		return E_FAIL;
 	}
 
-	m_hInternet = ::InternetOpen(_T(PRODUCT_NAME), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
+	m_hInternet = ::InternetOpen(pszUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
 	if(!m_hInternet)
 	{
 		SetErrorCode(GetLastError());
@@ -618,6 +620,20 @@
 	return bCheckForBeta;
 }
 
+std::wstring CUpdateChecker::GetUserAgent()
+{
+	std::wstring wstrUserAgent(PRODUCT_FULL_VERSION_T);
+	wstrUserAgent += L" (" +
+		boost::lexical_cast<std::wstring>(PRODUCT_VERSION1) + L"." + 
+		boost::lexical_cast<std::wstring>(PRODUCT_VERSION2) + L"." + 
+		boost::lexical_cast<std::wstring>(PRODUCT_VERSION3) + L"." + 
+		boost::lexical_cast<std::wstring>(PRODUCT_VERSION4) + L")";
+
+	wstrUserAgent += L" (" + WindowsVersion::GetWindowsVersion() + L")";
+
+	return wstrUserAgent;
+}
+
 // ============================================================================
 /// CUpdateChecker::GetResult
 /// @date 2009/04/18
@@ -662,7 +678,8 @@
 	vBuffer.reserve(stReserveBuffer);
 
 	// open the connection and try to get to the file
-	HRESULT hResult = pUpdateChecker->m_httpFile.Open(strSite);
+	std::wstring wstrUserAgent = GetUserAgent();
+	HRESULT hResult = pUpdateChecker->m_httpFile.Open(strSite, wstrUserAgent.c_str());
 	if(SUCCEEDED(hResult))
 	{
 		eWaitResult = pUpdateChecker->m_httpFile.WaitForResult(pUpdateChecker->m_hKillEvent);
Index: src/ch/UpdateChecker.h
===================================================================
diff -u -r5b177c8d202751958cb04cd3049549a94aab5994 -rd5fd15320ef765fd5225b10e764bca458c2e317c
--- src/ch/UpdateChecker.h	(.../UpdateChecker.h)	(revision 5b177c8d202751958cb04cd3049549a94aab5994)
+++ src/ch/UpdateChecker.h	(.../UpdateChecker.h)	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -52,7 +52,7 @@
 	CAsyncHttpFile();
 	~CAsyncHttpFile();
 
-	HRESULT Open(const tchar_t* pszPath);
+	HRESULT Open(const wchar_t* pszPath, const wchar_t* pszUserAgent);
 	HRESULT GetFileSize(size_t& stSize);
 
 	HRESULT RequestData(void* pBuffer, size_t stSize);
@@ -142,6 +142,9 @@
 	/// Returns information if we're interested in beta versions
 	bool CheckForBeta();
 
+	// user agent
+	static std::wstring GetUserAgent();
+
 protected:
 	CString m_strSite;
 	bool m_bCheckForBeta;
Index: src/ch/WindowsVersion.cpp
===================================================================
diff -u
--- src/ch/WindowsVersion.cpp	(revision 0)
+++ src/ch/WindowsVersion.cpp	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -0,0 +1,96 @@
+// ============================================================================
+//  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 "WindowsVersion.h"
+#include "TRegistry.h"
+#include <boost\lexical_cast.hpp>
+#include <boost\algorithm\string\replace.hpp>
+
+std::wstring WindowsVersion::GetWindowsVersion()
+{
+	TRegistry regCurrentVer(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
+
+	std::wstring wstrVersion;
+	std::wstring wstrProductName;
+	std::wstring wstrInstallType;
+	std::wstring wstrBuildNumber;
+	std::wstring wstrServicePack;
+
+	DWORD dwMajor = 0;
+	DWORD dwMinor = 0;
+	if (regCurrentVer.QueryDword(L"CurrentMajorVersionNumber", dwMajor) && regCurrentVer.QueryDword(L"CurrentMinorVersionNumber", dwMinor))
+		wstrVersion = boost::lexical_cast<std::wstring>(dwMajor) + L"." + boost::lexical_cast<std::wstring>(dwMinor);
+	else
+	{
+		if (!regCurrentVer.QueryString(L"CurrentVersion", wstrVersion))
+			wstrVersion = L"Unknown version";
+	}
+
+	if (regCurrentVer.QueryString(L"CurrentBuildNumber", wstrBuildNumber))
+		wstrVersion += L"." + wstrBuildNumber;
+
+	regCurrentVer.QueryString(L"ProductName", wstrProductName);
+	if (regCurrentVer.QueryString(L"InstallationType", wstrInstallType) && !wstrInstallType.empty())
+	{
+		if (wstrInstallType == L"Client")
+			wstrInstallType.clear();
+		else
+			wstrInstallType = wstrInstallType[0];
+	}
+
+	regCurrentVer.QueryString(L"CSDVersion", wstrServicePack);
+	boost::replace_all(wstrServicePack, L"Service Pack ", L"SP");
+
+	std::wstring wstrFullVer = wstrProductName;
+	if (!wstrServicePack.empty())
+		wstrFullVer += L" " + wstrServicePack;
+
+	wstrFullVer += L" (" + wstrVersion + wstrInstallType + L";" + GetCpuArch() + L")";
+	return wstrFullVer;
+}
+
+std::wstring WindowsVersion::GetCpuArch()
+{
+	SYSTEM_INFO si = { 0 };
+	GetNativeSystemInfo(&si);
+
+	switch (si.wProcessorArchitecture)
+	{
+	case PROCESSOR_ARCHITECTURE_AMD64:
+	{
+#ifndef _M_AMD64
+		return L"x64-";
+#else
+		return L"x64";
+#endif
+	}
+
+	case PROCESSOR_ARCHITECTURE_INTEL:
+	{
+#ifndef _M_IX86
+		return L"x86-";
+#else
+		return L"x86";
+#endif
+	}
+
+	default:
+		return L"A" + boost::lexical_cast<std::wstring>(si.wProcessorArchitecture);
+	}
+}
Index: src/ch/WindowsVersion.h
===================================================================
diff -u
--- src/ch/WindowsVersion.h	(revision 0)
+++ src/ch/WindowsVersion.h	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -0,0 +1,31 @@
+// ============================================================================
+//  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 __WINDOWSVERSION_H__
+#define __WINDOWSVERSION_H__
+
+#include <string>
+
+class WindowsVersion
+{
+public:
+	static std::wstring GetWindowsVersion();
+	static std::wstring GetCpuArch();
+};
+
+#endif
Index: src/ch/ch.vc140.vcxproj
===================================================================
diff -u -rbfc7a8378a96c5b58def559b343918fca32f05a6 -rd5fd15320ef765fd5225b10e764bca458c2e317c
--- src/ch/ch.vc140.vcxproj	(.../ch.vc140.vcxproj)	(revision bfc7a8378a96c5b58def559b343918fca32f05a6)
+++ src/ch/ch.vc140.vcxproj	(.../ch.vc140.vcxproj)	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -508,6 +508,7 @@
     <ClInclude Include="TMsgBox.h" />
     <ClInclude Include="TProgressCtrlEx.h" />
     <ClInclude Include="TRecentPathsTools.h" />
+    <ClInclude Include="TRegistry.h" />
     <ClInclude Include="UpdateChecker.h" />
     <ClInclude Include="ch.h" />
     <ClInclude Include="stdafx.h" />
@@ -540,6 +541,7 @@
     <ClInclude Include="StatusDlg.h" />
     <ClInclude Include="UpdaterDlg.h" />
     <ClInclude Include="TShellExtensionClient.h" />
+    <ClInclude Include="WindowsVersion.h" />
     <CustomBuild Include="resource.h">
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Generating map file for help compiler...</Message>
       <Message Condition="'$(Configuration)|$(Platform)'=='Testing Debug|Win32'">Generating map file for help compiler...</Message>
@@ -747,6 +749,7 @@
     <ClCompile Include="TMsgBox.cpp" />
     <ClCompile Include="TProgressCtrlEx.cpp" />
     <ClCompile Include="TRecentPathsTools.cpp" />
+    <ClCompile Include="TRegistry.cpp" />
     <ClCompile Include="UpdateChecker.cpp" />
     <ClCompile Include="ch.cpp" />
     <ClCompile Include="stdafx.cpp">
@@ -805,6 +808,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Testing Release|x64'">
       </PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="WindowsVersion.cpp" />
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="ch.rc">
Index: src/ch/ch.vc140.vcxproj.filters
===================================================================
diff -u -r7972b0944e0a947144fbdb93262f7d73ac528dc7 -rd5fd15320ef765fd5225b10e764bca458c2e317c
--- src/ch/ch.vc140.vcxproj.filters	(.../ch.vc140.vcxproj.filters)	(revision 7972b0944e0a947144fbdb93262f7d73ac528dc7)
+++ src/ch/ch.vc140.vcxproj.filters	(.../ch.vc140.vcxproj.filters)	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -209,6 +209,12 @@
     <ClInclude Include="FeedbackHandlerFactory.h">
       <Filter>Source Files\Core</Filter>
     </ClInclude>
+    <ClInclude Include="WindowsVersion.h">
+      <Filter>Source Files\Tools</Filter>
+    </ClInclude>
+    <ClInclude Include="TRegistry.h">
+      <Filter>Source Files\Tools</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\common\TShellExtMenuConfig.cpp">
@@ -349,6 +355,12 @@
     <ClCompile Include="FeedbackHandlerFactory.cpp">
       <Filter>Source Files\Core</Filter>
     </ClCompile>
+    <ClCompile Include="WindowsVersion.cpp">
+      <Filter>Source Files\Tools</Filter>
+    </ClCompile>
+    <ClCompile Include="TRegistry.cpp">
+      <Filter>Source Files\Tools</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="res\ch.rc2">
Index: src/common/version.h
===================================================================
diff -u -r3dc0468ce01fa7aed8fea91348289a3cc3386578 -rd5fd15320ef765fd5225b10e764bca458c2e317c
--- src/common/version.h	(.../version.h)	(revision 3dc0468ce01fa7aed8fea91348289a3cc3386578)
+++ src/common/version.h	(.../version.h)	(revision d5fd15320ef765fd5225b10e764bca458c2e317c)
@@ -25,9 +25,8 @@
 #endif
 
 // copyright information
-#define COPYRIGHT_INFO	"Copyright (C) 2001-2014 J�zef Starosczyk"
+#define COPYRIGHT_INFO	"Copyright (C) 2001-2016 J�zef Starosczyk"
 #define PRODUCT_SITE	"http://www.copyhandler.com"
 #define CONTACT_INFO	"http://www.copyhandler.com/contact"
 
 #endif
-