如何以编程方式更改项目的产品版本?

时间:2008-11-20 17:55:07

标签: visual-studio-2005 automated-deploy

这是我的问题:

我有几个部署项目。为了部署应用程序,我需要完成几项任务,其中之一就是更改每个部署项目的产品版本和产品代码。

我找不到以编程方式改变它们的方法。

任何人都可以帮助我吗?

提前致谢。

更新:由于它是一个部署项目(最终生成可执行安装程序),我无法使用MSBuild,而是从命令提示符处使用Devenv。 (布鲁诺,谢谢你的快速反应)。

11 个答案:

答案 0 :(得分:11)

我今天正在寻找完全相同的东西。我发现这是使用谷歌:

static void Main(string[] args) 
{
    string setupFileName = @"<Replace the path to vdproj file>"; 
    StreamReader reader = File.OpenText(setupFileName); 
    string file = string.Empty; 

    try 
    { 
        Regex expression = new Regex(@"(?:\""ProductCode\"" = 
        \""8.){([\d\w-]+)}"); 
        Regex expression1 = new Regex(@"(?:\""UpgradeCode\"" = 
        \""8.){([\d\w-]+)}"); 
        file = reader.ReadToEnd(); 

        file = expression.Replace(file, "\"ProductCode\" = \"8:{" + 
        Guid.NewGuid().ToString().ToUpper() + "}"); 
        file = expression1.Replace(file, "\"UpgradeCode\" = \"8:{" 
        + Guid.NewGuid().ToString().ToUpper() + "}"); 
    } 
    finally 
    { 
        // Close the file otherwise the compile may not work 
        reader.Close(); 
    } 

    TextWriter tw = new StreamWriter(setupFileName); 
    try 
    { 
        tw.Write(file); 
    } 
    finally 
    { 
        // close the stream 
        tw.Close(); 
    } 
 }

答案 1 :(得分:5)

我知道原始海报正在寻找解决此问题的.NET 2.0解决方案。但是,由于这不是标记为.NET,我将提供我的C ++解决方案来解决这个问题。这可能适用于.NET版本,但我会将其留给其他人。

这不仅会更新我的应用程序的about框和日志文件中的版本信息,还会更新Windows资源管理器中显示的所有Windows版本信息。

更新:我添加了自原始答案以来我对流程所做的一些更改。

首先,我将整个版本信息块从我的Project.rc文件移动到我的Project.rc2文件中:

/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION FILE_VER
 PRODUCTVERSION PROD_VER
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
  FILEFLAGS 0x1L
#else
  FILEFLAGS 0x0L
#endif
  FILEOS 0x4L
  FILETYPE 0x1L
  FILESUBTYPE 0x0L
BEGIN
   BLOCK "StringFileInfo"
   BEGIN
       BLOCK "040904e4"
       BEGIN
           VALUE "CompanyName", "MyCompany"
           VALUE "FileDescription", "Software Description"
           VALUE "FileVersion", 1,0,0,1
           VALUE "InternalName", "FileName.exe"
           VALUE "LegalCopyright", "(c) 2008 My Company.  All rights reserved."
           VALUE "OriginalFilename", "FileName.exe"
           VALUE "ProductName", "Product Name"
           VALUE "ProductVersion", 1,0,0,1
       END
   END
   BLOCK "VarFileInfo"
   BEGIN
       VALUE "Translation", 0x409, 1252
   END
END

这实际上将您要编辑的所有版本信息内容从资源编辑器传输到单独的文件中。这使得在编辑器外部编辑资源文件时不会出错。缺点是您无法再从资源编辑器编辑版本信息。但是,由于我们希望自动更新这些内容,这不是什么大问题。

接下来,我创建了一个VersionInfo.h文件并将其添加到我的项目中:

#pragma once

//major release version of the program, increment only when major changes are made
#define VER_MAJOR 2

//minor release version of the program, increment if any new features are added
#define VER_MINOR 0

//any bugfix updates, no new features
#define VER_REV 0

//if this is some special release (e.g. Alpha 1) put the special release string here
#define STR_SPECIAL_REL "Alpha 1"


#define FILE_VER VER_MAJOR,VER_MINOR,VER_REV
#define PROD_VER FILE_VER

//these are special macros that convert numerical version tokens into string tokens
//we can't use actual int and string types because they won't work in the RC files
#define STRINGIZE2(x) #x
#define STRINGIZE(x) STRINGIZE2(x)

#define STR_FILE_VER STRINGIZE(VER_MAJOR) "." STRINGIZE(VER_MINOR) "." STRINGIZE(VER_REV)
#define STR_PROD_VER STR_FILE_VER " " STR_SPECIAL_REL

#define STR_COPYRIGHT_INFO "©" BuildYear " Your Company. All rights reserved."

然后我在rc2文件中包含VersionInfo.h并进行了以下更改:

#include "VersionInfo.h"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//

<no changes>
           VALUE "FileVersion", STR_FILE_VER
           <no changes>
           VALUE "LegalCopyright", STR_COPYRIGHT_INFO
           <no changes>
           VALUE "ProductVersion", STR_PROD_VER
