Index: src/ch/CfgProperties.cpp
===================================================================
diff -u -r2457755b4084e3d1c80a8e7c77c9f0996312941b -r07a3be49b0c7e5599eb89c2f9da9a9272cc1558a
--- src/ch/CfgProperties.cpp	(.../CfgProperties.cpp)	(revision 2457755b4084e3d1c80a8e7c77c9f0996312941b)
+++ src/ch/CfgProperties.cpp	(.../CfgProperties.cpp)	(revision 07a3be49b0c7e5599eb89c2f9da9a9272cc1558a)
@@ -33,7 +33,7 @@
 	pManager->register_bool(_t("Program/Enabled clipboard monitoring"), false);
 	pManager->register_signed_num(_t("Program/Monitor scan interval"), 1000, 0, llHour);
 	pManager->register_bool(_t("Program/Reload after restart"), false);
-	pManager->register_bool(_t("Program/Check for updates at startup"), true);
+	pManager->register_unsigned_num(_t("Program/Check for updates frequency"), eFreq_Weekly, eFreq_Never, eFreq_Max - 1);
 	pManager->register_bool(_t("Program/Updater checks for beta"), true);
 
 	pManager->register_bool(_t("Program/Shutdown system after finished"), false);
@@ -111,5 +111,8 @@
 	pManager->register_string(_t("Shortcuts/Shortcut"), _t(""), icpf::property::flag_array);
 	pManager->register_string(_t("Recent paths/Path"), _t(""), icpf::property::flag_array);
 
+	// invisible options
+	pManager->register_unsigned_num(_t("Runtime state/Last checked for updates"), 0, 0, ULLONG_MAX);
+
 	return true;
 }
Index: src/ch/CfgProperties.h
===================================================================
diff -u -r2457755b4084e3d1c80a8e7c77c9f0996312941b -r07a3be49b0c7e5599eb89c2f9da9a9272cc1558a
--- src/ch/CfgProperties.h	(.../CfgProperties.h)	(revision 2457755b4084e3d1c80a8e7c77c9f0996312941b)
+++ src/ch/CfgProperties.h	(.../CfgProperties.h)	(revision 07a3be49b0c7e5599eb89c2f9da9a9272cc1558a)
@@ -29,7 +29,7 @@
 	PP_PCLIPBOARDMONITORING = 0,
 	PP_PMONITORSCANINTERVAL,
 	PP_PRELOADAFTERRESTART,
-	PP_PCHECK_FOR_UPDATES_AT_STARTUP,
+	PP_PCHECK_FOR_UPDATES_FREQUENCY,
 	PP_PUPDATE_CHECK_FOR_BETA,
 	PP_PSHUTDOWNAFTREFINISHED,
 	PP_PTIMEBEFORESHUTDOWN,
@@ -104,9 +104,24 @@
 	PP_SNDFINISHEDSOUNDPATH,
 
 	PP_SHORTCUTS,
-	PP_RECENTPATHS
+	PP_RECENTPATHS,
+
+	// invisible options
+	PP_LAST_UPDATE_TIMESTAMP
 };
 
+enum EUpdatesFrequency
+{
+	eFreq_Never,
+	eFreq_EveryStartup,
+	eFreq_Daily,
+	eFreq_Weekly,
+	eFreq_OnceEvery2Weeks,
+	eFreq_Monthly,
+	eFreq_Quarterly,
+	eFreq_Max
+};
+
 // register function
 bool RegisterProperties(icpf::config* pManager);
 
Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r2457755b4084e3d1c80a8e7c77c9f0996312941b -r07a3be49b0c7e5599eb89c2f9da9a9272cc1558a
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 2457755b4084e3d1c80a8e7c77c9f0996312941b)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 07a3be49b0c7e5599eb89c2f9da9a9272cc1558a)
@@ -177,12 +177,54 @@
 	// start clipboard monitoring
 	CClipboardMonitor::StartMonitor(&m_tasks);
 	
