Index: TortoiseBlame/TortoiseBlame.cpp
===================================================================
--- TortoiseBlame/TortoiseBlame.cpp	(revision 17099)
+++ TortoiseBlame/TortoiseBlame.cpp	(working copy)
@@ -22,6 +22,7 @@
 #include "registry.h"
 #include "LangDll.h"
 #include "auto_buffer.h"
+#include "CreateProcessHelper.h"
 
 #define MAX_LOADSTRING 1000
 
@@ -502,7 +503,7 @@
 
 	if(!bCaseSensitive)
 	{
-		makeLower(szWhat, strlen(szWhat));
+		MakeLower(szWhat, strlen(szWhat));
 	}
 
 	std::string sWhat = std::string(szWhat);
@@ -517,7 +518,7 @@
 		SendEditor(SCI_GETLINE, i, (LPARAM)linebuf.get());
 		if (!bCaseSensitive)
 		{
-			makeLower(linebuf, bufsize);
+			MakeLower(linebuf, bufsize);
 		}
 		_stprintf_s(buf, 20, _T("%ld"), revs[i]);
 		if (authors[i].compare(sWhat)==0)
@@ -539,7 +540,7 @@
 			SendEditor(SCI_GETLINE, i, (LPARAM)linebuf.get());
 			if (!bCaseSensitive)
 			{
-				makeLower(linebuf, bufsize);
+				MakeLower(linebuf, bufsize);
 			}
 			_stprintf_s(buf, 20, _T("%ld"), revs[i]);
 			if (authors[i].compare(sWhat)==0)
@@ -689,12 +690,6 @@
 	char bufLine[20];
 	_stprintf_s(bufLine, 20, _T("%d"), m_SelectedLine+1); //using the current line is a good guess.
 
-	STARTUPINFO startup;
-	PROCESS_INFORMATION process;
-	memset(&startup, 0, sizeof(startup));
-	startup.cb = sizeof(startup);
-	memset(&process, 0, sizeof(process));
-	tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
 	tstring svnCmd = _T(" /command:blame ");
 	svnCmd += _T(" /path:\"");
 	svnCmd += szOrigPath;
@@ -711,11 +706,7 @@
 		svnCmd += _T(" /ignorespaces");
 	if (bIgnoreAllSpaces)
 		svnCmd += _T(" /ignoreallspaces");
-    if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))
-	{
-		CloseHandle(process.hThread);
-		CloseHandle(process.hProcess);
-	}
+	RunCommand(svnCmd);
 }
 
 void TortoiseBlame::DiffPreviousRevision()
@@ -734,12 +725,6 @@
 	char bufEndRev[20];
 	_stprintf_s(bufEndRev, 20, _T("%d"), nRevisionTo);
 
-	STARTUPINFO startup;
-	PROCESS_INFORMATION process;
-	memset(&startup, 0, sizeof(startup));
-	startup.cb = sizeof(startup);
-	memset(&process, 0, sizeof(process));
-	tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
 	tstring svnCmd = _T(" /command:diff ");
 	svnCmd += _T(" /path:\"");
 	svnCmd += szOrigPath;
@@ -748,11 +733,7 @@
 	svnCmd += bufStartRev;
 	svnCmd += _T(" /endrev:");
 	svnCmd += bufEndRev;
-	if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))
-	{
-		CloseHandle(process.hThread);
-		CloseHandle(process.hProcess);
-	}
+	RunCommand(svnCmd);
 }
 
 void TortoiseBlame::ShowLog()
@@ -760,12 +741,6 @@
 	char bufRev[20];
 	_stprintf_s(bufRev, 20, _T("%d"), m_selectedorigrev);
 
-	STARTUPINFO startup;
-	PROCESS_INFORMATION process;
-	memset(&startup, 0, sizeof(startup));
-	startup.cb = sizeof(startup);
-	memset(&process, 0, sizeof(process));
-	tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
 	tstring svnCmd = _T(" /command:log ");
 	svnCmd += _T(" /path:\"");
 	svnCmd += szOrigPath;
@@ -774,11 +749,7 @@
 	svnCmd += bufRev;
 	svnCmd += _T(" /pegrev:");
 	svnCmd += bufRev;
-	if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))
-	{
-		CloseHandle(process.hThread);
-		CloseHandle(process.hProcess);
-	}
+	RunCommand(svnCmd);
 }
 
 void TortoiseBlame::Notify(SCNotification *notification) 
@@ -1185,7 +1156,7 @@
 	} while (cPos != NULL);
 }
 
-void TortoiseBlame::makeLower( char* buffer, size_t len )
+void TortoiseBlame::MakeLower( char* buffer, size_t len )
 {
 	for (char *p = buffer; p < buffer + len; p++)
 	{
@@ -1194,6 +1165,18 @@
 	}
 }
 
+void TortoiseBlame::RunCommand(const tstring& command)
+{
+	PROCESS_INFORMATION process;
+	memset(&process, 0, sizeof(process));
+	tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
+	if(!CCreateProcessHelper::CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(command.c_str()), &process))
+		return;
+
+	CloseHandle(process.hThread);
+	CloseHandle(process.hProcess);
+}
+
 // Forward declarations of functions included in this code module:
 ATOM				MyRegisterClass(HINSTANCE hResource);
 ATOM				MyRegisterBlameClass(HINSTANCE hResource);
Index: TortoiseBlame/TortoiseBlame.h
===================================================================
--- TortoiseBlame/TortoiseBlame.h	(revision 17099)
+++ TortoiseBlame/TortoiseBlame.h	(working copy)
@@ -160,5 +160,6 @@
 	CRegStdDWORD					m_regNewLinesColor;
 
 private:
-	static void makeLower( char* buffer, size_t length );
+	static void MakeLower( char* buffer, size_t length );
+	static void RunCommand(const tstring& command);
 };
Index: TortoiseMerge/AppUtils.cpp
===================================================================
--- TortoiseMerge/AppUtils.cpp	(revision 17099)
+++ TortoiseMerge/AppUtils.cpp	(working copy)
@@ -29,6 +29,7 @@
 #include "svn_diff.h"
 #include "svn_string.h"
 #include "svn_utf.h"
+#include "CreateProcessHelper.h"
 
 CAppUtils::CAppUtils(void)
 {
@@ -54,12 +55,8 @@
 	sSCMPath.Replace(_T("%3"), sSavePath);
 	sSCMPath.Replace(_T("%4"), sTemp);
 	// start the external SCM program to fetch the specific version of the file
-	STARTUPINFO startup;
 	PROCESS_INFORMATION process;
-	memset(&startup, 0, sizeof(startup));
-	startup.cb = sizeof(startup);
-	memset(&process, 0, sizeof(process));
-	if (CreateProcess(NULL, (LPTSTR)(LPCTSTR)sSCMPath, NULL, NULL, FALSE, 0, 0, 0, &startup, &process)==0)
+	if (!CCreateProcessHelper::CreateProcess(NULL, (LPTSTR)(LPCTSTR)sSCMPath, &process))
 	{
 		LPVOID lpMsgBuf;
 		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
@@ -220,7 +217,3 @@
 	}
 	return false;
 }
-
-
-
-
Index: TortoiseMerge/BaseView.cpp
===================================================================
--- TortoiseMerge/BaseView.cpp	(revision 17099)
+++ TortoiseMerge/BaseView.cpp	(working copy)
@@ -101,26 +101,17 @@
 	{
 		m_apFonts[i] = NULL;
 	}
-	m_hConflictedIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_CONFLICTEDLINE), 
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hConflictedIgnoredIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_CONFLICTEDIGNOREDLINE), 
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hRemovedIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_REMOVEDLINE), 
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hAddedIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ADDEDLINE), 
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hWhitespaceBlockIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_WHITESPACELINE),
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hEqualIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_EQUALLINE),
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hLineEndingCR = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_LINEENDINGCR),
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hLineEndingCRLF = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_LINEENDINGCRLF),
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hLineEndingLF = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_LINEENDINGLF),
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
-	m_hEditedIcon = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_LINEEDITED),
-									IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+	m_hConflictedIcon = LoadIcon(IDI_CONFLICTEDLINE);
+	m_hConflictedIgnoredIcon = LoadIcon(IDI_CONFLICTEDIGNOREDLINE); 
+	m_hRemovedIcon = LoadIcon(IDI_REMOVEDLINE);
+	m_hAddedIcon = LoadIcon(IDI_ADDEDLINE);
+	m_hWhitespaceBlockIcon = LoadIcon(IDI_WHITESPACELINE);
+	m_hEqualIcon = LoadIcon(IDI_EQUALLINE);
+	m_hLineEndingCR = LoadIcon(IDI_LINEENDINGCR);
+	m_hLineEndingCRLF = LoadIcon(IDI_LINEENDINGCRLF);
+	m_hLineEndingLF = LoadIcon(IDI_LINEENDINGLF);
+	m_hEditedIcon = LoadIcon(IDI_LINEEDITED);
+
 	for (int i=0; i<1024; ++i)
 		m_sConflictedText += _T("??");
 	m_sNoLineNr.LoadString(IDS_EMPTYLINETT);
@@ -129,11 +120,7 @@
 
 CBaseView::~CBaseView()
 {
-	if (m_pCacheBitmap)
-	{
-		m_pCacheBitmap->DeleteObject();
-		delete m_pCacheBitmap;
-	}
+	ReleaseBitmap();
 	DeleteFonts();
 	DestroyIcon(m_hAddedIcon);
 	DestroyIcon(m_hRemovedIcon);
@@ -186,12 +173,7 @@
 
 void CBaseView::DocumentUpdated()
 {
-	if (m_pCacheBitmap != NULL)
-	{
-		m_pCacheBitmap->DeleteObject();
-		delete m_pCacheBitmap;
-		m_pCacheBitmap = NULL;
-	}
+	ReleaseBitmap();
 	m_nLineHeight = -1;
 	m_nCharWidth = -1;
 	m_nScreenChars = -1;
@@ -588,7 +570,6 @@
 
 bool CBaseView::IsBlockWhitespaceOnly(int nLineIndex, bool& bIdentical)
 {
-	enum { MAX_WHITESPACEBLOCK_SIZE	= 8 };
 	CheckOtherView();
 	if (!m_pOtherViewData)
 		return false;
@@ -596,11 +577,15 @@
 		(m_pViewData->GetState(nLineIndex) == DIFFSTATE_NORMAL) &&
 		(m_pOtherViewData->GetLine(nLineIndex) == m_pViewData->GetLine(nLineIndex))
 		)
+	{
 		return false;
+	}
 
 	CString mine = GetWhitespaceBlock(m_pViewData, nLineIndex);
 	CString other;
-	if (!mine.IsEmpty())
+	if (mine.IsEmpty())
+		bIdentical = false;
+	else
 	{
 		other = GetWhitespaceBlock(m_pOtherViewData, min(nLineIndex, m_pOtherViewData->GetCount() - 1));
 		bIdentical = mine == other;
@@ -613,10 +598,8 @@
 		other.Replace(_T("\r"), _T(""));
 		other.Replace(_T("\n"), _T(""));
 	}
-	else
-		bIdentical = false;
-		
-	return (mine == other) && (!mine.IsEmpty());
+
+	return (!mine.IsEmpty()) && (mine == other);
 }
 
 int CBaseView::GetLineNumber(int index) const
@@ -1658,21 +1641,12 @@
 {
 	CView::OnDestroy();
 	DeleteFonts();
-	if (m_pCacheBitmap != NULL)
-	{
-		delete m_pCacheBitmap;
-		m_pCacheBitmap = NULL;
-	}
+	ReleaseBitmap();
 }
 
 void CBaseView::OnSize(UINT nType, int cx, int cy)
 {
-	if (m_pCacheBitmap != NULL)
-	{
-		m_pCacheBitmap->DeleteObject();
-		delete m_pCacheBitmap;
-		m_pCacheBitmap = NULL;
-	}
+	ReleaseBitmap();
 	// make sure the view header is redrawn
 	CRect rcScroll;
 	GetClientRect(&rcScroll);
@@ -2426,27 +2400,28 @@
 
 void CBaseView::ShowDiffLines(int nLine)
 {
-	if ((nLine >= m_nTopLine)&&(nLine < GetLineCount()))
+	if ((nLine < m_nTopLine)||(nLine >= GetLineCount()))
 	{
-		if ((m_pwndRight)&&(m_pwndRight->m_pViewData)&&(m_pwndLeft)&&(m_pwndLeft->m_pViewData)&&(!m_pMainFrame->m_bOneWay))
-		{
-			nLine = (nLine > m_pwndRight->m_pViewData->GetCount() ? -1 : nLine);
-			nLine = (nLine > m_pwndLeft->m_pViewData->GetCount() ? -1 : nLine);
-
-			if (nLine >= 0)
-			{
-				if (nLine != m_nMouseLine)
-				{
-					m_nMouseLine = nLine;
-					if (nLine >= GetLineCount())
-						nLine = -1;
-					m_pwndLineDiffBar->ShowLines(nLine);
-				}
-			}
-		}
+		m_pwndLineDiffBar->ShowLines(nLine);
+		return;
 	}
-	else
+
+	if ((!m_pwndRight)||(!m_pwndRight->m_pViewData)||(!m_pwndLeft)||(!m_pwndLeft->m_pViewData))
+		return;
+	if(m_pMainFrame->m_bOneWay)
+		return;
+
+	nLine = (nLine > m_pwndRight->m_pViewData->GetCount() ? -1 : nLine);
+	nLine = (nLine > m_pwndLeft->m_pViewData->GetCount() ? -1 : nLine);
+
+	if (nLine < 0)
+		return;
+
+	if (nLine != m_nMouseLine)
 	{
+		m_nMouseLine = nLine;
+		if (nLine >= GetLineCount())
+			nLine = -1;
 		m_pwndLineDiffBar->ShowLines(nLine);
 	}
 }
@@ -2743,7 +2718,9 @@
 
 	if ((::GetKeyState(VK_LBUTTON) & 0x8000) != 0 ||
 		(::GetKeyState(VK_RBUTTON) & 0x8000) != 0)
+	{
 		return;
+	}
 
 	if ((nChar > 31)||(nChar == VK_TAB))
 	{
@@ -3166,3 +3143,20 @@
 		point = rect.CenterPoint();
 	}
 }
+
+HICON CBaseView::LoadIcon(WORD iconId)
+{
+	HANDLE icon = ::LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE(iconId), 
+						IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+	return (HICON)icon;
+}
+
+void CBaseView::ReleaseBitmap()
+{
+	if (m_pCacheBitmap != NULL)
+	{
+		m_pCacheBitmap->DeleteObject();
+		delete m_pCacheBitmap;
+		m_pCacheBitmap = NULL;
+	}
+}
Index: TortoiseMerge/BaseView.h
===================================================================
--- TortoiseMerge/BaseView.h	(revision 17099)
+++ TortoiseMerge/BaseView.h	(working copy)
@@ -306,4 +306,6 @@
 	UINT GetMenuFlags(DiffStates state) const;
 	void AddCutCopyAndPaste(CMenu& popup);
 	void CompensateForKeyboard(CPoint& point);
+	static HICON LoadIcon(WORD iconId);
+	void ReleaseBitmap();
 };
Index: TortoiseMerge/MainFrm.cpp
===================================================================
--- TortoiseMerge/MainFrm.cpp	(revision 17099)
+++ TortoiseMerge/MainFrm.cpp	(working copy)
@@ -33,6 +33,7 @@
 #include ".\mainfrm.h"
 #include "auto_buffer.h"
 #include "StringUtils.h"
+#include "CreateProcessHelper.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -911,12 +912,13 @@
 	m_bHasConflicts = true;
 	if (m_pwndBottomView->IsWindowVisible())
 	{
-		if (m_pwndBottomView->m_pViewData)
+		CViewData* viewdata = m_pwndBottomView->m_pViewData;
+		if (viewdata)
 		{
-			for (int i=0; i<m_pwndBottomView->m_pViewData->GetCount(); i++)
+			for (int i=0; i<viewdata->GetCount(); i++)
 			{
-				if ((DIFFSTATE_CONFLICTED == m_pwndBottomView->m_pViewData->GetState(i))||
-					(DIFFSTATE_CONFLICTED_IGNORED == m_pwndBottomView->m_pViewData->GetState(i)))
+				const DiffStates state = viewdata->GetState(i);
+				if ((DIFFSTATE_CONFLICTED == state)||(DIFFSTATE_CONFLICTED_IGNORED == state))
 					return i;
 			}
 		}
@@ -1068,30 +1070,8 @@
 		cmd += m_Data.m_mergedFile.GetFilename() + _T("\"");
 		auto_buffer<TCHAR> buf(cmd.GetLength()+1);
 		_tcscpy_s(buf, cmd.GetLength()+1, cmd);
-		STARTUPINFO startup;
-		PROCESS_INFORMATION process;
-		memset(&startup, 0, sizeof(startup));
-		startup.cb = sizeof(startup);
-		memset(&process, 0, sizeof(process));
-		if (CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, 0, 0, &startup, &process)==0)
-		{
-			LPVOID lpMsgBuf;
-			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-				FORMAT_MESSAGE_FROM_SYSTEM | 
-				FORMAT_MESSAGE_IGNORE_INSERTS,
-				NULL,
-				GetLastError(),
-				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-				(LPTSTR) &lpMsgBuf,
-				0,
-				NULL 
-				);
-			MessageBox((LPCTSTR)lpMsgBuf, _T("TortoiseMerge"), MB_OK | MB_ICONINFORMATION);
-			LocalFree( lpMsgBuf );
+		if(!RunCommand(buf))
 			return FALSE;
