rpflq

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

     一个偶然的机会,在MSDN看到一种用脚本自动增加版本号的方法:

How To Increment Version Information After Each Build in Visual C++
http://support.microsoft.com/default.aspx?scid=kb;en-us;237870

也许是对VB脚本不是很熟练,几近修改,用的还是不爽;尤其是手下那么多project,挨个改rc应用实在是比较费事。于是,用VC6写了一个插件(DevStudio Add-in)……

     我的目的比较简单:
1.  在我没有修改rc文件,把VERSIONINFO挪到其他文件的时候(见上面连接 How to...),这个插件可以直接pass;
2.  我希望build成功之后,如果没有修改过源代码,用不着增加版本号;
3.  如果需要修改版本号,在下次build之前;避免build后修改,由于影响.rc,下次需要重新build。

步骤如下:
1.  首先当然要创建一个project,可以用类型为DevStudio Add-in Wizard的向导。向导完成后,Add-in的框架已经出来了(汗,MS!),要做的事情已经很少了。

2.  修改模板生成的CComands类
    2.1 增加一个BOOL型变量m_bUpdateVersion标记是不是有源代码文件被修改过
protected:
 BOOL m_bUpdateVersion; 
public:
 BOOL GetUpdateVersion() 
 { return m_bUpdateVersion;   };
 void SetUpdateVersion(BOOL bUpdateNext)
 { m_bUpdateVersion = bUpdateNext;  };
    2.2  增加更新版本号的代码

BOOL CCommands::UpdateVersionNO(LPCTSTR lpszVersionFileName)
{
 BOOL rt = FALSE;

 CComBSTR bstrProjName;
 
 CComPtr<IDispatch> pDisp;
 GetApplicationObject()->get_ActiveProject(&pDisp);
 
 CComQIPtr<IGenericProject> pProj = pDisp;
 if (pProj)
 {
  pProj->get_FullName(&bstrProjName);
  
  CString strProjName = (bstrProjName);
  CString strPathName, strFileName;
  
  if( GetPathFromFileName(strProjName, strPathName) )
  {
   strFileName = strPathName + lpszVersionFileName;
   
   CStdioFile versionFile;
   try
   {
    
    if( versionFile.Open(strFileName, CStdioFile::modeReadWrite) )
    {
     versionFile.SeekToBegin();
     CString strVerFile, strVerProd;
     
     LONG lVerFile[4] = {0, 0, 0, 0};
     LONG lVerProd[4] = {0, 0, 0, 0};
     CHAR szBufferVerFile[256] = {0};
     CHAR szBufferVerProd[256] = {0};
     
     versionFile.ReadString(strVerFile);
     versionFile.ReadString(strVerProd);
     
     _stscanf(strVerFile, "#define%s%d,%d,%d,%d", szBufferVerFile, lVerFile+0, lVerFile+1, lVerFile+2, lVerFile+3);
     _stscanf(strVerProd, "#define%s%d,%d,%d,%d", szBufferVerProd, lVerProd+0, lVerProd+1, lVerProd+2, lVerProd+3);
     
     if( lstrlen(szBufferVerFile)>0 && lstrlen(szBufferVerProd)>0 )
     {
      versionFile.SeekToBegin();
      versionFile.SetLength(0);
      
      lVerFile[3] ++;
      lVerProd[3] ++;
      
      CString strLine;
      strLine.Format(_T("#define %s\t\t%d,%d,%d,%d\n"), szBufferVerFile, lVerFile[0], lVerFile[1], lVerFile[2], lVerFile[3]);
      versionFile.WriteString(strLine);
      strLine.Format(_T("#define %s\t\t%d,%d,%d,%d\n"), szBufferVerProd, lVerProd[0], lVerProd[1], lVerProd[2], lVerProd[3]);
      versionFile.WriteString(strLine);
      strLine.Format(_T("#define %s_STR\t\"%d, %d, %d, %d\\0\"\n"), szBufferVerFile, lVerFile[0], lVerFile[1], lVerFile[2], lVerFile[3]);
      versionFile.WriteString(strLine);
      strLine.Format(_T("#define %s_STR\t\"%d, %d, %d, %d\\0\"\n"), szBufferVerProd, lVerProd[0], lVerProd[1], lVerProd[2], lVerProd[3]);
      versionFile.WriteString(strLine);     
      versionFile.WriteString("\n");
     }
     
     versionFile.Close();

     rt = TRUE;
    }
   }
   catch ( ... )
   {
   }
  }
 }
 return rt;
}

    2.3 在适当的位置判断状态,更新版本号文件:
HRESULT CCommands::XApplicationEvents::DocumentSave(IDispatch* theDocument)
{    //当有源代码更新并保存的时候
 ....
 if( !m_pCommands->GetUpdateVersion() )
 {
  m_pCommands->SetUpdateVersion(TRUE);
  m_pCommands->UpdateVersionNO("Version_NO.h");
 }
 ....

}
HRESULT CCommands::XApplicationEvents::BuildFinish(long nNumErrors, long nNumWarnings)
{    //如果编译成功,有必要重置标志信息,以便下次修改文件的时候同时更新版本号所在文件
 ... 
 if( nNumErrors==0 && m_pCommands->GetUpdateVersion() )
 {
  m_pCommands->SetUpdateVersion(FALSE);
 }

 ...
}

3.  修改工程的Settings,输出位置为\Microsoft Visual Studio\Common\MSDev98\AddIns\****.dll。如果需要调试的话,需要修改release设置的若干项,具体参考release模式下dll的调试。

4.  在其他的project,把.rc的VERSIONINFO转移到.rc2,把FILEVERSION、PRODUCTVERSION等用宏代替,并在一个新文件Version_NO.h中定义这些宏,比如:
#define VERSION_FILE  1,1,0,208
#define VERSION_PROD  1,1,0,208
#define VERSION_FILE_STR "1, 1, 0, 208\0"
#define VERSION_PROD_STR "1, 1, 0, 208\0"






posted on 2005-03-03 19:57  新博客-乱七八糟  阅读(3081)  评论(1)    收藏  举报