-	if(GetConfig().get_bool(PP_PCHECK_FOR_UPDATES_AT_STARTUP))
+	EUpdatesFrequency eFrequency = (EUpdatesFrequency)GetConfig().get_unsigned_num(PP_PCHECK_FOR_UPDATES_FREQUENCY);
+	if(eFrequency != eFreq_Never)
 	{
-		CUpdaterDlg* pDlg = new CUpdaterDlg(true);
-		pDlg->m_bAutoDelete = true;
+		unsigned long long ullMinInterval = 0;
+		switch(eFrequency)
+		{
+		case eFreq_Daily:
+			ullMinInterval = 1*24*60*60;
+			break;
+		case eFreq_Weekly:
+			ullMinInterval = 7*24*60*60;
+			break;
+		case eFreq_OnceEvery2Weeks:
+			ullMinInterval = 14*24*60*60;
+			break;
+		case eFreq_Monthly:
+			ullMinInterval = 30*24*60*60;	// we don't really care if it is a day less or more
+			break;
+		case eFreq_Quarterly:
+			ullMinInterval = 90*24*60*60;
+			break;
+		case eFreq_EveryStartup:
+		default:
+			ullMinInterval = 0;
+		}
 
-		pDlg->Create();
+		// get last check time stored in configuration
+		unsigned long long ullCurrentStamp = _time64(NULL);
+		unsigned long long ullTimestamp = GetConfig().get_unsigned_num(PP_LAST_UPDATE_TIMESTAMP);
+
+		// perform checking for updates only when the minimal interval has passed
+		if(ullCurrentStamp - ullTimestamp >= ullMinInterval)
+		{
+			CUpdaterDlg* pDlg = new CUpdaterDlg(true);
+			pDlg->m_bAutoDelete = true;
+
+			pDlg->Create();
+			chcore::TCoreConfig& rConfig = GetConfig();
+			try
+			{
+				rConfig.set_unsigned_num(PP_LAST_UPDATE_TIMESTAMP, _time64(NULL));
+				rConfig.write(NULL);
+			}
+			catch(icpf::exception& /*e*/)
+			{
+				LOG_ERROR(_T("Storing last update check timestamp in configuration failed"));
+			}
+		}
 	}
 
 	// start saving timer
Index: src/ch/OptionsDlg.cpp
===================================================================
diff -u -r2457755b4084e3d1c80a8e7c77c9f0996312941b -r07a3be49b0c7e5599eb89c2f9da9a9272cc1558a
--- src/ch/OptionsDlg.cpp	(.../OptionsDlg.cpp)	(revision 2457755b4084e3d1c80a8e7c77c9f0996312941b)
+++ src/ch/OptionsDlg.cpp	(.../OptionsDlg.cpp)	(revision 07a3be49b0c7e5599eb89c2f9da9a9272cc1558a)
@@ -236,7 +236,7 @@
 	PROP_BOOL(IDS_CLIPBOARDMONITORING_STRING, GetConfig().get_bool(PP_PCLIPBOARDMONITORING));
 	PROP_UINT(IDS_CLIPBOARDINTERVAL_STRING, GetConfig().get_signed_num(PP_PMONITORSCANINTERVAL));
 	PROP_BOOL(IDS_AUTORUNPROGRAM_STRING, GetConfig().get_bool(PP_PRELOADAFTERRESTART));
-	PROP_BOOL(IDS_CFG_CHECK_FOR_UPDATES_AT_STARTUP, GetConfig().get_bool(PP_PCHECK_FOR_UPDATES_AT_STARTUP));
+	PROP_COMBO(IDS_CFG_CHECK_FOR_UPDATES_FREQUENCY, IDS_UPDATE_FREQUENCIES, GetConfig().get_unsigned_num(PP_PCHECK_FOR_UPDATES_FREQUENCY));
 	PROP_BOOL(IDS_CFG_UPDATE_CHECK_FOR_BETA, GetConfig().get_bool(PP_PUPDATE_CHECK_FOR_BETA));
 	PROP_BOOL(IDS_AUTOSHUTDOWN_STRING, GetConfig().get_bool(PP_PSHUTDOWNAFTREFINISHED));
 	PROP_UINT(IDS_SHUTDOWNTIME_STRING, GetConfig().get_signed_num(PP_PTIMEBEFORESHUTDOWN));
