VSS 文件的清理类

VSS 是微软的 项目管理工具,全称是 MicroSoft Visual SourceSafe. 现在的版本是 VSS2005 ,老一点的公司有的还在用VSS6.0,是跟 VC++ 6.0 配套的管理工具。虽然是微软的产品,但这款软件是出了名的难用,连微软自己都不用。微软自己不用,但少不了别人用。鄙人的上一个项目就是用的VSS,后来改成了 AB(Alienbrain )。在网上下载代码阅读,发现好多也是用VSS管理的。用IDE打开的时候,会弹出对话框,多而且讨厌。这两天有空,就特意研究了一下VSS,写了个小工具用,系统上只装了 VSS2003 和 VS2008,所以主要是以这两个版本的VS 写的类

 

如果把一个项目传到VSS上去,那么VSS会对这个项目做如下操作。

 

第一,在每个文件夹下 添加 一些 .scc  文件  和 .vspscc 文件

第二, 更改 .sln 文件    在 其中的

GlobalSection(SourceCodeControl) = preSolution 和 EndGlobalSection 中间添加vss 控制的代码

第三,更改工程文件 ,既 .cproj (c++)或者 .csproj(c#) 文件等,在这些文件中添加Vss 控制的代码。

第四,把所有文件置为只读文件

 

只要把这些都消除了。那么工程也就会变成一个 纯的本地工程,打开的时候没有了烦人的提示框了。

下面是自己写的 C++ 清理类,

 

//-头文件

class CVssClearManager
{
public:		//-Static Function
	static unsigned	_stdcall	ThreadClearDirectory	(void* params);
	static void					Delete			();
	static CVssClearManager*	g_VssClearManager;
public:
	CVssClearManager		();
	~CVssClearManager		();
public:	//主要接口
	void	Execute				(const string_t& DirectoyName);	//
	void	Stop				();
	//bool	IsExecuting			() const {return m_bExecute;}

public:	//处理函数用的接口
	void	SetListBoxHwnd		(HWND hwnd)	;
private:
	void	ProcessDirectory	(const string_t& directoryName);
	void	ProcessFile_Sln		(const string_t& fileName);
	void	ProcessFile_Proj	(const string_t& fileName);	//-

private:
	void	LoadFile			(const string_t& fileName);
	void	SaveFile			(const string_t& fileName);
private:
	void	ResetLog			();
	void	Log					(const string_t& _msg);
private:	//Flag
	//bool	m_bExecute;
	bool	m_bStop;	//-

private:
	ILog*			m_pLog;				//-Log File
	string_t		m_TmpString_1;		//-tmp 1
	string_t		m_Directory;		//-文件夹
	StringVector	m_ItemColl;
	char*			m_pFileBuffer;		//-文件缓冲区
};


 

//-源文件

 

CVssClearManager* CVssClearManager::g_VssClearManager = NULL;

unsigned	_stdcall CVssClearManager::ThreadClearDirectory(void *params)
{
	if(g_VssClearManager == NULL)
		g_VssClearManager = new CVssClearManager;	//BuildClearManager

	PTCDContent pParams = (PTCDContent)params;
	g_VssClearManager ->SetListBoxHwnd(pParams ->hLogWnd);
	g_VssClearManager ->Execute(pParams ->DirectoryName);


	EnableWindow(GetDlgItem(pParams ->hWnd,IDC_PLAY),TRUE);
	EnableWindow(GetDlgItem(pParams ->hWnd,IDC_STOP),FALSE);
	g_VssClearManager ->Log(_T("完成 !!"));
	_endthreadex(0);

	return 0;
}
void CVssClearManager::Delete()
{
	if(g_VssClearManager != NULL)
	{
		delete g_VssClearManager;
		g_VssClearManager = NULL;
	}
}

CVssClearManager::CVssClearManager()
{
	m_bStop		= true;
	//m_bExecute  = false;
	m_Directory = _T("");
	m_TmpString_1 = _T("");
	m_ItemColl.clear();
	m_pFileBuffer = NULL;
	m_pLog	=	NULL;
}

CVssClearManager::~CVssClearManager()
{
	delete [] m_pFileBuffer;
	m_pFileBuffer = NULL;
	delete m_pLog;
	m_pLog = NULL;

	m_Directory.clear();
	m_ItemColl.clear();
}

void CVssClearManager::Execute(const string_t &DirectoryName)
{
	m_bStop = false;
	m_Directory = DirectoryName;
	g_VssClearManager ->ResetLog();
	g_VssClearManager ->Log(_T("开始 !!"));
	ProcessDirectory(DirectoryName);
	//m_bExecute = true;	//-
}

void CVssClearManager::Stop()
{
	//m_bExecute = false;
	m_bStop = true;
}


void CVssClearManager::SetListBoxHwnd(HWND hWnd)
{
	if(m_pLog != NULL)
		delete m_pLog;	//- 
	m_pLog = new CProcessLog(hWnd);
}
//private
void CVssClearManager::LoadFile(const string_t &fileName)
{
	if(fileName.empty()) 
		return;
	if(!m_ItemColl.empty())
		m_ItemColl.clear();		//-清理

	FILE* fp = _tfopen(fileName.c_str(),_T("rb"));
	if(fp)
	{
#pragma region "读取文件"
		long length = 0;
		fseek(fp,0,SEEK_END);
		length = ftell(fp);
		fseek(fp,0,SEEK_SET);
		if(m_pFileBuffer == NULL)
		{
			m_pFileBuffer = new char[length + 1];
		}
		else
		{
			int nFileBuffSize = _msize((void*)m_pFileBuffer);
			if(nFileBuffSize < (length +1))
			{
				delete []m_pFileBuffer;
				try
				{
					m_pFileBuffer = new char[length + 1];
				}
				catch(...)
				{
					delete []m_pFileBuffer;
					m_pFileBuffer = NULL;
					assert(!"内存不够了!!");
					return;
				}
			}
		}
		memset((void*)m_pFileBuffer,0,length + 1);
		fread((void*)m_pFileBuffer,1,length,fp);
		if(ferror(fp))
		{
			assert(!"Error Reading File");
		}
		fclose(fp);
#pragma endregion
#pragma region "格式化字符串"
		const char* pos		= m_pFileBuffer;
		const char* pos_0	= m_pFileBuffer;
		while(*pos)
		{
			if(*pos++ == 10)		//这里的换行都是 0x0D 0x0A,
			{
				int nLen = pos - pos_0;
				string tmp1(pos_0,nLen);
				m_ItemColl.push_back(tmp1);
				pos_0 = pos;
			}
		}
#pragma endregion
	}

}

void CVssClearManager::SaveFile(const string_t& fileName)
{
	if(fileName.empty()) return;
	FILE* fp = _tfopen(fileName.c_str(),_T("wb"));
	if(fp)
	{
		StringVector::iterator it;
		for(it = m_ItemColl.begin();it != m_ItemColl.end(); ++it)
		{
			::fwrite(it ->c_str(),1,it ->size(),fp);
		}
		if(ferror(fp))
		{
			assert(!"Error Writing File");
		}
		fclose(fp);
	}
}

void CVssClearManager::ProcessDirectory(const string_t& directoryName)
{
	if(m_bStop) 
	{
		_endthreadex(0);
		return;
	}

	string_t  currentDir = directoryName;
	string_t  tmpString	 = _T("切换文件夹: ");
	//m_TmpString = _T("切换文件夹");
	//m_TmpString += directoryName.c_str();	//-
	tmpString += currentDir.c_str();
	//Log(m_TmpString);		//-
	Log(tmpString);

	WIN32_FIND_DATA FindFileData;
	HANDLE hFind = INVALID_HANDLE_VALUE;
	tmpString  = directoryName + _T("\\*");
	hFind = FindFirstFile(tmpString.c_str(), &FindFileData);
	if(hFind == INVALID_HANDLE_VALUE)
	{
		return;
	}
	else
	{	//查找的第一个文件都是"."或者".."m,都是目录,所以不进行文件操作了
		if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			tmpString = FindFileData.cFileName;	//-
			if(tmpString != _T(".") && tmpString != _T(".."))
			{
				tmpString = directoryName + _T("\\") + FindFileData.cFileName;
				ProcessDirectory(tmpString);
			}
		}
	}
	while(FindNextFile(hFind,&FindFileData)!= 0)
	{
		if(m_bStop) 
		{
			_endthreadex(0);
			return;	//-
		}
		if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			tmpString = FindFileData.cFileName;
			if(tmpString != _T(".") && tmpString != _T(".."))
			{
				tmpString = directoryName + _T("\\") + FindFileData.cFileName;
				ProcessDirectory(tmpString);
			}
		}
		else
		{
			//-取消只读属性
			tmpString = directoryName + _T("\\") + FindFileData.cFileName;
			FindFileData.dwFileAttributes &= (~FILE_ATTRIBUTE_READONLY);
			SetFileAttributes(tmpString.c_str(),FindFileData.dwFileAttributes);
			string_t::size_type suffixpos = tmpString.rfind(_T("."));
			if(suffixpos == string_t::npos) 
				continue;	//
			m_TmpString_1 = tmpString.substr(suffixpos);
			if(
				m_TmpString_1 == _T(".SCC") || m_TmpString_1 == _T(".scc") 
			   ||m_TmpString_1 == _T(".vssscc") ||m_TmpString_1 == _T(".VSSSCC")
			   ||m_TmpString_1 == _T(".vspscc") ||m_TmpString_1 == _T(".VSPSCC")
			   )
			{
				::DeleteFile(tmpString.c_str());
				tmpString = _T("删除文件: ") + tmpString;
				Log(tmpString);
			}
			else if (m_TmpString_1 == _T(".SLN") || m_TmpString_1 == _T(".sln"))
			{
				ProcessFile_Sln(tmpString);
				tmpString = _T("处理文件: ") + tmpString;
				Log(tmpString);
			}
			else if(m_TmpString_1 == _T(".vcproj") || m_TmpString_1== _T(".VCPROJ")
					|| m_TmpString_1 == _T(".csproj") || m_TmpString_1== _T(".CSPROJ"))
			{
				ProcessFile_Proj(tmpString);
				tmpString = _T("处理文件: ") + tmpString;
				Log(tmpString);
			}

		}
	}
	FindClose(hFind);
}

