OSDN Git Service

Fixed issue #209: High CPU usage in tortoiseproc.exe
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / CheckForUpdatesDlg.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "stdafx.h"\r
20 #include "TortoiseProc.h"\r
21 #include "CommonResource.h"\r
22 #include "..\version.h"\r
23 #include "MessageBox.h"\r
24 #include ".\checkforupdatesdlg.h"\r
25 #include "Registry.h"\r
26 #include "AppUtils.h"\r
27 #include "TempFile.h"\r
28 \r
29 \r
30 IMPLEMENT_DYNAMIC(CCheckForUpdatesDlg, CStandAloneDialog)\r
31 CCheckForUpdatesDlg::CCheckForUpdatesDlg(CWnd* pParent /*=NULL*/)\r
32         : CStandAloneDialog(CCheckForUpdatesDlg::IDD, pParent)\r
33         , m_bShowInfo(FALSE)\r
34         , m_bVisible(FALSE)\r
35 {\r
36         m_sUpdateDownloadLink = _T("http://code.google.com/p/tortoisegit/downloads");\r
37         m_sUpdateChangeLogLink = _T("http://code.google.com/p/tortoisegit/wiki/ReleaseNotes");\r
38 }\r
39 \r
40 CCheckForUpdatesDlg::~CCheckForUpdatesDlg()\r
41 {\r
42 }\r
43 \r
44 void CCheckForUpdatesDlg::DoDataExchange(CDataExchange* pDX)\r
45 {\r
46         CStandAloneDialog::DoDataExchange(pDX);\r
47         DDX_Control(pDX, IDC_LINK, m_link);\r
48         DDX_Control(pDX, IDC_LINK_CHANGE_LOG, m_ChangeLogLink);\r
49 }\r
50 \r
51 \r
52 BEGIN_MESSAGE_MAP(CCheckForUpdatesDlg, CStandAloneDialog)\r
53         ON_STN_CLICKED(IDC_CHECKRESULT, OnStnClickedCheckresult)\r
54         ON_WM_TIMER()\r
55         ON_WM_WINDOWPOSCHANGING()\r
56         ON_WM_SETCURSOR()\r
57 END_MESSAGE_MAP()\r
58 \r
59 BOOL CCheckForUpdatesDlg::OnInitDialog()\r
60 {\r
61         CStandAloneDialog::OnInitDialog();\r
62 \r
63         CString temp;\r
64         temp.Format(IDS_CHECKNEWER_YOURVERSION, TSVN_VERMAJOR, TSVN_VERMINOR, TSVN_VERMICRO, TSVN_VERBUILD);\r
65         SetDlgItemText(IDC_YOURVERSION, temp);\r
66 \r
67         DialogEnableWindow(IDOK, FALSE);\r
68 \r
69         if (AfxBeginThread(CheckThreadEntry, this)==NULL)\r
70         {\r
71                 CMessageBox::Show(NULL, IDS_ERR_THREADSTARTFAILED, IDS_APPNAME, MB_OK | MB_ICONERROR);\r
72         }\r
73 \r
74         SetTimer(100, 1000, NULL);\r
75         return TRUE;\r
76 }\r
77 \r
78 void CCheckForUpdatesDlg::OnOK()\r
79 {\r
80         if (m_bThreadRunning)\r
81                 return;\r
82         CStandAloneDialog::OnOK();\r
83 }\r
84 \r
85 void CCheckForUpdatesDlg::OnCancel()\r
86 {\r
87         if (m_bThreadRunning)\r
88                 return;\r
89         CStandAloneDialog::OnCancel();\r
90 }\r
91 \r
92 UINT CCheckForUpdatesDlg::CheckThreadEntry(LPVOID pVoid)\r
93 {\r
94         return ((CCheckForUpdatesDlg*)pVoid)->CheckThread();\r
95 }\r
96 \r
97 UINT CCheckForUpdatesDlg::CheckThread()\r
98 {\r
99         m_bThreadRunning = TRUE;\r
100 \r
101         CString temp;\r
102         CString tempfile = CTempFiles::Instance().GetTempFilePath(true).GetWinPathString();\r
103 \r
104         CRegString checkurluser = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""));\r
105         CRegString checkurlmachine = CRegString(_T("Software\\TortoiseGit\\UpdateCheckURL"), _T(""), FALSE, HKEY_LOCAL_MACHINE);\r
106         CString sCheckURL = checkurluser;\r
107         if (sCheckURL.IsEmpty())\r
108         {\r
109                 sCheckURL = checkurlmachine;\r
110                 if (sCheckURL.IsEmpty())\r
111                         sCheckURL = _T("http://code.google.com/p/tortoisegit/downloads/list");\r
112         }\r
113         CoInitialize(NULL);\r
114         HRESULT res = URLDownloadToFile(NULL, sCheckURL, tempfile, 0, NULL);\r
115         if (res == S_OK)\r
116         {\r
117                 try\r
118                 {\r
119                         CStdioFile file(tempfile, CFile::modeRead | CFile::shareDenyWrite);\r
120                         CString ver;\r
121                         int major,minor,micro,build;\r
122                         major=minor=micro=build=0;\r
123                         unsigned __int64 version=0;\r
124 \r
125                         if(file.GetLength()>100)\r
126                         {\r
127                                 while(file.ReadString(ver))\r
128                                 {\r
129                                         int start;\r
130                                         while( (start=ver.Find(_T("TortoiseGit-"))) > 0 )\r
131                                         {\r
132                                                 ver = ver.Mid(start+CString(_T("TortoiseGit-")).GetLength());\r
133                                                 int x1,x2,x3,x4;\r
134                                                 x1=_ttoi(ver)&0xFFFF;\r
135                                                 ver = ver.Mid(ver.Find('.')+1);\r
136                                                 x2=_ttoi(ver)&0xFFFF;\r
137                                                 ver = ver.Mid(ver.Find('.')+1);\r
138                                                 x3=_ttoi(ver)&0xFFFF;\r
139                                                 ver = ver.Mid(ver.Find('.')+1);\r
140                                                 x4=_ttoi(ver)&0xFFFF;\r
141                                                 \r
142                                                 unsigned __int64 newversion;\r
143                                                 newversion = (x1<<48) + (x2<<32) + (x3<<16)+x4;\r
144                                                 if(newversion>version)\r
145                                                 {\r
146                                                         major=x1;\r
147                                                         minor=x2;\r
148                                                         micro=x3;\r
149                                                         build=x4;\r
150                                                         version = newversion;\r
151                                                 }\r
152                                         }\r
153                                 }\r
154 \r
155                         }else if (file.ReadString(ver))\r
156                         {\r
157                                 CString vertemp = ver;\r
158                                 major = _ttoi(vertemp);\r
159                                 vertemp = vertemp.Mid(vertemp.Find('.')+1);\r
160                                 minor = _ttoi(vertemp);\r
161                                 vertemp = vertemp.Mid(vertemp.Find('.')+1);\r
162                                 micro = _ttoi(vertemp);\r
163                                 vertemp = vertemp.Mid(vertemp.Find('.')+1);\r
164                                 build = _ttoi(vertemp);\r
165                                 version = (major<<48) + (minor<<32) + (micro<<16)+build;\r
166                         }\r
167 \r
168                         {\r
169                                 BOOL bNewer = FALSE;\r
170                                 if (major > TSVN_VERMAJOR)\r
171                                         bNewer = TRUE;\r
172                                 else if ((minor > TSVN_VERMINOR)&&(major == TSVN_VERMAJOR))\r
173                                         bNewer = TRUE;\r
174                                 else if ((micro > TSVN_VERMICRO)&&(minor == TSVN_VERMINOR)&&(major == TSVN_VERMAJOR))\r
175                                         bNewer = TRUE;\r
176                                 else if ((build > TSVN_VERBUILD)&&(micro == TSVN_VERMICRO)&&(minor == TSVN_VERMINOR)&&(major == TSVN_VERMAJOR))\r
177                                         bNewer = TRUE;\r
178 \r
179                                 if (version != 0)\r
180                                 {\r
181                                         ver.Format(_T("%d.%d.%d.%d"),major,minor,micro,build);\r
182                                         temp.Format(IDS_CHECKNEWER_CURRENTVERSION, (LPCTSTR)ver);\r
183                                         SetDlgItemText(IDC_CURRENTVERSION, temp);\r
184                                         temp.Format(_T("%d.%d.%d.%d"), TSVN_VERMAJOR, TSVN_VERMINOR, TSVN_VERMICRO, TSVN_VERBUILD);\r
185                                 }\r
186 \r
187                                 if (version == 0)\r
188                                 {\r
189                                         temp.LoadString(IDS_CHECKNEWER_NETERROR);\r
190                                         SetDlgItemText(IDC_CHECKRESULT, temp);\r
191                                 }\r
192                                 else if (bNewer)\r
193                                 {\r
194                                         if(file.ReadString(temp) && !temp.IsEmpty())\r
195                                         {       // Read the next line, it could contain a message for the user\r
196                                                 CString tempLink;\r
197                                                 if(file.ReadString(tempLink) && !tempLink.IsEmpty())\r
198                                                 {       // Read another line to find out the download link-URL, if any\r
199                                                         m_sUpdateDownloadLink = tempLink;\r
200                                                 }\r
201 \r
202                                         }\r
203                                         else\r
204                                         {\r
205                                                 temp.LoadString(IDS_CHECKNEWER_NEWERVERSIONAVAILABLE);\r
206                                         }\r
207                                         SetDlgItemText(IDC_CHECKRESULT, temp);\r
208                                         m_bShowInfo = TRUE;\r
209                                 }\r
210                                 else\r
211                                 {\r
212                                         temp.LoadString(IDS_CHECKNEWER_YOURUPTODATE);\r
213                                         SetDlgItemText(IDC_CHECKRESULT, temp);\r
214                                 }\r
215                         }\r
216                 }\r
217                 catch (CException * e)\r
218                 {\r
219                         e->Delete();\r
220                         temp.LoadString(IDS_CHECKNEWER_NETERROR);\r
221                         SetDlgItemText(IDC_CHECKRESULT, temp);\r
222                 }\r
223         }\r
224         else\r
225         {\r
226                 // Try to cache web page;\r
227 \r
228                 temp.LoadString(IDS_CHECKNEWER_NETERROR);\r
229                 SetDlgItemText(IDC_CHECKRESULT, temp);\r
230         }\r
231         if (!m_sUpdateDownloadLink.IsEmpty())\r
232         {\r
233                 m_link.ShowWindow(SW_SHOW);\r
234                 m_link.SetURL(m_sUpdateDownloadLink);\r
235         }\r
236         if (!m_sUpdateDownloadLink.IsEmpty())\r
237         {\r
238                 m_ChangeLogLink.ShowWindow(SW_SHOW);\r
239                 m_ChangeLogLink.SetURL(m_sUpdateChangeLogLink);\r
240         }\r
241 \r
242         DeleteFile(tempfile);\r
243         m_bThreadRunning = FALSE;\r
244         DialogEnableWindow(IDOK, TRUE);\r
245         return 0;\r
246 }\r
247 \r
248 void CCheckForUpdatesDlg::OnStnClickedCheckresult()\r
249 {\r
250         // user clicked on the label, start the browser with our web page\r
251         HINSTANCE result = ShellExecute(NULL, _T("opennew"), m_sUpdateDownloadLink, NULL,NULL, SW_SHOWNORMAL);\r
252         if ((UINT)result <= HINSTANCE_ERROR)\r
253         {\r
254                 result = ShellExecute(NULL, _T("open"), m_sUpdateDownloadLink, NULL,NULL, SW_SHOWNORMAL);\r
255         }\r
256 }\r
257 \r
258 void CCheckForUpdatesDlg::OnTimer(UINT_PTR nIDEvent)\r
259 {\r
260         if (nIDEvent == 100)\r
261         {\r
262                 if (m_bThreadRunning == FALSE)\r
263                 {\r
264                         if (m_bShowInfo)\r
265                         {\r
266                                 m_bVisible = TRUE;\r
267                                 ShowWindow(SW_SHOWNORMAL);\r
268                         }\r
269                         else\r
270                         {\r
271                                 EndDialog(0);\r
272                         }\r
273                 }\r
274         }\r
275         CStandAloneDialog::OnTimer(nIDEvent);\r
276 }\r
277 \r
278 void CCheckForUpdatesDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)\r
279 {\r
280         CStandAloneDialog::OnWindowPosChanging(lpwndpos);\r
281         if (m_bVisible == FALSE)\r
282                 lpwndpos->flags &= ~SWP_SHOWWINDOW;\r
283 }\r
284 \r
285 BOOL CCheckForUpdatesDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)\r
286 {\r
287         if ((!m_sUpdateDownloadLink.IsEmpty())&&(pWnd)&&(pWnd == GetDlgItem(IDC_CHECKRESULT)))\r
288         {\r
289                 HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND));\r
290                 SetCursor(hCur);\r
291                 return TRUE;\r
292         }\r
293 \r
294         HCURSOR hCur = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));\r
295         SetCursor(hCur);\r
296         return CStandAloneDialogTmpl<CDialog>::OnSetCursor(pWnd, nHitTest, message);\r
297 }\r