@@ -356,7 +356,7 @@
 	rConfig.set_bool(PP_PCLIPBOARDMONITORING, GetBoolProp(iPosition++));
 	rConfig.set_signed_num(PP_PMONITORSCANINTERVAL, GetUintProp(iPosition++));
 	rConfig.set_bool(PP_PRELOADAFTERRESTART, GetBoolProp(iPosition++));
-	rConfig.set_bool(PP_PCHECK_FOR_UPDATES_AT_STARTUP, GetBoolProp(iPosition++));
+	rConfig.set_unsigned_num(PP_PCHECK_FOR_UPDATES_FREQUENCY, GetIndexProp(iPosition++));
 	rConfig.set_bool(PP_PUPDATE_CHECK_FOR_BETA, GetBoolProp(iPosition++));
 	rConfig.set_bool(PP_PSHUTDOWNAFTREFINISHED, GetBoolProp(iPosition++));
 	rConfig.set_signed_num(PP_PTIMEBEFORESHUTDOWN, GetUintProp(iPosition++));
Index: src/ch/UpdaterDlg.cpp
===================================================================
diff -u -rb82ebc5caf998dbfd61370968f0438d8fb74897a -r07a3be49b0c7e5599eb89c2f9da9a9272cc1558a
--- src/ch/UpdaterDlg.cpp	(.../UpdaterDlg.cpp)	(revision b82ebc5caf998dbfd61370968f0438d8fb74897a)
+++ src/ch/UpdaterDlg.cpp	(.../UpdaterDlg.cpp)	(revision 07a3be49b0c7e5599eb89c2f9da9a9272cc1558a)
@@ -45,6 +45,11 @@
 	fmt.SetParam(_t("%site"), _T(PRODUCT_SITE));
 	m_ctlText.SetWindowText(fmt);
 
+	// disable button initially
+	CWnd* pWnd = GetDlgItem(IDC_OPEN_WEBPAGE_BUTTON);
+	if(pWnd)
+		pWnd->EnableWindow(FALSE);
+
 	if(!m_bBackgroundMode)
 		ShowWindow(SW_SHOW);
 
@@ -60,19 +65,23 @@
 
 void CUpdaterDlg::OnBnClickedOpenWebpageButton()
 {
-	CString str;
-	str.Format(_T("Opening a browser with address %s..."), (PCTSTR)m_ucChecker.GetDownloadAddress());
-	LOG_DEBUG(str);
+	CString strDownloadAddr = m_ucChecker.GetDownloadAddress();
+	if(!strDownloadAddr.IsEmpty())
+	{
+		CString str;
+		str.Format(_T("Opening a browser with address %s..."), (PCTSTR)strDownloadAddr);
+		LOG_DEBUG(str);
 
-	str.Format(_T("url.dll,FileProtocolHandler %s"), (PCTSTR)m_ucChecker.GetDownloadAddress());
-	ulong_t ulRes = (ulong_t)ShellExecute(NULL, _T("open"), _T("rundll32.exe"), str, NULL, SW_SHOW);
+		str.Format(_T("url.dll,FileProtocolHandler %s"), (PCTSTR)strDownloadAddr);
+		ulong_t ulRes = (ulong_t)ShellExecute(NULL, _T("open"), _T("rundll32.exe"), str, NULL, SW_SHOW);
 
-	str.Format(_T("ShellExecute returned %lu"), ulRes);
-	LOG_DEBUG(str);
+		str.Format(_T("ShellExecute returned %lu"), ulRes);
+		LOG_DEBUG(str);
 
-	// close the dialog if succeeded; 32 is some arbitrary value from ms docs
-	if(ulRes > 32)
-		CUpdaterDlg::OnOK();
+		// close the dialog if succeeded; 32 is some arbitrary value from ms docs
+		if(ulRes > 32)
+			CUpdaterDlg::OnOK();
+	}
 }
 
 void CUpdaterDlg::OnTimer(UINT_PTR nIDEvent)
@@ -84,6 +93,7 @@
 		CUpdateChecker::ECheckResult eResult = m_ucChecker.GetResult();
 		CString strFmt;
 		EBkModeResult eBkMode = eRes_None;