void CVssClearManager::ProcessFile_Proj(const string_t &fileName)
{
	if(m_bStop) 
	{
		_endthreadex(0);
		return;
	}
	LoadFile(fileName);
	if(m_ItemColl.empty()) return;
	StringVector::iterator it = m_ItemColl.begin();
	while(it != m_ItemColl.end())
	{
		string::size_type flag_pos = it ->find("\tScc");
		string::size_type flag_pos_1 = it ->find(" Scc");
		string::size_type flag_pos_end;
		if(flag_pos != string::npos || flag_pos_1 != string::npos) //找到了
		{
			flag_pos_end = it ->find('>');
			if(flag_pos_end != string::npos)
			{
				*it = "\t>";
				++it;
			}
			else
			{
				it = m_ItemColl.erase(it);
			}
		}
		else
		{
			++it;
		}
	}
	SaveFile(fileName);
}
void CVssClearManager::ProcessFile_Sln(const string_t& fileName)
{
	if(m_bStop)
	{
		_endthreadex(0);
		return;
	}
	LoadFile(fileName);

	if(m_ItemColl.empty()) return;
	bool bEraseFlag = false;
	StringVector::iterator it = m_ItemColl.begin();
	while(it != m_ItemColl.end())
	{
		if( it ->find("GlobalSection(SourceCodeControl)") != string::npos)
		{
			bEraseFlag = true;
		}

		if(bEraseFlag)
		{

			if(it ->find("EndGlobalSection") != string::npos)
			{
				bEraseFlag = false;
			}
			it = m_ItemColl.erase(it);
		}
		else
		{
			++it;
		}
	}

	SaveFile(fileName);
}



//-log

void CVssClearManager::ResetLog()
{
	if(m_pLog != NULL)
	{
		m_pLog ->Clear();
	}
}
void CVssClearManager::Log(const string_t& msg)
{
	if(m_pLog != NULL) 
	{
		m_pLog ->Log(msg);
	}

}

//-完成 //

 

根据这个类,写了个小工具,传到CSDN资源里了。有问题欢迎大家评论交流


链接1 :VSS在 .sln 和 proj文件内部 做了什么改动 

http://codeidol.com/windows/visual-studio-hack/Master-Projects-and-Solutions/Remove-SourceSafe-Bindings/#part-16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值