Introduction
This program finds all the #define WINVER 0x0502
in your Visual Studio 2005 Projects folder. All projects there have a stdafx.h file that may contain this #define WINVER 0x0502
or some other value (e.g., 420, 440, 502, etc.). My program finds these #define
s and changes the (Windows 7) value to 0x0601.
Background
I had close to 100 projects in my Visual Studio 2005 Projects folder and didn't want to manually change all the stdafx.h files.
Using the Code
While developing this program, I was getting an error: "Encountered a sharing violation while accessing path\StdAfx.h". At first, I thought it meant the My Documents folder should have "file sharing" set. No, that wasn't it. After looking at the Cfile::Remove()
method, it said that it would cause a CFileException
if the file was still open for reading. fdi.Close()
closes the file and deletes the object, and I didn't know the file descriptor fdi
would still be valid. Well it is. The following code fragment is the correct way of handling fdi.Remove(Oldfile)
and the fdo
file descriptor fdo.Rename(Oldfile, NewFile)
method.
Here is the code fragment:
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;
You have seen on a few program where they show something like: Running... That was easy to do.
void CChangeWinverDlg::OnTimer(UINT_PTR nIDEvent)
{
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);
}
Here is the complete method (something of interest, the stdafx.h file might look like this):
#ifndef WINVER
#define WINVER 0x0502
#endif
CString.Find(...)
: If you simple try to find the "WINVER
" string
and assume the "0x0
" follows, it wraps back to the previous line "#ifndef WINVER"
and replaces the "ifndef
" with "#i601ef
". You must first find the #define
then the WINVER
; next, the 0x0 string
before replacing what follows with 601
.
Also, you can't read and write to the same file, so I read the old stdafx.h file and created a new file stdafx.hpp to copy the records into. Then, at the end of my method, I removed the old file (stdafx.h) and renamed the new (stdafx.hpp) to (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;
}
Points of Interest
Note: When I bought this system, it had OEM Windows Vista; at the time, I didn't know that VS2005 doesn't work with Vista. Every day, Windows Update tried to install VS2005 SP1 (KB947738) and failed every time. I could debug console apps, but not MFC apps. When I upgraded to Windows 7, it stopped trying to update the Service Pack, and trying to use VS2005 on Windows 7 became a nightmare.
It is always a good idea to make a backup of your files before running an untested program like this one; during the development stage, weird things might happen. Once I had it bug free, I compiled several of them using Visual Studio 2010.
History
ChangeWinver
: V1.0: 09/01/2010 ChangeWinver
: V1.1: 09/02/2010 Added abort
method