-		}
-		CloseHandle(process.hThread);
-		CloseHandle(process.hProcess);
 	}
 	return true;
 }
@@ -1191,7 +1171,6 @@
 	pCmdUI->Enable(bEnable);
 }
 
-
 void CMainFrame::OnUpdateViewOnewaydiff(CCmdUI *pCmdUI)
 {
 	pCmdUI->SetCheck(!m_bOneWay);
@@ -1498,15 +1477,15 @@
 
 void CMainFrame::OnViewLinedown()
 {
-	onViewLineUpDown(1);
+	OnViewLineUpDown(1);
 }
 
 void CMainFrame::OnViewLineup()
 {
-	onViewLineUpDown(-1);
+	OnViewLineUpDown(-1);
 }
 
-void CMainFrame::onViewLineUpDown(int direction)
+void CMainFrame::OnViewLineUpDown(int direction)
 {
 	if (m_pwndLeftView)
 		m_pwndLeftView->ScrollToLine(m_pwndLeftView->m_nTopLine+direction);
@@ -1519,15 +1498,15 @@
 
 void CMainFrame::OnViewLineleft()
 {
-	onViewLineLeftRight(-1);
+	OnViewLineLeftRight(-1);
 }
 
 void CMainFrame::OnViewLineright()
 {
-	onViewLineLeftRight(1);
+	OnViewLineLeftRight(1);
 }
 
-void CMainFrame::onViewLineLeftRight(int direction)
+void CMainFrame::OnViewLineLeftRight(int direction)
 {
 	if (m_pwndLeftView)
 		m_pwndLeftView->ScrollSide(direction);
@@ -1756,43 +1735,19 @@
 {
 	if (m_bReadOnly)
 		return FALSE;
-	if ((m_pwndBottomView)&&(m_pwndBottomView->IsWindowVisible()))
-	{
-		TCHAR buf[MAX_PATH*3];
-		GetModuleFileName(NULL, buf, MAX_PATH);
-		TCHAR * end = _tcsrchr(buf, '\\');
-		end++;
-		(*end) = 0;
-		_tcscat_s(buf, MAX_PATH*3, _T("TortoiseProc.exe /command:resolve /path:\""));
-		_tcscat_s(buf, MAX_PATH*3, m_Data.m_mergedFile.GetFilename());
-		_tcscat_s(buf, MAX_PATH*3, _T("\" /closeonend:1 /noquestion /skipcheck"));
-		STARTUPINFO startup;
-		PROCESS_INFORMATION process;
-		memset(&startup, 0, sizeof(startup));
-		startup.cb = sizeof(startup);
-		memset(&process, 0, sizeof(process));
-		if (CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, 0, 0, &startup, &process)==0)
-		{
-			LPVOID lpMsgBuf;
-			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-				FORMAT_MESSAGE_FROM_SYSTEM | 
-				FORMAT_MESSAGE_IGNORE_INSERTS,
-				NULL,
-				GetLastError(),
-				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-				(LPTSTR) &lpMsgBuf,
-				0,
-				NULL 
-				);
-			MessageBox((LPCTSTR)lpMsgBuf, _T("TortoiseMerge"), MB_OK | MB_ICONINFORMATION);
-			LocalFree( lpMsgBuf );
-			return FALSE;
-		}
-		CloseHandle(process.hThread);
-		CloseHandle(process.hProcess);
-	}
-	else
+	if ((!m_pwndBottomView)||(!m_pwndBottomView->IsWindowVisible()))
 		return FALSE;
+
+	TCHAR buf[MAX_PATH*3];
+	GetModuleFileName(NULL, buf, MAX_PATH);
+	TCHAR * end = _tcsrchr(buf, '\\');
+	end++;
+	(*end) = 0;
+	_tcscat_s(buf, MAX_PATH*3, _T("TortoiseProc.exe /command:resolve /path:\""));
+	_tcscat_s(buf, MAX_PATH*3, m_Data.m_mergedFile.GetFilename());
+	_tcscat_s(buf, MAX_PATH*3, _T("\" /closeonend:1 /noquestion /skipcheck"));
+	if(!RunCommand(buf))
+		return FALSE;
 	return TRUE;
 }
 
@@ -2041,3 +1996,28 @@
 	m_wndLineDiffBar.DocumentUpdated();
 }
 
+bool CMainFrame::RunCommand(TCHAR* command)
+{
+	PROCESS_INFORMATION process;
+	if(CCreateProcessHelper::CreateProcess(NULL, buf, &process))
+	{
+		CloseHandle(process.hThread);
+		CloseHandle(process.hProcess);
+		return true;
+	}
+
+	LPVOID lpMsgBuf;
+	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+		FORMAT_MESSAGE_FROM_SYSTEM | 
+		FORMAT_MESSAGE_IGNORE_INSERTS,
+		NULL,
+		GetLastError(),
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+		(LPTSTR) &lpMsgBuf,
+		0,
+		NULL 
+		);
+	MessageBox((LPCTSTR)lpMsgBuf, _T("TortoiseMerge"), MB_OK | MB_ICONINFORMATION);
+	LocalFree( lpMsgBuf );
+	return false;
+}
Index: TortoiseMerge/MainFrm.h
===================================================================
--- TortoiseMerge/MainFrm.h	(revision 17099)
+++ TortoiseMerge/MainFrm.h	(working copy)
@@ -179,6 +179,7 @@
 	void			ShowDiffBar(bool bShow);
 
 private:
-	void onViewLineUpDown(int direction);
-	void onViewLineLeftRight(int direction);
+	void OnViewLineUpDown(int direction);
+	void OnViewLineLeftRight(int direction);
+	static bool RunCommand(TCHAR* command);
 };
Index: TortoiseProc/AppUtils.cpp
===================================================================
--- TortoiseProc/AppUtils.cpp	(revision 17099)
+++ TortoiseProc/AppUtils.cpp	(working copy)
@@ -32,6 +32,7 @@
 #include <intshcut.h>
 #include "auto_buffer.h"
 #include "StringUtils.h"
+#include "CreateProcessHelper.h"
 
 CAppUtils::CAppUtils(void)
 {
@@ -533,15 +534,9 @@
 
 bool CAppUtils::LaunchApplication(const CString& sCommandLine, UINT idErrMessageFormat, bool bWaitForStartup)
 {
-	STARTUPINFO startup;
 	PROCESS_INFORMATION process;
-	memset(&startup, 0, sizeof(startup));
-	startup.cb = sizeof(startup);
-	memset(&process, 0, sizeof(process));
-
 	CString cleanCommandLine(sCommandLine);
-
-	if (CreateProcess(NULL, const_cast<TCHAR*>((LPCTSTR)cleanCommandLine), NULL, NULL, FALSE, 0, 0, sOrigCWD, &startup, &process)==0)
+	if (!CCreateProcessHelper::CreateProcess(NULL, const_cast<TCHAR*>((LPCTSTR)cleanCommandLine), sOrigCWD, &process))
 	{
 		if(idErrMessageFormat != 0)
 		{
Index: TortoiseShell/ContextMenu.cpp
===================================================================
--- TortoiseShell/ContextMenu.cpp	(revision 17099)
+++ TortoiseShell/ContextMenu.cpp	(working copy)
@@ -24,6 +24,7 @@
 #include "SVNProperties.h"
 #include "SVNStatus.h"
 #include "auto_buffer.h"
+#include "CreateProcessHelper.h"
 
 #define GetPIDLFolder(pida) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[0])
 #define GetPIDLItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1])
@@ -1235,616 +1236,576 @@
 	if (lpcmi == NULL)
 		return hr;
 
+	if(files_.empty()&&folder_.empty())
+		return hr;
+
 	std::string command;
 	std::string parent;
 	std::string file;
+	
+	UINT_PTR idCmd = LOWORD(lpcmi->lpVerb);
 
-	if ((files_.size() > 0)||(folder_.size() > 0))
+	if (HIWORD(lpcmi->lpVerb))
 	{
-		UINT_PTR idCmd = LOWORD(lpcmi->lpVerb);
+		tstring verb = tstring(MultibyteToWide(lpcmi->lpVerb));
+		std::map<tstring, UINT_PTR>::const_iterator verb_it = myVerbsMap.lower_bound(verb);
+		if (verb_it != myVerbsMap.end() && verb_it->first == verb)
+			idCmd = verb_it->second;
+		else
+			return hr;
+	}
 
-		if (HIWORD(lpcmi->lpVerb))
+	// See if we have a handler interface for this id
+	std::map<UINT_PTR, UINT_PTR>::const_iterator id_it = myIDMap.lower_bound(idCmd);
+	if (id_it != myIDMap.end() && id_it->first == idCmd)
+	{
+		tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
+		tstring tortoiseMergePath = GetAppDirectory() + _T("TortoiseMerge.exe");
+		tstring cwdFolder;
+		if (folder_.empty() && files_.empty())
 		{
-			tstring verb = tstring(MultibyteToWide(lpcmi->lpVerb));
-			std::map<tstring, UINT_PTR>::const_iterator verb_it = myVerbsMap.lower_bound(verb);
-			if (verb_it != myVerbsMap.end() && verb_it->first == verb)
-				idCmd = verb_it->second;
-			else
-				return hr;
+			// use the users desktop path as the CWD
+			TCHAR desktopDir[MAX_PATH] = {0};
+			SHGetSpecialFolderPath(lpcmi->hwnd, desktopDir, CSIDL_DESKTOPDIRECTORY, TRUE);
+			cwdFolder = desktopDir;
 		}
-
-		// See if we have a handler interface for this id
-		std::map<UINT_PTR, UINT_PTR>::const_iterator id_it = myIDMap.lower_bound(idCmd);
-		if (id_it != myIDMap.end() && id_it->first == idCmd)
+		else
 		{
-			STARTUPINFO startup;
-			PROCESS_INFORMATION process;
-			memset(&startup, 0, sizeof(startup));
-			startup.cb = sizeof(startup);
-			memset(&process, 0, sizeof(process));
-			tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
-			tstring tortoiseMergePath = GetAppDirectory() + _T("TortoiseMerge.exe");
-			tstring cwdFolder;
-			if (folder_.empty() && files_.empty())
+			cwdFolder = folder_.empty() ? files_[0] : folder_;
+			if (!PathIsDirectory(cwdFolder.c_str()))
 			{
-				// use the users desktop path as the CWD
-				TCHAR desktopDir[MAX_PATH] = {0};
-				SHGetSpecialFolderPath(lpcmi->hwnd, desktopDir, CSIDL_DESKTOPDIRECTORY, TRUE);
-				cwdFolder = desktopDir;
+				cwdFolder = cwdFolder.substr(0, cwdFolder.rfind('\\'));
 			}
-			else
-			{
-				cwdFolder = folder_.empty() ? files_[0] : folder_;
-				if (!PathIsDirectory(cwdFolder.c_str()))
-				{
-					cwdFolder = cwdFolder.substr(0, cwdFolder.rfind('\\'));
-				}
-			}
+		}
 
-			//TortoiseProc expects a command line of the form:
-			//"/command:<commandname> /pathfile:<path> /startrev:<startrevision> /endrev:<endrevision> /deletepathfile
-			// or
-			//"/command:<commandname> /path:<path> /startrev:<startrevision> /endrev:<endrevision>
-			//
-			//* path is a path to a single file/directory for commands which only act on single items (log, checkout, ...)
-			//* pathfile is a path to a temporary file which contains a list of file paths
-			tstring svnCmd = _T(" /command:");
-			tstring tempfile;
-			switch (id_it->second)
-			{
-				//#region case
-			case ShellMenuCheckout:
-				svnCmd += _T("checkout /path:\"");
+		//TortoiseProc expects a command line of the form:
+		//"/command:<commandname> /pathfile:<path> /startrev:<startrevision> /endrev:<endrevision> /deletepathfile
+		// or
+		//"/command:<commandname> /path:<path> /startrev:<startrevision> /endrev:<endrevision>
+		//
+		//* path is a path to a single file/directory for commands which only act on single items (log, checkout, ...)
+		//* pathfile is a path to a temporary file which contains a list of file paths
+		tstring svnCmd = _T(" /command:");
+		tstring tempfile;
+		switch (id_it->second)
+		{
+			//#region case
+		case ShellMenuCheckout:
+			svnCmd += _T("checkout /path:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuUpdate:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("update /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuUpdateExt:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("update /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /rev");
+			break;
+		case ShellMenuCommit:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("commit /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuAdd:
+		case ShellMenuAddAsReplacement:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("add /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuIgnore:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("ignore /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuIgnoreCaseSensitive:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("ignore /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /onlymask");
+			break;
+		case ShellMenuDeleteIgnore:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("ignore /delete /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuDeleteIgnoreCaseSensitive:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("ignore /delete /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /onlymask");
+			break;
+		case ShellMenuUnIgnore:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("unignore /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuUnIgnoreCaseSensitive:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("unignore /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /onlymask");
+			break;
+		case ShellMenuRevert:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("revert /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuDelUnversioned:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("delunversioned /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuCleanup:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("cleanup /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuResolve:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("resolve /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuSwitch:
+			svnCmd += _T("switch /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuUpdate:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("update /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuUpdateExt:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("update /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /rev");
-				break;
-			case ShellMenuCommit:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("commit /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuAdd:
-			case ShellMenuAddAsReplacement:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("add /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuIgnore:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("ignore /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuIgnoreCaseSensitive:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("ignore /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /onlymask");
-				break;
-			case ShellMenuDeleteIgnore:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("ignore /delete /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuDeleteIgnoreCaseSensitive:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("ignore /delete /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /onlymask");
-				break;
-			case ShellMenuUnIgnore:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("unignore /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuUnIgnoreCaseSensitive:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("unignore /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /onlymask");
-				break;
-			case ShellMenuRevert:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("revert /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuDelUnversioned:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("delunversioned /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuCleanup:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("cleanup /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuResolve:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("resolve /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuSwitch:
-				svnCmd += _T("switch /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuImport:
-				svnCmd += _T("import /path:\"");
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuImport:
+			svnCmd += _T("import /path:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuExport:
+			svnCmd += _T("export /path:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuAbout:
+			svnCmd += _T("about");
+			break;
+		case ShellMenuCreateRepos:
+			svnCmd += _T("repocreate /path:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuMerge:
+			svnCmd += _T("merge /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuExport:
-				svnCmd += _T("export /path:\"");
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuMergeAll:
+			svnCmd += _T("mergeall /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuAbout:
-				svnCmd += _T("about");
-				break;
-			case ShellMenuCreateRepos:
-				svnCmd += _T("repocreate /path:\"");
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuCopy:
+			svnCmd += _T("copy /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuMerge:
-				svnCmd += _T("merge /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuMergeAll:
-				svnCmd += _T("mergeall /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuCopy:
-				svnCmd += _T("copy /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuSettings:
-				svnCmd += _T("settings");
-				break;
-			case ShellMenuHelp:
-				svnCmd += _T("help");
-				break;
-			case ShellMenuRename:
-				svnCmd += _T("rename /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuRemove:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("remove /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuRemoveKeep:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("remove /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /keep");
-				break;
-			case ShellMenuDiff:
-				svnCmd += _T("diff /path:\"");
-				if (files_.size() == 1)
-					svnCmd += files_.front();
-				else if (files_.size() == 2)
-				{
-					std::vector<tstring>::iterator I = files_.begin();
-					svnCmd += *I;
-					I++;
-					svnCmd += _T("\" /path2:\"");
-					svnCmd += *I;
-				}
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
-					svnCmd += _T(" /alternative");
-				break;
-			case ShellMenuPrevDiff:
-				svnCmd += _T("prevdiff /path:\"");
-				if (files_.size() == 1)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
-					svnCmd += _T(" /alternative");
-				break;
-			case ShellMenuUrlDiff:
-				svnCmd += _T("urldiff /path:\"");
-				if (files_.size() == 1)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuDropCopyAdd:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("dropcopyadd /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /droptarget:\"");
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuSettings:
+			svnCmd += _T("settings");
+			break;
+		case ShellMenuHelp:
+			svnCmd += _T("help");
+			break;
+		case ShellMenuRename:
+			svnCmd += _T("rename /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"";)
-					break;
-			case ShellMenuDropCopy:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("dropcopy /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /droptarget:\"");
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuRemove:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("remove /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuRemoveKeep:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("remove /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /keep");
+			break;
+		case ShellMenuDiff:
+			svnCmd += _T("diff /path:\"");
+			if (files_.size() == 1)
+				svnCmd += files_.front();
+			else if (files_.size() == 2)
+			{
+				std::vector<tstring>::iterator I = files_.begin();
+				svnCmd += *I;
+				I++;
+				svnCmd += _T("\" /path2:\"");
+				svnCmd += *I;
+			}
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"";)
-					break;
-			case ShellMenuDropCopyRename:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("dropcopy /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /droptarget:\"");
+			svnCmd += _T("\"");
+			if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
+				svnCmd += _T(" /alternative");
+			break;
+		case ShellMenuPrevDiff:
+			svnCmd += _T("prevdiff /path:\"");
+			if (files_.size() == 1)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\" /rename";)
-					break;
-			case ShellMenuDropMove:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("dropmove /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /droptarget:\"");
+			svnCmd += _T("\"");
+			if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
+				svnCmd += _T(" /alternative");
+			break;
+		case ShellMenuUrlDiff:
+			svnCmd += _T("urldiff /path:\"");
+			if (files_.size() == 1)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuDropMoveRename:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("dropmove /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /droptarget:\"");
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuDropCopyAdd:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("dropcopyadd /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /droptarget:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuDropCopy:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("dropcopy /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /droptarget:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuDropCopyRename:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("dropcopy /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /droptarget:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\" /rename";)
+			break;
+		case ShellMenuDropMove:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("dropmove /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /droptarget:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuDropMoveRename:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("dropmove /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /droptarget:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\" /rename";)
+			break;
+		case ShellMenuDropExport:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("dropexport /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /droptarget:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuDropExportExtended:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("dropexport /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /droptarget:\"");
+			svnCmd += folder_;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /extended");
+			break;
+		case ShellMenuLog:
+			svnCmd += _T("log /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\" /rename";)
-				break;
-			case ShellMenuDropExport:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("dropexport /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /droptarget:\"");
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuConflictEditor:
+			svnCmd += _T("conflicteditor /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuDropExportExtended:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("dropexport /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /droptarget:\"");
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuRelocate:
+			svnCmd += _T("relocate /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
 				svnCmd += folder_;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /extended");
-				break;
-			case ShellMenuLog:
-				svnCmd += _T("log /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuConflictEditor:
-				svnCmd += _T("conflicteditor /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuRelocate:
-				svnCmd += _T("relocate /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuShowChanged:
-				if (files_.size() > 1)
-                {
-				    tempfile = WriteFileListToTempFile();
-				    svnCmd += _T("repostatus /pathfile:\"");
-				    svnCmd += tempfile;
-    				svnCmd += _T("\"");
-    				svnCmd += _T(" /deletepathfile");
-                }
-                else
-                {
-                    svnCmd += _T("repostatus /path:\"");
-				    if (files_.size() > 0)
-					    svnCmd += files_.front();
-				    else
-					    svnCmd += folder_;
-    				svnCmd += _T("\"");
-                }
-				break;
-			case ShellMenuRepoBrowse:
-				svnCmd += _T("repobrowser /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuBlame:
-				svnCmd += _T("blame /path:\"");
-				if (files_.size() > 0)
-					svnCmd += files_.front();
-				else
-					svnCmd += folder_;
-				svnCmd += _T("\"");
-				break;
-			case ShellMenuCreatePatch:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("createpatch /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuApplyPatch:
-				if ((itemStates & ITEMIS_PATCHINCLIPBOARD) && ((~itemStates) & ITEMIS_PATCHFILE))
-				{
-					// if there's a patch file in the clipboard, we save it
-					// to a temporary file and tell TortoiseMerge to use that one
-					UINT cFormat = RegisterClipboardFormat(_T("TSVN_UNIFIEDDIFF"));
-					if ((cFormat)&&(OpenClipboard(NULL)))
-					{ 
-						HGLOBAL hglb = GetClipboardData(cFormat); 
-						LPCSTR lpstr = (LPCSTR)GlobalLock(hglb); 
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuShowChanged:
+			if (files_.size() > 1)
+			{
+			    tempfile = WriteFileListToTempFile();
+			    svnCmd += _T("repostatus /pathfile:\"");
+			    svnCmd += tempfile;
+    			svnCmd += _T("\"");
+    			svnCmd += _T(" /deletepathfile");
+			}
+			else
+			{
+				svnCmd += _T("repostatus /path:\"");
+				if(files_.size() > 0)
+				    svnCmd += files_.front();
+				   else
+				    svnCmd += folder_;
+    			svnCmd += _T("\"");
+			}
+			break;
+		case ShellMenuRepoBrowse:
+			svnCmd += _T("repobrowser /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
+				svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuBlame:
+			svnCmd += _T("blame /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
+				svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuCreatePatch:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("createpatch /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuApplyPatch:
+			if ((itemStates & ITEMIS_PATCHINCLIPBOARD) && ((~itemStates) & ITEMIS_PATCHFILE))
+			{
+				// if there's a patch file in the clipboard, we save it
+				// to a temporary file and tell TortoiseMerge to use that one
+				UINT cFormat = RegisterClipboardFormat(_T("TSVN_UNIFIEDDIFF"));
+				if ((cFormat)&&(OpenClipboard(NULL)))
+				{ 
+					HGLOBAL hglb = GetClipboardData(cFormat); 
+					LPCSTR lpstr = (LPCSTR)GlobalLock(hglb); 
 
-						DWORD len = GetTempPath(0, NULL);
-						auto_buffer<TCHAR> path(len+1);
-						auto_buffer<TCHAR> tempF(len+100);
-						GetTempPath (len+1, path);
-						GetTempFileName (path, TEXT("svn"), 0, tempF);
-						std::wstring sTempFile = std::wstring(tempF);
+					DWORD len = GetTempPath(0, NULL);
+					auto_buffer<TCHAR> path(len+1);
+					auto_buffer<TCHAR> tempF(len+100);
+					GetTempPath (len+1, path);
+					GetTempFileName (path, TEXT("svn"), 0, tempF);
+					std::wstring sTempFile = std::wstring(tempF);
 
-						FILE * outFile;
-						size_t patchlen = strlen(lpstr);
-						_tfopen_s(&outFile, sTempFile.c_str(), _T("wb"));
-						if(outFile)
-						{
-							size_t size = fwrite(lpstr, sizeof(char), patchlen, outFile);
-							if (size == patchlen)
-							{
-								itemStates |= ITEMIS_PATCHFILE;
-								files_.clear();
-								files_.push_back(sTempFile);
-							}
-							fclose(outFile);
-						}
-						GlobalUnlock(hglb); 
-						CloseClipboard(); 
-					} 
-				}
-				if (itemStates & ITEMIS_PATCHFILE)
-				{
-					svnCmd = _T(" /diff:\"");
-					if (files_.size() > 0)
+					FILE * outFile;
+					size_t patchlen = strlen(lpstr);
+					_tfopen_s(&outFile, sTempFile.c_str(), _T("wb"));
+					if(outFile)
 					{
-						svnCmd += files_.front();
-						if (itemStatesFolder & ITEMIS_FOLDERINSVN)
+						size_t size = fwrite(lpstr, sizeof(char), patchlen, outFile);
+						if (size == patchlen)
 						{
-							svnCmd += _T("\" /patchpath:\"");
-							svnCmd += folder_;
+							itemStates |= ITEMIS_PATCHFILE;
+							files_.clear();
+							files_.push_back(sTempFile);
 						}
+						fclose(outFile);
 					}
-					else
+					GlobalUnlock(hglb); 
+					CloseClipboard(); 
+				} 
+			}
+			if (itemStates & ITEMIS_PATCHFILE)
+			{
+				svnCmd = _T(" /diff:\"");
+				if (files_.size() > 0)
+				{
+					svnCmd += files_.front();
+					if (itemStatesFolder & ITEMIS_FOLDERINSVN)
+					{
+						svnCmd += _T("\" /patchpath:\"");
 						svnCmd += folder_;
-					if (itemStates & ITEMIS_INVERSIONEDFOLDER)
-						svnCmd += _T("\" /wc");
-					else
-						svnCmd += _T("\"");
+					}
 				}
 				else
-				{
-					svnCmd = _T(" /patchpath:\"");
-					if (files_.size() > 0)
-						svnCmd += files_.front();
-					else
-						svnCmd += folder_;
+					svnCmd += folder_;
+				if (itemStates & ITEMIS_INVERSIONEDFOLDER)
+					svnCmd += _T("\" /wc");
+				else
 					svnCmd += _T("\"");
-				}
-				myIDMap.clear();
-				myVerbsIDMap.clear();
-				myVerbsMap.clear();
-				if (CreateProcess(tortoiseMergePath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, cwdFolder.c_str(), &startup, &process)==0)
-				{
-					LPVOID lpMsgBuf;
-					FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-						FORMAT_MESSAGE_FROM_SYSTEM | 
-						FORMAT_MESSAGE_IGNORE_INSERTS,
-						NULL,
-						GetLastError(),
-						MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-						(LPTSTR) &lpMsgBuf,
-						0,
-						NULL 
-						);
-					MessageBox( NULL, (LPCTSTR)lpMsgBuf, _T("TortoiseMerge launch failed"), MB_OK | MB_ICONINFORMATION );
-					LocalFree( lpMsgBuf );
-				}
-				CloseHandle(process.hThread);
-				CloseHandle(process.hProcess);
-				return NOERROR;
-				break;
-			case ShellMenuRevisionGraph:
-				svnCmd += _T("revisiongraph /path:\"");
+			}
+			else
+			{
+				svnCmd = _T(" /patchpath:\"");
 				if (files_.size() > 0)
 					svnCmd += files_.front();
 				else
 					svnCmd += folder_;
 				svnCmd += _T("\"");
-				break;
-			case ShellMenuLock:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("lock /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuUnlock:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("unlock /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuUnlockForce:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("unlock /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				svnCmd += _T(" /force");
-				break;
-			case ShellMenuProperties:
-				tempfile = WriteFileListToTempFile();
-				svnCmd += _T("properties /pathfile:\"");
-				svnCmd += tempfile;
-				svnCmd += _T("\"");
-				svnCmd += _T(" /deletepathfile");
-				break;
-			case ShellMenuClipPaste:
-				if (WriteClipboardPathsToTempFile(tempfile))
+			}
+			myIDMap.clear();
+			myVerbsIDMap.clear();
+			myVerbsMap.clear();
+			RunCommand(tortoiseMergePath, svnCmd, cwdFolder, _T("TortoiseMerge launch failed") );
+			return NOERROR;
+		case ShellMenuRevisionGraph:
+			svnCmd += _T("revisiongraph /path:\"");
+			if (files_.size() > 0)
+				svnCmd += files_.front();
+			else
+				svnCmd += folder_;
+			svnCmd += _T("\"");
+			break;
+		case ShellMenuLock:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("lock /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuUnlock:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("unlock /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuUnlockForce:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("unlock /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			svnCmd += _T(" /force");
+			break;
+		case ShellMenuProperties:
+			tempfile = WriteFileListToTempFile();
+			svnCmd += _T("properties /pathfile:\"");
+			svnCmd += tempfile;
+			svnCmd += _T("\"");
+			svnCmd += _T(" /deletepathfile");
+			break;
+		case ShellMenuClipPaste:
+			if (WriteClipboardPathsToTempFile(tempfile))
+			{
+				bool bCopy = true;
+				UINT cPrefDropFormat = RegisterClipboardFormat(_T("Preferred DropEffect"));
+				if (cPrefDropFormat)
 				{
-					bool bCopy = true;
-					UINT cPrefDropFormat = RegisterClipboardFormat(_T("Preferred DropEffect"));
-					if (cPrefDropFormat)
+					if (OpenClipboard(lpcmi->hwnd))
 					{
-						if (OpenClipboard(lpcmi->hwnd))
+						HGLOBAL hglb = GetClipboardData(cPrefDropFormat);
+						if (hglb)
 						{
-							HGLOBAL hglb = GetClipboardData(cPrefDropFormat);
-							if (hglb)
-							{
-								DWORD* effect = (DWORD*) GlobalLock(hglb);
-								if (*effect == DROPEFFECT_MOVE)
-									bCopy = false;
-								GlobalUnlock(hglb);
-							}
-							CloseClipboard();
+							DWORD* effect = (DWORD*) GlobalLock(hglb);
+							if (*effect == DROPEFFECT_MOVE)
+								bCopy = false;
+							GlobalUnlock(hglb);
 						}
+						CloseClipboard();
 					}
-
-					if (bCopy)
-						svnCmd += _T("pastecopy /pathfile:\"");
-					else
-						svnCmd += _T("pastemove /pathfile:\"");
-					svnCmd += tempfile;
-					svnCmd += _T("\"");
-					svnCmd += _T(" /deletepathfile");
-					svnCmd += _T(" /droptarget:\"");
-					svnCmd += folder_;
-					svnCmd += _T("\"");
 				}
-				else return NOERROR;
-				break;
-			default:
-				break;
-				//#endregion
-			} // switch (id_it->second) 
-			svnCmd += _T(" /hwnd:");
-			TCHAR buf[30];
-			_stprintf_s(buf, 30, _T("%ld"), (LONG_PTR)lpcmi->hwnd);
-			svnCmd += buf;
-			myIDMap.clear();
-			myVerbsIDMap.clear();
-			myVerbsMap.clear();
-			if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, cwdFolder.c_str(), &startup, &process)==0)
-			{
-				LPVOID lpMsgBuf;
-				FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-					FORMAT_MESSAGE_FROM_SYSTEM | 
-					FORMAT_MESSAGE_IGNORE_INSERTS,
-					NULL,
-					GetLastError(),
-					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-					(LPTSTR) &lpMsgBuf,
-					0,
-					NULL 
-					);
-				MessageBox( NULL, (LPCTSTR)lpMsgBuf, _T("TortoiseProc Launch failed"), MB_OK | MB_ICONINFORMATION );
-				LocalFree( lpMsgBuf );
+
+				if (bCopy)
+					svnCmd += _T("pastecopy /pathfile:\"");
+				else
+					svnCmd += _T("pastemove /pathfile:\"");
+				svnCmd += tempfile;
+				svnCmd += _T("\"");
+				svnCmd += _T(" /deletepathfile");
+				svnCmd += _T(" /droptarget:\"");
+				svnCmd += folder_;
+				svnCmd += _T("\"");
 			}
-			CloseHandle(process.hThread);
-			CloseHandle(process.hProcess);
-			hr = NOERROR;
-		} // if (id_it != myIDMap.end() && id_it->first == idCmd) 
-	} // if ((files_.size() > 0)||(folder_.size() > 0)) 
+			else
+				return NOERROR;
+			break;
+		default:
+			break;
+			//#endregion
+		} // switch (id_it->second) 
+		svnCmd += _T(" /hwnd:");
+		TCHAR buf[30];
+		_stprintf_s(buf, 30, _T("%ld"), (LONG_PTR)lpcmi->hwnd);
+		svnCmd += buf;
+		myIDMap.clear();
+		myVerbsIDMap.clear();
+		myVerbsMap.clear();
+		RunCommand(tortoiseProcPath, svnCmd, cwdFolder.c_str(), _T("TortoiseProc Launch failed"));
+		return NOERROR;
+	} // if (id_it != myIDMap.end() && id_it->first == idCmd) 
 	return hr;
-
 }
 
 // This is for the status bar and things like that:
@@ -2427,25 +2388,24 @@
 	RGBQUAD *prgbQuad;
 	int cxRow;
 	HRESULT hr = pfnGetBufferedPaintBits(hPaintBuffer, &prgbQuad, &cxRow);
-	if (SUCCEEDED(hr))
+	if (FAILED(hr))
+		return hr;
+
+	ARGB *pargb = reinterpret_cast<ARGB *>(prgbQuad);
+	if (!HasAlpha(pargb, sizIcon, cxRow))
 	{
-		ARGB *pargb = reinterpret_cast<ARGB *>(prgbQuad);
-		if (!HasAlpha(pargb, sizIcon, cxRow))
+		ICONINFO info;
+		if (GetIconInfo(hicon, &info))
 		{
-			ICONINFO info;
-			if (GetIconInfo(hicon, &info))
+			if (info.hbmMask)
 			{
-				if (info.hbmMask)
-				{
-					hr = ConvertToPARGB32(hdc, pargb, info.hbmMask, sizIcon, cxRow);
-				}
-
-				DeleteObject(info.hbmColor);
-				DeleteObject(info.hbmMask);
+				hr = ConvertToPARGB32(hdc, pargb, info.hbmMask, sizIcon, cxRow);
 			}
+
+			DeleteObject(info.hbmColor);
+			DeleteObject(info.hbmMask);
 		}
 	}
-
 	return hr;
 }
 
@@ -2480,42 +2440,67 @@
 	bmi.bmiHeader.biHeight = sizImage.cy;
 	bmi.bmiHeader.biBitCount = 32;
 
-	HRESULT hr = E_OUTOFMEMORY;
+	
 	HANDLE hHeap = GetProcessHeap();
 	void *pvBits = HeapAlloc(hHeap, 0, bmi.bmiHeader.biWidth * 4 * bmi.bmiHeader.biHeight);
-	if (pvBits)
+	if (!pvBits)
+		return E_OUTOFMEMORY;
+
+	HRESULT hr = E_UNEXPECTED;
+	if (GetDIBits(hdc, hbmp, 0, bmi.bmiHeader.biHeight, pvBits, &bmi, DIB_RGB_COLORS) == bmi.bmiHeader.biHeight)
 	{
-		hr = E_UNEXPECTED;
-		if (GetDIBits(hdc, hbmp, 0, bmi.bmiHeader.biHeight, pvBits, &bmi, DIB_RGB_COLORS) == bmi.bmiHeader.biHeight)
-		{
-			ULONG cxDelta = cxRow - bmi.bmiHeader.biWidth;
-			ARGB *pargbMask = static_cast<ARGB *>(pvBits);
+		ULONG cxDelta = cxRow - bmi.bmiHeader.biWidth;
+		ARGB *pargbMask = static_cast<ARGB *>(pvBits);
 
-			for (ULONG y = bmi.bmiHeader.biHeight; y; --y)
+		for (ULONG y = bmi.bmiHeader.biHeight; y; --y)
+		{
+			for (ULONG x = bmi.bmiHeader.biWidth; x; --x)
 			{
-				for (ULONG x = bmi.bmiHeader.biWidth; x; --x)
+				if (*pargbMask++)
 				{
-					if (*pargbMask++)
-					{
-						// transparent pixel
-						*pargb++ = 0;
-					}
-					else
-					{
-						// opaque pixel
-						*pargb++ |= 0xFF000000;
-					}
+					// transparent pixel
+					*pargb++ = 0;
 				}
-
-				pargb += cxDelta;
+				else
+				{
+					// opaque pixel
+					*pargb++ |= 0xFF000000;
+				}
 			}
 
-			hr = S_OK;
+			pargb += cxDelta;
 		}
 
-		HeapFree(hHeap, 0, pvBits);
+		hr = S_OK;
 	}
+	HeapFree(hHeap, 0, pvBits);
 
 	return hr;
 }
 
+void CShellExt::RunCommand(const tstring& path, const tstring& command,
+	const tstring& folder, LPCTSTR errorMessage)
+{
+	PROCESS_INFORMATION process;
+	if (CCreateProcessHelper::CreateProcess(path.c_str(), const_cast<TCHAR*>(command.c_str()), folder.c_str(), &process))
+	{
+		// process started - close handles and exit
+		CloseHandle(process.hThread);
+		CloseHandle(process.hProcess);
+		return;
+	}
+
+	LPVOID lpMsgBuf;
+	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+			FORMAT_MESSAGE_FROM_SYSTEM | 
+			FORMAT_MESSAGE_IGNORE_INSERTS,
+			NULL,
+			GetLastError(),
+			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+			(LPTSTR) &lpMsgBuf,
+			0,
+			NULL 
+			);
+	MessageBox( NULL, (LPCTSTR)lpMsgBuf, errorMessage, MB_OK | MB_ICONINFORMATION );
+	LocalFree( lpMsgBuf );
+}
Index: TortoiseShell/RemoteCacheLink.cpp
===================================================================
--- TortoiseShell/RemoteCacheLink.cpp	(revision 17099)
+++ TortoiseShell/RemoteCacheLink.cpp	(working copy)
@@ -22,6 +22,7 @@
 #include "..\TSVNCache\CacheInterface.h"
 #include "TSVNPath.h"
 #include "PathUtils.h"
+#include "CreateProcessHelper.h"
 
 CRemoteCacheLink::CRemoteCacheLink(void) 
 	: m_hPipe(INVALID_HANDLE_VALUE)
@@ -182,14 +183,9 @@
 		if (GetProcessIntegrityLevel() < SECURITY_MANDATORY_MEDIUM_RID)
 			return false;
 
-		STARTUPINFO startup;
 		PROCESS_INFORMATION process;
-		memset(&startup, 0, sizeof(startup));
-		startup.cb = sizeof(startup);
-		memset(&process, 0, sizeof(process));
-
 		CString sCachePath = CPathUtils::GetAppDirectory(g_hmodThisDll) + _T("TSVNCache.exe");
-		if (CreateProcess(sCachePath.GetBuffer(sCachePath.GetLength()+1), NULL, NULL, NULL, FALSE, 0, 0, 0, &startup, &process)==0)
+		if (!CCreateProcessHelper::CreateProcess(sCachePath.GetBuffer(sCachePath.GetLength()+1), NULL, &process))
 		{
 			// It's not appropriate to do a message box here, because there may be hundreds of calls
 			sCachePath.ReleaseBuffer();
Index: TortoiseShell/ShellExt.h
===================================================================
--- TortoiseShell/ShellExt.h	(revision 17099)
+++ TortoiseShell/ShellExt.h	(working copy)
@@ -225,8 +225,8 @@
 	HRESULT			ConvertBufferToPARGB32(HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hicon, SIZE& sizIcon);
 	bool			HasAlpha(__in ARGB *pargb, SIZE& sizImage, int cxRow);
 	HRESULT			ConvertToPARGB32(HDC hdc, __inout ARGB *pargb, HBITMAP hbmp, SIZE& sizImage, int cxRow);
+	static void		RunCommand( const tstring& path, const tstring& command, const tstring& folder, LPCTSTR errorMessage );
 
-
 public:
 	CShellExt(FileState state);
 	virtual ~CShellExt();
Index: TortoiseShell/SVNPropertyPage.cpp
===================================================================
--- TortoiseShell/SVNPropertyPage.cpp	(revision 17099)
+++ TortoiseShell/SVNPropertyPage.cpp	(working copy)
@@ -24,6 +24,7 @@
 #include "PathUtils.h"
 #include "SVNStatus.h"
 #include "auto_buffer.h"
+#include "CreateProcessHelper.h"
 
 #define MAX_STRING_LENGTH		4096			//should be big enough
 
@@ -143,10 +144,8 @@
 	switch (uMessage)
 	{
 	case WM_INITDIALOG:
-		{
-			InitWorkfileView();
-			return TRUE;
-		}
+		InitWorkfileView();
+		return TRUE;
 	case WM_NOTIFY:
 		{
 			LPNMHDR point = (LPNMHDR)lParam;
@@ -159,83 +158,62 @@
 			}
 			SetWindowLongPtr (m_hwnd, DWLP_MSGRESULT, FALSE);
 			return TRUE;        
+		}
+	case WM_DESTROY:
+		return TRUE;
+	case WM_COMMAND:
+		switch (HIWORD(wParam))
+		{
+			case BN_CLICKED:
+				if (LOWORD(wParam) == IDC_SHOWLOG)
+				{
+					tstring svnCmd = _T(" /command:");
+					svnCmd += _T("log /path:\"");
+					svnCmd += filenames.front().c_str();
+					svnCmd += _T("\"");
+					RunCommand(svnCmd);
+				}
+				if (LOWORD(wParam) == IDC_EDITPROPERTIES)
+				{
+					DWORD pathlength = GetTempPath(0, NULL);
+					auto_buffer<TCHAR> path(pathlength+1);
+					auto_buffer<TCHAR> tempFile(pathlength + 100);
+					GetTempPath (pathlength+1, path);
+					GetTempFileName (path, _T("svn"), 0, tempFile);
+					tstring retFilePath = tstring(tempFile);
 
-			}
-		case WM_DESTROY:
-			return TRUE;
+					HANDLE file = ::CreateFile (tempFile,
+						GENERIC_WRITE, 
+						FILE_SHARE_READ, 
+						0, 
+						CREATE_ALWAYS, 
+						FILE_ATTRIBUTE_TEMPORARY,
+						0);
 
-		case WM_COMMAND:
-			switch (HIWORD(wParam))
-			{
-				case BN_CLICKED:
-					if (LOWORD(wParam) == IDC_SHOWLOG)
+					if (file != INVALID_HANDLE_VALUE)
 					{
-						STARTUPINFO startup;
-						PROCESS_INFORMATION process;
-						memset(&startup, 0, sizeof(startup));
-						startup.cb = sizeof(startup);
-						memset(&process, 0, sizeof(process));
-						tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
-						tstring svnCmd = _T(" /command:");
-						svnCmd += _T("log /path:\"");
-						svnCmd += filenames.front().c_str();
-						svnCmd += _T("\"");
-						if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))
+						DWORD written = 0;
+						for (std::vector<tstring>::iterator I = filenames.begin(); I != filenames.end(); ++I)
 						{
-							CloseHandle(process.hThread);
-							CloseHandle(process.hProcess);
+							::WriteFile (file, I->c_str(), (DWORD)I->size()*sizeof(TCHAR), &written, 0);
+							::WriteFile (file, _T("\n"), 2, &written, 0);
 						}
-					}
-					if (LOWORD(wParam) == IDC_EDITPROPERTIES)
-					{
-						DWORD pathlength = GetTempPath(0, NULL);
-						auto_buffer<TCHAR> path(pathlength+1);
-						auto_buffer<TCHAR> tempFile(pathlength + 100);
-						GetTempPath (pathlength+1, path);
-						GetTempFileName (path, _T("svn"), 0, tempFile);
-						tstring retFilePath = tstring(tempFile);
+						::CloseHandle(file);
 
-						HANDLE file = ::CreateFile (tempFile,
-							GENERIC_WRITE, 
-							FILE_SHARE_READ, 
-							0, 
-							CREATE_ALWAYS, 
-							FILE_ATTRIBUTE_TEMPORARY,
-							0);
-
-						if (file != INVALID_HANDLE_VALUE)
-						{
-							DWORD written = 0;
-							for (std::vector<tstring>::iterator I = filenames.begin(); I != filenames.end(); ++I)
-							{
-								::WriteFile (file, I->c_str(), (DWORD)I->size()*sizeof(TCHAR), &written, 0);
-								::WriteFile (file, _T("\n"), 2, &written, 0);
-							}
-							::CloseHandle(file);
-
-							STARTUPINFO startup;
-							PROCESS_INFORMATION process;
-							memset(&startup, 0, sizeof(startup));
-							startup.cb = sizeof(startup);
-							memset(&process, 0, sizeof(process));
-							tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
-							tstring svnCmd = _T(" /command:");
-							svnCmd += _T("properties /pathfile:\"");
-							svnCmd += retFilePath.c_str();
-							svnCmd += _T("\"");
-							svnCmd += _T(" /deletepathfile");
-							if (CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(svnCmd.c_str()), NULL, NULL, FALSE, 0, 0, 0, &startup, &process))
-							{
-								CloseHandle(process.hThread);
-								CloseHandle(process.hProcess);
-							}
-						}
+						tstring svnCmd = _T(" /command:");
+						svnCmd += _T("properties /pathfile:\"");
+						svnCmd += retFilePath.c_str();
+						svnCmd += _T("\"");
+						svnCmd += _T(" /deletepathfile");
+						RunCommand(svnCmd);
 					}
-					break;
-			} // switch (HIWORD(wParam)) 
+				}
+				break;
+		} // switch (HIWORD(wParam)) 
 	} // switch (uMessage) 
 	return FALSE;
 }
+
 void CSVNPropertyPage::Time64ToTimeString(__time64_t time, TCHAR * buf, size_t buflen)
 {
 	struct tm newtime;
@@ -431,4 +409,13 @@
 	} 
 }
 
+void CSVNPropertyPage::RunCommand(const tstring& command)
+{
+	PROCESS_INFORMATION process;
+	tstring tortoiseProcPath = GetAppDirectory() + _T("TortoiseProc.exe");
+	if (!CCreateProcessHelper::CreateProcess(tortoiseProcPath.c_str(), const_cast<TCHAR*>(command.c_str()), &process))
+		return;
 
+	CloseHandle(process.hThread);
+	CloseHandle(process.hProcess);
+}
Index: TortoiseShell/SVNPropertyPage.h
===================================================================
--- TortoiseShell/SVNPropertyPage.h	(revision 17099)
+++ TortoiseShell/SVNPropertyPage.h	(working copy)
@@ -78,6 +78,7 @@
 	 */
 	virtual void InitWorkfileView();
 	void Time64ToTimeString(__time64_t time, TCHAR * buf, size_t buflen);
+	static void RunCommand(const tstring& command);
 	
 	struct listproperty
 	{
Index: Utils/CreateProcessHelper.h
===================================================================
--- Utils/CreateProcessHelper.h	(revision 0)
+++ Utils/CreateProcessHelper.h	(revision 0)
@@ -0,0 +1,56 @@
+// TortoiseSVN - a Windows shell extension for easy version control
+
+// Copyright (C) 2009 - TortoiseSVN
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// 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 General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+#pragma once
+
+/**
+ * A helper class for invoking CreateProcess() and a wrapper class for STARTUPINFO
+ */
+
+class CCreateProcessHelper
+{
+public:
+	static bool CreateProcess(LPCTSTR lpApplicationName,
+					LPTSTR lpCommandLine,
+					LPCTSTR lpCurrentDirectory,
+					LPPROCESS_INFORMATION lpProcessInformation);
+	static bool CreateProcess(LPCTSTR lpApplicationName,
+					LPTSTR lpCommandLine,
+					LPPROCESS_INFORMATION lpProcessInformation);
+};
+
+inline bool CCreateProcessHelper::CreateProcess(LPCTSTR applicationName,
+	LPTSTR commandLine, LPCTSTR currentDirectory,
+	LPPROCESS_INFORMATION processInfo)
+{
+	STARTUPINFO startupInfo;
+	memset(&startupInfo, 0, sizeof(STARTUPINFO));
+	startupInfo.cb = sizeof(STARTUPINFO);
+
+	memset(processInfo, 0, sizeof(PROCESS_INFORMATION));
+	const BOOL result = ::CreateProcess( applicationName,
+					commandLine, NULL, NULL, FALSE, 0, 0, currentDirectory,
+					&startupInfo, processInfo );
+	return result != 0;
+}
+
+inline bool CCreateProcessHelper::CreateProcess(LPCTSTR applicationName,
+	LPTSTR commandLine, LPPROCESS_INFORMATION processInformation)
+{
+	return CreateProcess( applicationName, commandLine, 0, processInformation );
+}

Property changes on: Utils\CreateProcessHelper.h
___________________________________________________________________
Added: svn:eol-style
   + native

Index: Utils/Hooks.cpp
===================================================================
--- Utils/Hooks.cpp	(revision 17099)
+++ Utils/Hooks.cpp	(working copy)
@@ -433,19 +433,17 @@
 	PROCESS_INFORMATION pi;
 	SecureZeroMemory(&pi, sizeof(pi));
 
-	DWORD dwFlags = 0;
-
-	if (!CreateProcess(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, dwFlags, NULL, curDir.GetWinPath(), &si, &pi)) 
+	if (!CreateProcess(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, 0, NULL, curDir.GetWinPath(), &si, &pi)) 
 	{
-			int err = GetLastError();  // preserve the CreateProcess error
-			if (hErr != INVALID_HANDLE_VALUE) 
-			{
-				CloseHandle(hErr);
-				CloseHandle(hRedir);
-			}
-			SetLastError(err);
-			cmd.ReleaseBuffer();
-			return (DWORD)-1;
+		const int err = GetLastError();  // preserve the CreateProcess error
+		if (hErr != INVALID_HANDLE_VALUE) 
+		{
+			CloseHandle(hErr);
+			CloseHandle(hRedir);
+		}
+		SetLastError(err);
+		cmd.ReleaseBuffer();
+		return (DWORD)-1;
 	}
 	cmd.ReleaseBuffer();
 
@@ -490,4 +488,3 @@
 
 	return exitcode;
 }
-
