【项目研究】设计MFC自动更新程序

本程序拟设计为在windows操作系统常见的升级更新过程。主要核心是:

1、嗅探原程序的安装路径。

2、复制或解压下载的更新安装包至安装路径下,覆盖旧文件。(这里可能还要考虑一个还原)

3、界面显示进度条,严格与安装时间同步。

对于第一个问题,我可以偷点懒,因为源程序也是我写的。为了使我们方便嗅探,需要修改源程序代码,使程序在第一次启动时将路径写入注册表。这样的话,更新时就可以轻而易举的读取到安装路径了。

在此需研究和复习一些常用的windows函数和注册表操作:

首先是获取当前运行程序的路径;

CString m_FilePath;
// GetModuleFileName获取的是当前运行程序完整路径(包括名称和后缀)(in/out,out,in)
GetModuleFileName(NULL,m_FilePath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);

可以进一步提取安装文件所在文件夹;

int n=m_FilePath.ReverseFind('\\');
m_FilePath=m_FilePath.Left(n);

可将以上操作封装到一个函数里,这里我起名叫做GetProductDir(CString& szPath),然后还需要写一个写入注册表的函数;

BOOL SetProductRegString(LPCTSTR szKey,LPCTSTR lpszEntry,LPCTSTR lpszValue)
{
	// 向注册表中写入字符串
	ASSERT(lpszEntry != NULL);
	CString szSubKey = szBaseKey+"\\"+szKey;
	HKEY hSecKey;
	RegCreateKey(HKEY_LOCAL_MACHINE,szSubKey,&hSecKey);
	LONG lResult = RegSetValueEx(hSecKey, lpszEntry, NULL, REG_SZ,
		(LPBYTE)lpszValue, (lstrlen(lpszValue)+1)*sizeof(TCHAR));
	RegCloseKey(hSecKey);
	return lResult == ERROR_SUCCESS;
}

其中szBaseKey是我自定义的注册表路径;

最后可以写一个简单的插入路径的函数来调用以上代码了;

BOOL SetFilePath()
{	
	// 设置路径
	CString filePath;
	GetProductDir(filePath);
	return SetProductRegString("File","Path",filePath);
}

当我的更新程序需要获取路径时,获取本程序指定注册表路径下File文件夹中的Path字段内容即可。

在更新程序中也需要一个读注册表的函数;

CString GetProductRegString(LPCTSTR lpszKey,LPCTSTR lpszEntry, LPCTSTR strDefVal)
{
	// 获取注册表中的字符串
	CString strValue = strDefVal;
	ASSERT(lpszEntry != NULL);
	CString szSubKey = szBaseKey+"\\"+lpszKey;
	HKEY hSecKey;
	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE,
		&hSecKey) == ERROR_SUCCESS)
	{
		DWORD dwType, dwCount;
		LONG lResult = RegQueryValueEx(hSecKey, (LPTSTR)lpszEntry, NULL, &dwType,
			NULL, &dwCount);
		if (lResult == ERROR_SUCCESS)
		{
			ASSERT(dwType == REG_SZ);
			lResult = RegQueryValueEx(hSecKey, (LPTSTR)lpszEntry, NULL, &dwType,
				(LPBYTE)strValue.GetBuffer(dwCount/sizeof(TCHAR)), &dwCount);
			strValue.ReleaseBuffer();
		}
		RegCloseKey(hSecKey);
	}
	return strValue;
}

然后通过GetProductRegString("File","Path","")便可以获取到该路径了,这样我们的第一个目标就基本实现了。

对于第二个和第三个问题,其实要深度研究的就是一个函数:CopyFileEx,并了解其回调函数。这个将在下一步的工作中进行,这个小项目的原型基本告一段落。(目前安装程序很小的情况下,CopyFile就完全可以达到我们的要求)

作者:pezy 出处:http://www.cnblogs.com/pezy 欢迎转载,也请保留这段声明。谢谢!
原文地址:https://www.cnblogs.com/pezy/p/2224804.html