<no changes>

使用此设置,我可以编辑我的构建脚本(使用Perl)来修改VersionInfo.h文件中的版本信息,然后使用devenv命令行重建整个项目。

我添加的另一个步骤也可能是有意义的(虽然它尚未完全完善,并且可能是未来的问题)是每次构建项目时生成唯一的构建号。在当前的版本中,它始终适用于完全重建,但仅适用于增量构建。我所做的是创建一个名为build_number.incl的文件,其中包含以下内容:

#define CurrentBuildNumber  "20081020P1525" 

本质上是构建开始的日期和时间。我创建了一个批处理文件,作为生成此文件的项目的预构建事件运行。该脚本还定义了BuildYear,以便VersionInfo.h文件中的版权始终包含最新版本的年份。批处理脚本如下:

    echo Generating Build Number
    @For /F "tokens=2,3,4 delims=/ " %%A in ('Date /t') do @(
    Set Month=%%A
    Set Day=%%B
    Set Year=%%C
    )

    @For /F "tokens=1,2,3 delims=/M: " %%A in ('Time /t') do @(
    Set Hour=%%A
    Set Minute=%%B
    Set AmPm=%%C
    )

    @echo #define CurrentBuildNumber  "%Year%%Month%%Day%%AmPm%%Hour%%Minute%" > "$(ProjectDir)\build_number.incl"
    @echo #define BuildYear "%Year%" >> "$(ProjectDir)\build_number.incl"
    echo ----------------------------------------------------------------------

然后,该文件将包含在项目中需要使用内部版本号的任何文件中(即“约”框)。

其中一些是从this CodeProject post.

收集的

希望这些信息有用。

答案 2 :(得分:2)

我遇到了同样的问题,我发现在 .vdproj 中修改 prebuildevent 文件并不完全符合我的要求

我在构建安装项目后使用了其他一些代码来修改 msi 文件,因此我使用 postbuildevent

请参阅我的博文here

答案 3 :(得分:1)

我们使用一个程序,根据配置文件值更新每个AssemblyInfo.cs或AssemblyInfo.vb。我们在每次构建之前运行此可执行文这是我们为自动化这一过程所能做的最好的事情。您可以在项目配置中添加对此批处理过程的调用作为预构建步骤。

答案 4 :(得分:0)

您可以使用msbuild任务更新产品版本。查看MSBuild团队关于此主题的this post

答案 5 :(得分:0)

Embedding SVN Revision number at compile time in a Windows app

在我对这个问题的回答中,我描述了如何使用SVN完成此任务。

答案 6 :(得分:0)

这可能不是你所追求的,但回到时间的迷雾中,我写了一个名为stampver的东西,它可以直接在.exe文件中自动增加内部版本号作为后期建立步骤。

答案 7 :(得分:0)

<强> Resource Tuner Console

  

此控制台资源编辑器允许创建可靠且可重复的   在决赛期间更新产品版本信息资源的过程   从命令提示符开始构建过程的阶段。

具体请参见批量处理文件版本信息页面以获取更多详细信息:

答案 8 :(得分:0)

答案 9 :(得分:0)

我知道这是一个非常老的线程,但这是一个实现相同目的的vbs解决方案。只需将其放在.vdproj文件旁边的部署文件夹中即可。

Function CreateGuid()
    CreateGuid = Left(CreateObject("Scriptlet.TypeLib").Guid,38)
End Function

Const ForReading = 1, ForWriting = 2, ForAppending = 8

Set fso = CreateObject("Scripting.FileSystemObject")
Set RegEx = CreateObject("VBScript.RegExp")

For Each file in fso.GetFolder(".").Files
    if (fso.GetExtensionName(file.Name) = "vdproj") then
        WScript.Echo "Updating: " + file.Name
        Set oFile = fso.OpenTextFile(file.Name, ForReading, True)
        fileContents = oFile.ReadAll
        oFile.Close
        RegEx.Pattern = """ProductCode"" = ""8:{.*-.*-.*-.*-.*}"
        fileContents=Regex.Replace(fileContents, """ProductCode"" = ""8:" & CreateGuid)
        Set oFile = fso.OpenTextFile(file.Name, ForWriting, True)
        oFile.Write fileContents
        oFile.Close
    end if
Next

然后在您的真实项目中,有一个类似于:

的帖子构建事件
cd $(SolutionDir)\CustomWebSetup
cscript -nologo UpdateProductCode.vbs

这将使用新的ProductCode更新vdproj,为 next 构建做准备。构建完成后,VS将提示重新加载部署项目。

答案 10 :(得分:-3)

研究RCS,CVS和/或颠覆的使用。我只熟悉RCS;我的理解是CVS基于RCS但更全面。我已经在各种板上看到颠覆是更好的,但我从未使用它。 RCS足以跟踪我所有文档和软件项目的变化和版本。

RCS在这里:http://www.cs.purdue.edu/homes/trinkle/RCS/

CVS在这里:http://www.nongnu.org/cvs/

Subversion在这里:http://subversion.tigris.org/