Upgrading Visual C++ 6.0 Projects to Visual Studio .NET 2003 in Batch Mode

Environment: Visual C++ .NET 2003

This article is intended for those interested in converting Visual C++ project files (.DSP) to files solutions that will work with Visual Studio .NET 2003. Note that only the project .DSP files are converted to .vcproj, .sln and, .suo files; the actual work of making the code compile error and warning free still needs to be done manually. Some C++ code will be presented; it uses the Visual Studio Automation to help perform the batch conversion, and an executable is available as a download.

Picture this: You decide that its time to change a Visual C++ project over to the newer Microsoft Visual Studio .NET 2003 compiler. Simple, you say, because Microsoft has made sure that your new tool is backwards compatible. Below, I show the steps needed for the conversion:

  1. You choose File->Open->Project from the menu, and navigate to the project you wish to convert. Having selected the file, you click Open.



    Click here for a larger image.

  2. Visual Studio .NET is smart enough to determine that the conversion must take place. Typically, you click Yes or Yes To All.

  3. When closing Visual Studio .NET 2003 or loading another project, the system asks to save. You typically click Yes.

That completes the conversion. The problem comes in when you have 300+ projects to convert; this conversion becomes a real chore. MSDN has an interesting article that discusses this very subject, which is available here. The problem with the MSDN solution is that no .sln/.suo files are created, and you are prompted with Step 3 every time. Below, I present some code, written in C++, that addresses this problem and allows a completely automated batch conversion from .DSP to .vcproj/.sln.

The code was written using .NET 2003; one of the import statements fails if you try to compile this with VC++ 6.0. The core conversion routine is presented below:

void DoWithDSPFile(LPTSTR szDSPFileName)
{
  VC::VCProjectEnginePtr  ptrVC(__uuidof(
                                VC::VCProjectEngineObject));
                                   // for project conversion
  EnvDTE::ProjectItemPtr  proj;    // not used
  VC::VCProjectPtr  ptrProject;    // smart ptr to project
  TCHAR  szCurDir[_MAX_PATH];      // full path to current
                                   // directory
  _bstr_t   bstrCD;                // smart bstring version of
                                   // the above
  TCHAR    szVCProj[_MAX_PATH];    // full path to the new
                                   // .vcproj file
  _bstr_t   bstrVCProj;            // bstr version of above
  TCHAR  szDSP[_MAX_PATH];         // full path to the old .dsp
                                   // file to convert
  TCHAR  szBareVCProj[_MAX_PATH];  // bare VCProj project name
                                   // with eg myproj.vcproj
  TCHAR  szSoln[_MAX_PATH];        // solution
  TCHAR  szBareName[_MAX_PATH];    // solution bare name
  _bstr_t   bstrBareSoln;          // bare (base) solution name
  TCHAR*   p;                      // pointer to a subsbring

  // grab our directory
  _tgetcwd(szCurDir, _MAX_PATH);
  bstrCD = szCurDir;

  _tcscpy(szVCProj, szCurDir);
  PathAddBackslash(szVCProj);

  // add original name
  _tcscat(szVCProj, szDSPFileName);

  // replace extension with .vcproj
  p = PathFindExtension(szVCProj);
  _tcscpy(p, _T(".vcproj"));

  // did we already do it?
  if (PathFileExists(szVCProj))
  {

    // tell the user & go to next file
    _ftprintf(stdout, _T("Skipping %s because already converted\n"),
              szVCProj);
    return;
  }

  // OK using smart pointers here, need try/catch
  try
  {
    // get full path to DSP file
    _tcscpy(szDSP, szCurDir);
    PathAddBackslash(szDSP);
    _tcscat(szDSP, szDSPFileName);

    // load old dsp file
    ptrProject = ptrVC->LoadProject(szDSP);

      // generate name from .DSP name (same base name)
    _tcscpy(szBareVCProj, szDSPFileName);
    p = PathFindExtension(szBareVCProj);
    _tcscpy(p, _T(".vcproj"));

    // name the project as proj.vcproj
    ptrProject->PutProjectFile(szBareVCProj);

    // save converted project (this will create the .vcproj file
    ptrProject->Save();

    // need to worry about creating a solution (.sln) file.
    // This was the hard part to figure out.
    _tcscpy(szSoln, szDSPFileName);
    p = PathFindExtension(szSoln);
    _tcscpy(p, _T(".sln"));
    _tgetcwd(szCurDir, _MAX_PATH);

    // create empty solution
    EnvDTE::_SolutionPtr ptrSoln(_T("VisualStudio.Solution.7.1"));

    // get the bare name for the solution
    _tcscpy(szBareName, szDSPFileName);
    p = PathFindExtension(szBareName);
    *p = 0;    // cut off at extension

    // get a bstring
    bstrBareSoln = szBareName;

    // and create the empty solution
    ptrSoln->Create(bstrCD, bstrBareSoln);

    // get the filename of our new solution
    bstrVCProj = szVCProj;

    // and add it into the newly created solution, replacing
    // whatever was there
    ptrSoln->AddFromFile(bstrVCProj, FALSE,
                        (EnvDTE::Project**)&proj);

    _ftprintf(stdout, _T("Project %s converted OK\n"), szVCProj);
  }
  catch(...)
  {
    _ftprintf(stdout, _T("Something bad happened...\n"));
  }

}

To run the program: Extract from the ZIP file and place somewhere on the path. In a command window, change to the root directory of the source tree whose projects you want changed. The program outputs successful conversions, but skips projects that were already converted. It is possible to redirect the output of this program to a file using standard redirection.

In conclusion, the program presented in this article quickly converts all of your .DSP project files to .VCPROJ and .SLN files, getting you the first step in your hopefully successful conversion.

Downloads

Download demo project and source - 42 Kb


Comments

  • Just ask:

    Posted by Legacy on 08/02/2003 12:00am

    Originally posted by: Jeff Zhang

    1. Is the following the point of this article: to save clicking "yes" on the conversion dialog?

    2. in VC++ 6, son projects within the same workspace can be located in different folders. an good example of our dear "Advanced Windows", I remember Jefferey put a bare workspace file in the root dir, while put each project under the name of the chapter...
    So does it means, we should read the workspace file to locate the project before converting it.

    Thanks ahead.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Agile methodologies give development and test teams the ability to build software at a faster rate than ever before. Combining DevOps with hybrid cloud architectures give teams not just the principles, but also the technology necessary to achieve their goals. By combining hybrid cloud and DevOps: IT departments maintain control, visibility, and security Dev/test teams remain agile and collaborative Organizational barriers are broken down Innovation and automation can thrive Download this white paper to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds