1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2014 - TortoiseGit
4 // Copyright (C) 2003-2008, 2012-2014 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "TortoiseProc.h"
22 #include "SysImageList.h"
23 #include "..\Utils\CrashReport.h"
24 #include "CmdLineParser.h"
27 #include "PathUtils.h"
28 #include "StringUtils.h"
29 #include "UnicodeUtils.h"
30 #include "MessageBox.h"
31 #include "DirFileEnum.h"
32 #include "GitAdminDir.h"
34 #include "SmartHandle.h"
35 #include "Commands\Command.h"
36 #include "..\version.h"
37 #include "JumpListHelpers.h"
38 #include "SinglePropSheetDlg.h"
39 #include "Settings\setmainpage.h"
40 #include "Libraries.h"
41 #include "TaskbarUUID.h"
42 #include "ProjectProperties.h"
43 #include "HistoryCombo.h"
46 #define STRUCT_IOVEC_DEFINED
52 #pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
54 BEGIN_MESSAGE_MAP(CTortoiseProcApp
, CWinAppEx
)
55 ON_COMMAND(ID_HELP
, CWinAppEx::OnHelp
)
58 //////////////////////////////////////////////////////////////////////////
60 CTortoiseProcApp::CTortoiseProcApp()
63 // prevent from inheriting %GIT_DIR% from parent process by resetting it,
64 // use MSVC function instead of Windows API because MSVC runtime caches environment variables
65 _tputenv(_T("GIT_DIR="));
66 CCrashReport::Instance().AddUserInfoToReport(L
"CommandLine", GetCommandLine());
70 m_bLoadUserToolbars
= FALSE
;
73 m_gdiplusToken
= NULL
;
74 #if defined (_WIN64) && _MSC_VER >= 1800
79 CTortoiseProcApp::~CTortoiseProcApp()
82 SYS_IMAGE_LIST().Cleanup();
85 // The one and only CTortoiseProcApp object
86 CTortoiseProcApp theApp
;
88 CString g_sGroupingUUID
;
89 CString g_sGroupingIcon
;
90 bool g_bGroupingRemoveIcon
= false;
93 #if ENABLE_CRASHHANLDER
94 CCrashReportTGit
crasher(L
"TortoiseGit " _T(APP_X64_STRING
), TGIT_VERMAJOR
, TGIT_VERMINOR
, TGIT_VERMICRO
, TGIT_VERBUILD
, TGIT_VERDATE
);
97 // CTortoiseProcApp initialization
99 BOOL
CTortoiseProcApp::InitInstance()
102 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows
));
103 CMFCButton::EnableWindowsTheming();
104 CHistoryCombo::m_nGitIconIndex
= SYS_IMAGE_LIST().AddIcon((HICON
)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_GITCONFIG
), IMAGE_ICON
, 0, 0, LR_DEFAULTSIZE
));
106 Gdiplus::GdiplusStartupInput gdiplusStartupInput
;
107 Gdiplus::GdiplusStartup(&m_gdiplusToken
,&gdiplusStartupInput
,NULL
);
109 //set the resource dll for the required language
110 CRegDWORD loc
= CRegDWORD(_T("Software\\TortoiseGit\\LanguageID"), 1033);
114 langStr
.Format(_T("%ld"), langId
);
115 CCrashReport::Instance().AddUserInfoToReport(L
"LanguageID", langStr
);
118 CStringA langpath
= CStringA(CPathUtils::GetAppParentDirectory());
119 langpath
+= "Languages";
120 HINSTANCE hInst
= NULL
;
123 langDll
.Format(_T("%sLanguages\\TortoiseProc%ld.dll"), (LPCTSTR
)CPathUtils::GetAppParentDirectory(), langId
);
125 hInst
= LoadLibrary(langDll
);
127 CString sVer
= _T(STRPRODUCTVER
);
128 CString sFileVer
= CPathUtils::GetVersionFromFile(langDll
);
129 if (sFileVer
.Compare(sVer
)!=0)
136 AfxSetResourceHandle(hInst
);
140 DWORD lid
= SUBLANGID(langId
);
144 langId
= MAKELANGID(PRIMARYLANGID(langId
), lid
);
149 } while ((hInst
== NULL
) && (langId
!= 0));
150 TCHAR buf
[6] = { 0 };
151 _tcscpy_s(buf
, _T("en"));
153 // MFC uses a help file with the same name as the application by default,
154 // which means we have to change that default to our language specific help files
155 CString sHelppath
= CPathUtils::GetAppDirectory() + _T("TortoiseGit_en.chm");
156 free((void*)m_pszHelpFilePath
);
157 m_pszHelpFilePath
=_tcsdup(sHelppath
);
158 sHelppath
= CPathUtils::GetAppParentDirectory() + _T("Languages\\TortoiseGit_en.chm");
161 CString sLang
= _T("_");
162 if (GetLocaleInfo(MAKELCID(langId
, SORT_DEFAULT
), LOCALE_SISO639LANGNAME
, buf
, _countof(buf
)))
165 sHelppath
.Replace(_T("_en"), sLang
);
166 if (PathFileExists(sHelppath
))
168 free((void*)m_pszHelpFilePath
);
169 m_pszHelpFilePath
=_tcsdup(sHelppath
);
173 sHelppath
.Replace(sLang
, _T("_en"));
174 if (GetLocaleInfo(MAKELCID(langId
, SORT_DEFAULT
), LOCALE_SISO3166CTRYNAME
, buf
, _countof(buf
)))
178 sHelppath
.Replace(_T("_en"), sLang
);
179 if (PathFileExists(sHelppath
))
181 free((void*)m_pszHelpFilePath
);
182 m_pszHelpFilePath
=_tcsdup(sHelppath
);
186 sHelppath
.Replace(sLang
, _T("_en"));
188 DWORD lid
= SUBLANGID(langId
);
192 langId
= MAKELANGID(PRIMARYLANGID(langId
), lid
);
197 setlocale(LC_ALL
, "");
199 if (!g_Git
.CheckMsysGitDir())
201 UINT ret
= CMessageBox::Show(NULL
, IDS_PROC_NOMSYSGIT
, IDS_APPNAME
, 3, IDI_HAND
, IDS_PROC_SETMSYSGITPATH
, IDS_PROC_GOTOMSYSGITWEBSITE
, IDS_ABORTBUTTON
);
204 ShellExecute(NULL
, NULL
, _T("http://msysgit.github.io/"), NULL
, NULL
, SW_SHOW
);
208 // open settings dialog
209 CSinglePropSheetDlg(CString(MAKEINTRESOURCE(IDS_PROC_SETTINGS_TITLE
)), new CSetMainPage(), this->GetMainWnd()).DoModal();
213 if (CAppUtils::GetMsysgitVersion() < 0x01070a00)
215 int ret
= CMessageBox::ShowCheck(NULL
, IDS_PROC_OLDMSYSGIT
, IDS_APPNAME
, 1, IDI_EXCLAMATION
, IDS_PROC_GOTOMSYSGITWEBSITE
, IDS_ABORTBUTTON
, IDS_IGNOREBUTTON
, _T("OldMsysgitVersionWarning"), IDS_PROC_NOTSHOWAGAINIGNORE
);
218 CMessageBox::RemoveRegistryKey(_T("OldMsysgitVersionWarning")); // only store answer if it is "Ignore"
219 ShellExecute(NULL
, NULL
, _T("http://msysgit.github.io/"), NULL
, NULL
, SW_SHOW
);
224 CMessageBox::RemoveRegistryKey(_T("OldMsysgitVersionWarning")); // only store answer if it is "Ignore"
230 CCrashReport::Instance().AddUserInfoToReport(L
"msysGitDir", CGit::ms_LastMsysGitDir
);
231 CString versionString
;
232 versionString
.Format(_T("%d"), CGit::ms_LastMsysGitVersion
);
233 CCrashReport::Instance().AddUserInfoToReport(L
"msysGitVersion", versionString
);
236 // InitCommonControls() is required on Windows XP if an application
237 // manifest specifies use of ComCtl32.dll version 6 or later to enable
238 // visual styles. Otherwise, any window creation will fail.
240 INITCOMMONCONTROLSEX used
= {
241 sizeof(INITCOMMONCONTROLSEX
),
242 ICC_ANIMATE_CLASS
| ICC_BAR_CLASSES
| ICC_COOL_CLASSES
| ICC_DATE_CLASSES
|
243 ICC_HOTKEY_CLASS
| ICC_INTERNET_CLASSES
| ICC_LISTVIEW_CLASSES
|
244 ICC_NATIVEFNTCTL_CLASS
| ICC_PAGESCROLLER_CLASS
| ICC_PROGRESS_CLASS
|
245 ICC_TAB_CLASSES
| ICC_TREEVIEW_CLASSES
| ICC_UPDOWN_CLASS
|
246 ICC_USEREX_CLASSES
| ICC_WIN95_CLASSES
248 InitCommonControlsEx(&used
);
250 AfxEnableControlContainer();
252 CWinAppEx::InitInstance();
253 SetRegistryKey(_T("TortoiseGit"));
254 AfxGetApp()->m_pszProfileName
= _tcsdup(_T("TortoiseProc")); // w/o this ResizableLib will store data under TortoiseGitProc which is not compatible with older versions
256 CCmdLineParser
parser(AfxGetApp()->m_lpCmdLine
);
259 CString sVal
= parser
.GetVal(_T("hwnd"));
261 hWndExplorer
= (HWND
)_wcstoui64(sVal
, nullptr, 16);
263 while (GetParent(hWndExplorer
)!=NULL
)
264 hWndExplorer
= GetParent(hWndExplorer
);
265 if (!IsWindow(hWndExplorer
))
270 // if HKCU\Software\TortoiseGit\Debug is not 0, show our command line
272 if (CRegDWORD(_T("Software\\TortoiseGit\\Debug"), FALSE
)==TRUE
)
273 AfxMessageBox(AfxGetApp()->m_lpCmdLine
, MB_OK
| MB_ICONINFORMATION
);
275 if (parser
.HasKey(_T("urlhandler")))
277 CString url
= parser
.GetVal(_T("urlhandler"));
278 if (url
.Find(_T("tgit://clone/")) == 0)
280 url
= url
.Mid(13); // 21 = "tgit://clone/".GetLength()
282 else if (url
.Find(_T("github-windows://openRepo/")) == 0)
284 url
= url
.Mid(26); // 26 = "github-windows://openRepo/".GetLength()
285 int questioMark
= url
.Find('?');
287 url
= url
.Left(questioMark
);
289 else if (url
.Find(_T("smartgit://cloneRepo/")) == 0)
291 url
= url
.Mid(21); // 21 = "smartgit://cloneRepo/".GetLength()
295 CMessageBox::Show(NULL
, IDS_ERR_INVALIDPATH
, IDS_APPNAME
, MB_ICONERROR
);
299 newCmd
.Format(_T("/command:clone /url:\"%s\" /hasurlhandler"), url
);
300 parser
= CCmdLineParser(newCmd
);
303 if ( parser
.HasKey(_T("path")) && parser
.HasKey(_T("pathfile")))
305 CMessageBox::Show(NULL
, IDS_ERR_INVALIDPATH
, IDS_APPNAME
, MB_ICONERROR
);
309 CTGitPath cmdLinePath
;
310 CTGitPathList pathList
;
311 if (g_sGroupingUUID
.IsEmpty())
312 g_sGroupingUUID
= parser
.GetVal(L
"groupuuid");
313 if ( parser
.HasKey(_T("pathfile")) )
316 CString sPathfileArgument
= CPathUtils::GetLongPathname(parser
.GetVal(_T("pathfile")));
318 cmdLinePath
.SetFromUnknown(sPathfileArgument
);
319 if (pathList
.LoadFromFile(cmdLinePath
)==false)
320 return FALSE
; // no path specified!
321 if ( parser
.HasKey(_T("deletepathfile")) )
323 // We can delete the temporary path file, now that we've loaded it
324 ::DeleteFile(cmdLinePath
.GetWinPath());
326 // This was a path to a temporary file - it's got no meaning now, and
327 // anybody who uses it again is in for a problem...
334 CString sPathArgument
= CPathUtils::GetLongPathname(parser
.GetVal(_T("path")));
335 if (parser
.HasKey(_T("expaths")))
337 // an /expaths param means we're started via the buttons in our Win7 library
338 // and that means the value of /expaths is the current directory, and
339 // the selected paths are then added as additional parameters but without a key, only a value
341 // because of the "strange treatment of quotation marks and backslashes by CommandLineToArgvW"
342 // we have to escape the backslashes first. Since we're only dealing with paths here, that's
344 // Without this, a command line like:
345 // /command:commit /expaths:"D:\" "D:\Utils"
346 // would fail because the "D:\" is treated as the backslash being the escape char for the quotation
347 // mark and we'd end up with:
348 // argv[1] = /command:commit
349 // argv[2] = /expaths:D:" D:\Utils
350 // See here for more details: http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
351 CString cmdLine
= GetCommandLineW();
352 cmdLine
.Replace(L
"\\", L
"\\\\");
354 LPWSTR
*szArglist
= CommandLineToArgvW(cmdLine
, &nArgs
);
357 // argument 0 is the process path, so start with 1
358 for (int i
= 1; i
< nArgs
; ++i
)
360 if (szArglist
[i
][0] != '/')
362 if (!sPathArgument
.IsEmpty())
363 sPathArgument
+= '*';
364 sPathArgument
+= szArglist
[i
];
367 sPathArgument
.Replace(L
"\\\\", L
"\\");
369 LocalFree(szArglist
);
371 if (sPathArgument
.IsEmpty() && parser
.HasKey(L
"path"))
373 CMessageBox::Show(hWndExplorer
, IDS_ERR_INVALIDPATH
, IDS_APPNAME
, MB_ICONERROR
);
376 int asterisk
= sPathArgument
.Find('*');
377 cmdLinePath
.SetFromUnknown(asterisk
>= 0 ? sPathArgument
.Left(asterisk
) : sPathArgument
);
378 pathList
.LoadFromAsteriskSeparatedString(sPathArgument
);
381 if (pathList
.IsEmpty()) {
382 pathList
.AddPath(CTGitPath::CTGitPath(g_Git
.m_CurrentDir
));
385 // Set CWD to temporary dir, and restore it later
387 DWORD len
= GetCurrentDirectory(0, NULL
);
390 std::unique_ptr
<TCHAR
[]> originalCurrentDirectory(new TCHAR
[len
]);
391 if (GetCurrentDirectory(len
, originalCurrentDirectory
.get()))
393 sOrigCWD
= originalCurrentDirectory
.get();
394 sOrigCWD
= CPathUtils::GetLongPathname(sOrigCWD
);
397 TCHAR pathbuf
[MAX_PATH
] = {0};
398 GetTortoiseGitTempPath(MAX_PATH
, pathbuf
);
399 SetCurrentDirectory(pathbuf
);
402 CheckForNewerVersion();
404 CAutoGeneralHandle TGitMutex
= ::CreateMutex(NULL
, FALSE
, _T("TortoiseGitProc.exe"));
405 if (!g_Git
.SetCurrentDir(cmdLinePath
.GetWinPathString(), parser
.HasKey(_T("submodule")) == TRUE
))
407 for (int i
= 0; i
< pathList
.GetCount(); ++i
)
408 if(g_Git
.SetCurrentDir(pathList
[i
].GetWinPath()))
412 if(!g_Git
.m_CurrentDir
.IsEmpty())
414 sOrigCWD
= g_Git
.m_CurrentDir
;
415 SetCurrentDirectory(g_Git
.m_CurrentDir
);
418 if (g_sGroupingUUID
.IsEmpty())
420 CRegStdDWORD groupSetting
= CRegStdDWORD(_T("Software\\TortoiseGit\\GroupTaskbarIconsPerRepo"), 3);
421 switch (DWORD(groupSetting
))
425 // implemented differently to TortoiseSVN atm
431 if (g_GitAdminDir
.HasAdminDir(g_Git
.m_CurrentDir
, true, &wcroot
))
434 CStringA
wcRootA(wcroot
+ CPathUtils::GetAppDirectory());
435 if (!git_odb_hash(&oid
, wcRootA
, wcRootA
.GetLength(), GIT_OBJ_BLOB
))
438 git_oid_tostr(hash
.GetBufferSetLength(GIT_OID_HEXSZ
+ 1), GIT_OID_HEXSZ
+ 1, &oid
);
439 hash
.ReleaseBuffer();
440 g_sGroupingUUID
= hash
;
442 ProjectProperties pp
;
444 CString icon
= pp
.sIcon
;
445 icon
.Replace('/', '\\');
447 g_bGroupingRemoveIcon
= true;
448 g_sGroupingIcon
= icon
;
454 CString sAppID
= GetTaskIDPerUUID(g_sGroupingUUID
).c_str();
455 InitializeJumpList(sAppID
);
456 EnsureGitLibrary(false);
462 // requires CWD to be set
463 CGit::m_LogEncode
= CAppUtils::GetLogOutputEncode();
465 // make sure all config files are read in order to check that none contains an error
466 g_Git
.GetConfigValue(_T("doesnot.exist"));
475 UINT choice
= CMessageBox::Show(hWndExplorer
, err
, _T("TortoiseGit"), 1, IDI_ERROR
, CString(MAKEINTRESOURCE(IDS_PROC_EDITLOCALGITCONFIG
)), CString(MAKEINTRESOURCE(IDS_PROC_EDITGLOBALGITCONFIG
)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON
)));
478 // open the config file with alternative editor
479 CAppUtils::LaunchAlternativeEditor(g_Git
.GetGitLocalConfig());
481 else if (choice
== 2)
483 // open the global config file with alternative editor
484 CAppUtils::LaunchAlternativeEditor(g_Git
.GetGitGlobalConfig());
490 // execute the requested command
491 CommandServer server
;
492 Command
* cmd
= server
.GetCommand(parser
.GetVal(_T("command")));
495 cmd
->SetExplorerHwnd(hWndExplorer
);
497 cmd
->SetParser(parser
);
498 cmd
->SetPaths(pathList
, cmdLinePath
);
500 retSuccess
= cmd
->Execute();
504 // Look for temporary files left around by TortoiseSVN and
505 // remove them. But only delete 'old' files because some
506 // apps might still be needing the recent ones.
508 DWORD len
= GetTortoiseGitTempPath(0, NULL
);
509 std::unique_ptr
<TCHAR
[]> path(new TCHAR
[len
+ 100]);
510 len
= GetTortoiseGitTempPath (len
+ 100, path
.get());
513 CDirFileEnum
finder(path
.get());
515 ::GetSystemTimeAsFileTime(&systime_
);
516 __int64 systime
= (((_int64
)systime_
.dwHighDateTime
)<<32) | ((__int64
)systime_
.dwLowDateTime
);
519 while (finder
.NextFile(filepath
, &isDir
))
521 HANDLE hFile
= ::CreateFile(filepath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, isDir
? FILE_FLAG_BACKUP_SEMANTICS
: NULL
, NULL
);
522 if (hFile
!= INVALID_HANDLE_VALUE
)
524 FILETIME createtime_
;
525 if (::GetFileTime(hFile
, &createtime_
, NULL
, NULL
))
527 ::CloseHandle(hFile
);
528 __int64 createtime
= (((_int64
)createtime_
.dwHighDateTime
)<<32) | ((__int64
)createtime_
.dwLowDateTime
);
529 if ((createtime
+ 864000000000) < systime
) //only delete files older than a day
531 ::SetFileAttributes(filepath
, FILE_ATTRIBUTE_NORMAL
);
533 ::RemoveDirectory(filepath
);
535 ::DeleteFile(filepath
);
539 ::CloseHandle(hFile
);
545 // Since the dialog has been closed, return FALSE so that we exit the
546 // application, rather than start the application's message pump.
550 void CTortoiseProcApp::CheckUpgrade()
552 CRegString regVersion
= CRegString(_T("Software\\TortoiseGit\\CurrentVersion"));
553 CString sVersion
= regVersion
;
554 if (sVersion
.Compare(_T(STRPRODUCTVER
))==0)
556 // we're starting the first time with a new version!
559 int pos
= sVersion
.Find('.');
562 lVersion
= (_ttol(sVersion
.Left(pos
))<<24);
563 lVersion
|= (_ttol(sVersion
.Mid(pos
+1))<<16);
564 pos
= sVersion
.Find('.', pos
+1);
565 lVersion
|= (_ttol(sVersion
.Mid(pos
+1))<<8);
569 pos
= sVersion
.Find(',');
572 lVersion
= (_ttol(sVersion
.Left(pos
))<<24);
573 lVersion
|= (_ttol(sVersion
.Mid(pos
+1))<<16);
574 pos
= sVersion
.Find(',', pos
+1);
575 lVersion
|= (_ttol(sVersion
.Mid(pos
+1))<<8);
580 if (CRegStdDWORD(_T("Software\\TortoiseGit\\UseLibgit2"), TRUE
) != TRUE
)
582 if (CMessageBox::Show(nullptr, _T("You have disabled the usage of libgit2 in TortoiseGit.\n\nThis might be the case in order to resolve an issue in an older TortoiseGit version.\n\nDo you want to restore the default value (i.e., enable it)?"), _T("TortoiseGit"), MB_ICONQUESTION
| MB_YESNO
) == IDYES
)
583 CRegStdDWORD(_T("Software\\TortoiseGit\\UseLibgit2")).removeValue();
586 if (CRegStdDWORD(_T("Software\\TortoiseGit\\UseLibgit2_mask")).exists())
588 if (CMessageBox::Show(nullptr, _T("You have a non-default setting of UseLibgit2_mask in your registry.\n\nThis might be the case in order to resolve an issue in an older TortoiseGit version.\n\nDo you want to restore the default value (i.e., remove custom setting from registry)?"), _T("TortoiseGit"), MB_ICONQUESTION
| MB_YESNO
) == IDYES
)
589 CRegStdDWORD(_T("Software\\TortoiseGit\\UseLibgit2_mask")).removeValue();
592 // version specific updates
593 if (lVersion
<= 0x01080802)
595 CRegStdDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\ResizableState\\CleanTypeDlgWindowPlacement")).removeValue();
598 if (lVersion
<= 0x01080801)
600 CRegStdDWORD(_T("Software\\TortoiseGit\\StatusColumns\\BrowseRefs")).removeValue();
601 CRegStdString(_T("Software\\TortoiseGit\\StatusColumns\\BrowseRefs_Order")).removeValue();
602 CRegStdString(_T("Software\\TortoiseGit\\StatusColumns\\BrowseRefs_Width")).removeValue();
605 if (lVersion
<= 0x01080401)
607 if (CRegStdDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\UseMAPI"), FALSE
) == TRUE
)
608 CRegStdDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\DeliveryType")) = 1;
609 CRegStdDWORD(_T("Software\\TortoiseGit\\TortoiseProc\\SendMail\\UseMAPI")).removeValue();
612 if (lVersion
<= 0x01080202)
614 // upgrade to 1.8.3: force recreation of all diff scripts.
615 CAppUtils::SetupDiffScripts(true, CString());
618 if (lVersion
<= 0x01080100)
620 if (CRegStdDWORD(_T("Software\\TortoiseGit\\LogTopoOrder"), TRUE
) == FALSE
)
621 CRegStdDWORD(_T("Software\\TortoiseGit\\LogOrderBy")) = 0;
623 // smoothly migrate broken msysgit path settings
624 CString oldmsysGitSetting
= CRegString(REG_MSYSGIT_PATH
);
625 oldmsysGitSetting
.TrimRight(_T("\\"));
626 CString right
= oldmsysGitSetting
.Right(4);
627 if (oldmsysGitSetting
.GetLength() > 4 && oldmsysGitSetting
.Right(4) == _T("\\cmd"))
629 CString newPath
= oldmsysGitSetting
.Mid(0, oldmsysGitSetting
.GetLength() - 3) + _T("bin");
630 if (PathFileExists(newPath
+ _T("\\git.exe")))
632 CRegString(REG_MSYSGIT_PATH
) = newPath
;
633 g_Git
.m_bInitialized
= FALSE
;
634 g_Git
.CheckMsysGitDir();
639 if (lVersion
<= 0x01040000)
641 CRegStdDWORD(_T("Software\\TortoiseGit\\OwnerdrawnMenus")).removeValue();
644 if (lVersion
<= 0x01070600)
649 CRegStdDWORD(_T("Software\\TortoiseGit\\ConvertBase")).removeValue();
650 CRegStdDWORD(_T("Software\\TortoiseGit\\DiffProps")).removeValue();
651 if (CRegStdDWORD(_T("Software\\TortoiseGit\\CheckNewer"), TRUE
) == FALSE
)
652 CRegStdDWORD(_T("Software\\TortoiseGit\\VersionCheck")) = FALSE
;
653 CRegStdDWORD(_T("Software\\TortoiseGit\\CheckNewer")).removeValue();
656 CAppUtils::SetupDiffScripts(false, CString());
658 // set the current version so we don't come here again until the next update!
659 regVersion
= _T(STRPRODUCTVER
);
662 void CTortoiseProcApp::InitializeJumpList(const CString
& appid
)
664 // for Win7 : use a custom jump list
667 DeleteJumpList(appid
);
668 DoInitializeJumpList(appid
);
672 void CTortoiseProcApp::DoInitializeJumpList(const CString
& appid
)
674 ATL::CComPtr
<ICustomDestinationList
> pcdl
;
675 HRESULT hr
= pcdl
.CoCreateInstance(CLSID_DestinationList
, NULL
, CLSCTX_INPROC_SERVER
);
679 hr
= pcdl
->SetAppID(appid
);
684 ATL::CComPtr
<IObjectArray
> poaRemoved
;
685 hr
= pcdl
->BeginList(&uMaxSlots
, IID_PPV_ARGS(&poaRemoved
));
689 ATL::CComPtr
<IObjectCollection
> poc
;
690 hr
= poc
.CoCreateInstance(CLSID_EnumerableObjectCollection
, NULL
, CLSCTX_INPROC_SERVER
);
694 CString sTemp
= CString(MAKEINTRESOURCE(IDS_MENUSETTINGS
));
695 CStringUtils::RemoveAccelerators(sTemp
);
697 ATL::CComPtr
<IShellLink
> psl
;
698 hr
= CreateShellLink(_T("/command:settings"), (LPCTSTR
)sTemp
, 20, &psl
);
702 sTemp
= CString(MAKEINTRESOURCE(IDS_MENUHELP
));
703 CStringUtils::RemoveAccelerators(sTemp
);
704 psl
.Release(); // Need to release the object before calling operator&()
705 hr
= CreateShellLink(_T("/command:help"), (LPCTSTR
)sTemp
, 19, &psl
);
710 ATL::CComPtr
<IObjectArray
> poa
;
711 hr
= poc
.QueryInterface(&poa
);
713 pcdl
->AppendCategory((LPCTSTR
)CString(MAKEINTRESOURCE(IDS_PROC_TASKS
)), poa
);
718 int CTortoiseProcApp::ExitInstance()
720 Gdiplus::GdiplusShutdown(m_gdiplusToken
);
722 CWinAppEx::ExitInstance();
728 void CTortoiseProcApp::CheckForNewerVersion()
730 // check for newer versions
731 if (CRegDWORD(_T("Software\\TortoiseGit\\VersionCheck"), TRUE
) != FALSE
)
737 if ((now
!= 0) && (localtime_s(&ptm
, &now
)==0))
740 // Check daily for new preview releases
741 CRegDWORD oldday
= CRegDWORD(_T("Software\\TortoiseGit\\CheckNewerDay"), (DWORD
)-1);
742 if (((DWORD
)oldday
) == -1)
743 oldday
= ptm
.tm_yday
;
746 if ((DWORD
)oldday
!= (DWORD
)ptm
.tm_yday
)
748 oldday
= ptm
.tm_yday
;
751 // we don't calculate the real 'week of the year' here
752 // because just to decide if we should check for an update
753 // that's not needed.
754 week
= ptm
.tm_yday
/ 7;
756 CRegDWORD oldweek
= CRegDWORD(_T("Software\\TortoiseGit\\CheckNewerWeek"), (DWORD
)-1);
757 if (((DWORD
)oldweek
) == -1)
758 oldweek
= week
; // first start of TortoiseProc, no update check needed
761 if ((DWORD
)week
!= oldweek
)
765 CAppUtils::RunTortoiseGitProc(_T("/command:updatecheck"), false, false);