更改 WINVER
如何将 #define WINVER 0x0502 更改为 0x0601

引言
这个程序会在你的 Visual Studio 2005 项目文件夹中查找所有的 #define WINVER 0x0502
。 所有的项目都会有一个 stdafx.h 文件,其中可能包含这个 #define WINVER 0x0502
或者其他值(例如 420, 440, 502 等)。 我的程序会找到这些 #define
并将(Windows 7)的值更改为 0x0601。
背景
我的 Visual Studio 2005 项目文件夹里有近 100 个项目,我不想手动更改所有的 stdafx.h 文件。
Using the Code
在开发这个程序时,我遇到了一个错误:“访问路径\StdAfx.h 时遇到共享冲突”。 最初,我以为这意味着“我的文档”文件夹应该设置“文件共享”。 事实并非如此。 在查看 Cfile::Remove()
方法后,它说如果文件仍然处于打开状态,它会导致 CFileException
。 fdi.Close()
关闭文件并删除对象,我不知道文件描述符 fdi
仍然有效。 事实是它仍然有效。 以下代码片段是正确处理 fdi.Remove(Oldfile)
和 fdo
文件描述符 fdo.Rename(Oldfile, NewFile)
方法的方式。
这是代码片段
//
// function block that Removes the old stdafx.h file
// and Renames the new stdafx.hpp file stdafx.h.
//
try
{
fdi.Close();
fdi.Remove(szFile);
fdo.Close();
fdo.Rename(szOutFile, szNewFile);
}
catch (CFileException *pEx)
{
pEx->ReportError();
fdi.Abort();
fdo.Abort();
pEx->Delete();
return FALSE;
}
return TRUE;
你可能在一些程序中见过类似“正在运行...”的显示,这很容易实现。
//
// 1 second timer displays "Running with marching periods".
//
void CChangeWinverDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
switch(n_periods)
{
case 1 : SetDlgItemText(IDC_STATIC_STATUS, "Running");
break;
case 2 : SetDlgItemText(IDC_STATIC_STATUS, "Running.");
break;
case 3 : SetDlgItemText(IDC_STATIC_STATUS, "Running..");
break;
case 4 : SetDlgItemText(IDC_STATIC_STATUS, "Running...");
break;
default : SetDlgItemText(IDC_STATIC_STATUS, "Running");
break;
}
n_periods++;
if(n_periods =5)
n_periods =;
CDialogEx::OnTimer(nIDEvent);
}
这是完整的代码(一些有趣的内容,stdafx.h 文件可能如下所示)
#ifndef WINVER
#define WINVER 0x0502
#endif
CString.Find(...)
:如果你简单地尝试查找“WINVER
”字符串并假设“0x0
”紧随其后,它会回溯到上一行“#ifndef WINVER
”并将“ifndef
”替换为“#i601ef
”。 你必须先找到 #define
,然后找到 WINVER
;接下来,找到 0x0 string
之后才能用 601
替换它。
此外,你不能同时读取和写入同一个文件,所以我读取了旧的 stdafx.h 文件并创建了一个新的文件 stdafx.hpp 来复制记录。 然后,在我的方法结束时,我删除了旧文件(stdafx.h)并将新文件(stdafx.hpp)重命名为(stdafx.h)。
BOOL CChangeWinverDlg::EditFile(CString& szFile)
{
CString szData;
CString szError;
CString szDef = "define";
CString szWord = "WINVER";
CString szValue = "0x0";
CString szNewFile;
CString szOutFile = szFile;
szOutFile += "pp";
CStdioFile fdi;
CStdioFile fdo;
SetDlgItemText(IDC_STATIC_DEBUG, szFile);
CFileException e;
int n;
if(!fdi.Open(szFile, CFile::modeRead, &e))
{
szError.Format("Could not open: %s for reading", e.m_strFileName);
AfxMessageBox(szError);
return FALSE;
}
if(!fdo.Open(szOutFile, CFile::modeCreate |
CFile::modeWrite | CFile::shareDenyNone, &e))
{
szError.Format("Could not open: %s for writing", e.m_strFileName);
AfxMessageBox(szError);
return FALSE;
}
while(fdi.ReadString(szData))
{
if((szData.Find(szDef, 0) > 0) && (szData.Find(szWord, 0) > 0))
{
n = szData.Find(szValue, 0);
n += 3;
szData.Delete(n, 3);
szData.Insert(n, "601");
}
szData += "\n";
fdo.WriteString(szData);
}
szNewFile = szOutFile;
n = szNewFile.Find(".hpp", 0);
szNewFile.Delete(n, 4);
szNewFile += ".h";
try
{
fdi.Close();
fdi.Remove(szFile);
fdo.Close();
fdo.Rename(szOutFile, szNewFile);
}
catch (CFileException *pEx)
{
pEx->ReportError();
fdi.Abort();
fdo.Abort();
pEx->Delete();
return FALSE;
}
return TRUE;
}
关注点
注意:当我购买这个系统时,它安装了 OEM Windows Vista;当时,我不知道 VS2005 不支持 Vista。 每天,Windows Update 都会尝试安装 VS2005 SP1 (KB947738) 并每次都失败。 我可以调试控制台应用程序,但不能调试 MFC 应用程序。 当我升级到 Windows 7 时,它停止尝试更新服务包,并且在 Windows 7 上使用 VS2005 变成了一场噩梦。
在使用像这个程序这样的未经测试的程序之前,最好备份你的文件;在开发阶段,可能会发生奇怪的事情。 一旦我修复了所有错误,我就使用 Visual Studio 2010 编译了几个程序。
历史
ChangeWinver
:V1.0:09/01/2010ChangeWinver
:V1.1:09/02/2010 添加了abort
方法