+		bool bEnableButton = false;
 
 		if(eResult != m_eLastState)
 		{
@@ -111,17 +121,20 @@
 			case CUpdateChecker::eResult_RemoteVersionOlder:
 				TRACE(_T("CUpdateChecker::eResult_RemoteVersionOlder\n"));
 				eBkMode = eRes_Exit;
+				bEnableButton = true;
 //				eBkMode = eRes_Show;		// for debugging purposes only
 				strFmt = rResManager.LoadString(IDS_UPDATER_OLD_VERSION_STRING);
 				break;
 			case CUpdateChecker::eResult_VersionCurrent:
 				TRACE(_T("CUpdateChecker::eResult_VersionCurrent\n"));
 				eBkMode = eRes_Exit;
+				bEnableButton = true;
 				strFmt = rResManager.LoadString(IDS_UPDATER_EQUAL_VERSION_STRING);
 				break;
 			case CUpdateChecker::eResult_RemoteVersionNewer:
 				TRACE(_T("CUpdateChecker::eResult_RemoteVersionNewer\n"));
 				eBkMode = eRes_Show;
+				bEnableButton = true;
 				strFmt = rResManager.LoadString(IDS_UPDATER_NEW_VERSION_STRING);
 				break;
 			default:
@@ -138,6 +151,11 @@
 
 			m_ctlText.SetWindowText(fmt);
 
+			// Update button state
+			CWnd* pWnd = GetDlgItem(IDC_OPEN_WEBPAGE_BUTTON);
+			if(pWnd)
+				pWnd->EnableWindow(bEnableButton);
+
 			m_eLastState = eResult;
 
 			// handle background mode
Index: src/ch/ch.rc
===================================================================
diff -u -r2457755b4084e3d1c80a8e7c77c9f0996312941b -r07a3be49b0c7e5599eb89c2f9da9a9272cc1558a
--- src/ch/ch.rc	(.../ch.rc)	(revision 2457755b4084e3d1c80a8e7c77c9f0996312941b)
+++ src/ch/ch.rc	(.../ch.rc)	(revision 07a3be49b0c7e5599eb89c2f9da9a9272cc1558a)
@@ -769,9 +769,10 @@
 BEGIN
     IDS_CFGINTERCEPTCONTEXTMENU_STRING 
                             "Intercept standard Windows operations (experimental/not recommended)"
-    IDS_CFG_CHECK_FOR_UPDATES_AT_STARTUP 
-                            "Automatically check for program updates at startup"
+    IDS_CFG_CHECK_FOR_UPDATES_FREQUENCY
+                            "Check for program updates"
     IDS_CFG_UPDATE_CHECK_FOR_BETA "Check for updates - include beta versions"
+	IDS_UPDATE_FREQUENCIES "Never!Every startup!Daily!Weekly!Once every 2 weeks!Monthly!Quarterly"
 END
 
 STRINGTABLE 
Index: src/ch/resource.h
===================================================================
diff -u -r2457755b4084e3d1c80a8e7c77c9f0996312941b -r07a3be49b0c7e5599eb89c2f9da9a9272cc1558a
--- src/ch/resource.h	(.../resource.h)	(revision 2457755b4084e3d1c80a8e7c77c9f0996312941b)
+++ src/ch/resource.h	(.../resource.h)	(revision 07a3be49b0c7e5599eb89c2f9da9a9272cc1558a)
@@ -421,10 +421,11 @@
 #define IDS_LANGSFOLDERCHOOSE_STRING    8094
 #define IDS_ABOUT_LANGUAGE_STRING       8095
 #define IDS_CFGINTERCEPTCONTEXTMENU_STRING 8096
-#define IDS_CFG_CHECK_FOR_UPDATES_AT_STARTUP 8097
+#define IDS_CFG_CHECK_FOR_UPDATES_FREQUENCY 8097
 #define IDS_CFG_UPDATE_CHECK_FOR_BETA 8098
 #define IDS_CFGLOGLEVEL				  8099
 #define IDS_CFGLOGLEVEL_VALUES		  8100
+#define IDS_UPDATE_FREQUENCIES			8101
 #define IDS_MENUCOPY_STRING             9000
 #define IDS_MENUMOVE_STRING             9001
 #define IDS_MENUCOPYMOVESPECIAL_STRING  9002