65.9K
CodeProject 正在变化。 阅读更多。
Home

版本控制构建

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (226投票s)

2004年1月15日

CPOL

35分钟阅读

viewsIcon

2519555

downloadIcon

20691

一个Visual Studio加载项和命令行实用程序,可自动执行.NET和VC++项目的版本控制

引言

当创建一个新项目时,Visual Studio会在其中生成一个AssemblyInfo文件。此文件包含AssemblyVersion属性等信息。版本信息由四个整数组成:主版本号、次版本号、内部版本号和修订号。Visual Studio 2002/2003生成的版本信息的默认模式是1.0.*,即主版本号设置为1,次版本号设置为0,而内部版本号和修订号是自动生成的。具体来说,在构建过程中,内部版本号是从2000年1月1日起的已过天数创建的,而修订号是从当天的当前本地时间创建的。VB.NET项目和托管VC++项目也适用类似的规则,只是项目信息文件的名称分别为AssemblyInfo.vbAssemblyInfo.cpp

然而,这种自动化有时可能会令人恼火。例如,如果您想为多个项目分配相同的版本。即使您在同一解决方案中重新构建所有项目,它们也可能获得不同的修订号。此外,如果您想从版本控制系统中重新构建一个旧的修订版本,您将不得不手动设置版本。

Visual Studio 2005默认生成AssemblyVersion属性的形式为1.0.0.0(即版本中没有通配符),并且还会添加AssemblyFileVersion属性。请注意,用户还可以包含分配给产品版本的AssemblyInformationalVersion属性。

正如George Shepherd的Windows Forms FAQ所建议的,一个同步多个项目版本之间版本号的简单方法是将版本信息提取到一个文件中,并从每个项目中引用它。然而,这种方法有一个缺点:如果一个程序集在不同的解决方案中使用,您最终可能会得到两个实际相同的程序集的版本。

此加载项的目的是帮助用户管理和同步所有这些版本,特别是对于包含多个项目的解决方案。Darriel Liu已经提供了一个解决方案(Visual Studio .NET 项目的生成号自动化),他创建了一个Visual Basic宏,修改了AssemblyVersion,基本上遵循了Microsoft的原始方法。本解决方案是用C#编写的,扩展了原始的思路,提供了GUI以获得更多控制,并能够独立或同步地管理所有三种版本类型。它还提供了一种自动化方式,以尽可能简化版本控制。

此外,加载项还支持非托管项目中Visual C++资源文件版本(FileVersionProductVersion)以及安装项目版本。

最后但同样重要的是,命令行实用程序不仅提供了加载项的批量处理功能,还将其功能扩展到Visual C++ 6.0项目。

本文首先提供版本的基本信息以及该工具如何管理它们。然后是实现细节,包括对所用特定技术.的描述。熟悉版本控制但对实现细节不感兴趣的读者可以跳到最后一部分,其中提供了用户基本说明。

目录

背景

本节将更详细地介绍.NET Framework中可用的版本,并描述该工具中使用的逻辑。

三剑客版本

如引言中已提到的,.NET Framework支持三种版本类型:AssemblyVersionAssemblyFileVersionAssemblyInformationalVersion,分别对应AssemblyVersionAttributeAssemblyFileVersionAttributeAssemblyInformationalAttribute。属性的实际值定义在AssemblyInfo文件中(Visual Studio 2005及更新版本将此文件隐藏在Properties子文件夹中)。

// ...

[assembly: AssemblyVersion("1.1.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.2.1.0")]
// ... 

请注意,给出的内容示例是C#AssemblyInfo文件;对于其他语言,语法略有不同。

正如读者可能知道的,AssemblyVersion存储在构建的程序集的元数据表中。它用于在其他程序集引用它时唯一标识一个程序集。此外,CLR在绑定到强命名程序集时使用此版本(更多细节可以在Jeff Richter的书“Applied Microsoft .NET Framework Programming”中找到)。AssemblyFileVersionAssemblyInformationalVersion仅供参考(例如,请参阅“如何使用程序集版本和程序集文件版本”“程序集版本控制”文章)。然而,值得注意的是,Windows Installer在将一个文件安装到已经存在同名文件的地方时会使用AssemblyFileVersion(请参阅“文件版本规则”文章 - 感谢si618指出这一点)。

这些值会合并到程序集中,并在编译后的程序集属性窗口的**版本**选项卡上显示。

窗格顶部显示的文件版本对应于AssemblyFileVersion属性,其他两个属性显示在“其他版本信息”组框内。如果AssemblyInfo文件中缺少任何属性,则会分配另一个可用属性的值。例如,如果只定义了AssemblyVersion属性,那么它的值将用于文件版本和产品版本。如果未定义版本,则默认为0.0.0.0

如果您查看.NET Framework文档中AssemblyVersionAttributeAssemblyFileVersionAttributeAssemblyInformationalAttribute类的描述,您可能会注意到它们每个都包含一个Version属性(在AssemblyInformationalVersionAttribute类中,该属性名为InformationalVersion)。此属性是一个字符串,这意味着它可以包含任何有效的字符串,而不限于由点分隔的四个整数列表。但是,如果您尝试将版本字符串更改为其他形式,编译器将发出警告或错误。至少必须提供一个整数(即主版本号)。因此,以下字符串是有效版本:

1
1.2
1.2.3
1.2.3.4

AssemblyVersion中,单个星号只能用作内部版本和修订号,或仅用作修订号的通配符。

1.2.*
1.2.3.*

有趣的是,尽管.NET Framework中有一个名为Version的类用于表示程序集版本,但上述版本类均未使用它。

C++资源文件中的版本

尽管对于托管C++项目,会创建一个AssemblyInfo.cpp文件(包含AssemblyVersion值),但其内容不会显示在编译代码的属性中。对于非托管C++应用程序,则使用资源文件(*.rc)来存储版本信息。

// ...

VS_VERSION_INFO VERSIONINFO
    FILEVERSION 1,0,0,1
    PRODUCTVERSION 1,0,0,1
    // ...

BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "041a04b0"
        BEGIN
            // ...

            VALUE "FileVersion", "1, 0, 0, 1"
            // ...

            VALUE "ProductVersion", "1, 0, 0, 1"
        END
    END
    // ...

END

正如您所见,文件版本和产品版本至少出现两次:在VS_VERSION_INFO块下方,以及在StringFileInfo块内。此外,StringFileInfo块可能包含多个块,每个块对应于不同的语言选择。另请注意,版本中的分隔符可能因本地化设置而异。

应该指出的是,对于托管C++项目,版本信息块不会在资源文件中自动生成,但开发人员必须添加它,例如在资源视图窗口中,或手动编辑资源文件的内容。

安装项目中的版本

与其他项目类型不同,安装项目只有产品版本。它可以包含最多三个由点分隔的整数,并存储在项目文件(扩展名为*.vdproj*)本身中(而不是单独的文件中)。

// ...
"Product"
{
    "Name" = "8:Microsoft Visual Studio"
    "ProductName" = "8:SetupProject"
    "ProductCode" = "8:{1DC3B403-8041-43BD-BA39-588EDA4325E4}"
    "PackageCode" = "8:{C2627176-ED8C-40B0-B9E2-095D4612A21C}"
    "UpgradeCode" = "8:{1FD6C202-4297-4AAE-8C48-DDB81C44EC44}"
    // ...
    "ProductVersion" = "8:2.0.0"
    // ...
}

您可能会注意到,数字8后面跟着一个冒号,它 precedes产品版本值。这个数字仅指示要跟随的数据类型(8代表字符串)。

当从Visual Studio环境中修改安装产品的版本时,系统会要求您修改ProductCodePackageCode。这些代码(以GUID形式给出)用于在后续安装或升级期间标识应用程序。因此,修改产品版本的工具应能够为这两个代码创建新的GUID。

本工具使用的逻辑

AssemblyInfo文件通常在创建项目时首次修改:开发人员输入公司名称、版权和产品描述等信息。之后,很少修改它,通常只更改版本信息。因此,当源代码在版本更改后被修改时,相应的“文件已修改”时间戳将比AssemblyInfo文件的时间戳更新。

当用户从四个命令中的任何一个启动该工具时,该工具将浏览当前打开的解决方案中的项目。对于C#、VB.NET、VJ#或VC++项目中的每个文件,最后保存文件的时间戳将与相应AssemblyInfo文件的时间戳进行比较。如果有一个文件的时间戳更近(这意味着源代码在上次版本更改后已被修改),则该项目将被标记为需要版本更新。在GUI中,项目将在主应用程序窗体中显示一个复选标记,并建议下一个版本,该版本将根据工具设置创建。用户可以更改选择,甚至修改下一个版本。从窗体触发构建后,应用程序将更新所有选定项目的程序集版本并(重新)构建解决方案。批量命令在没有用户干预的情况下执行相同的过程。

根据配置设置,该工具还将Visual C++资源文件(可能包含ProductVersionFileVersion)包含在编号方案中:如果资源文件包含版本信息,则其时间戳将与项目中所有文件的时间戳进行比较。如果项目(例如,托管C++应用程序)同时包含AssemblyInfo和资源文件中的版本信息,则将较大的版本用作参考。

需要指出的是,如果Visual C++项目包含资源文件但没有AssemblyInfo文件,添加新资源将始终将最新时间戳放在资源文件上,项目将不会被标记为版本更新。但是,值得注意的是,添加新资源通常会修改resource.h头文件,该文件在资源文件之前保存。因此,为了(至少部分)规避上述不一致性,参考时间戳(用于与项目中其他文件的时间戳进行比较)是从资源文件时间戳偏移一秒创建的。

由于安装项目只包含一个文件,因此无法为它们实现时间戳比较逻辑——用户必须手动选择这些文件进行版本更新。

使用演示项目 

下载的演示项目是一个VS2008解决方案,包含几个不同的项目。

  1. Addin项目,仅包含一个实现IDTExtensibility2IDTCommandTarget接口的类,用于创建加载项。该类是通过注册表注册的加载项的通用入口点(即COM对象注册),因此只需要注册一个类。
  2. Implementation项目,用于实现加载项功能的が主模块。
  3. Buttons是资源DLL,包含用于工具栏按钮和菜单的图像。
  4. CommandLine是命令行实用程序的主项目。
  5. Configurator项目,用于将配置对话框作为独立应用程序启动。
  6. Shared项目包含加载项和命令行实用程序共有的类。
  7. Test应用程序,用于在安装为加载项之前测试该应用程序。
  8. Setup,创建该工具的安装程序。

最初,该解决方案是在VS2002上为.NET Framework 1.x创建的。随着加载项的2.0版本,添加了对VS2005的支持,后来扩展到最新的Visual Studio版本,如工具历史中所述。为多个Visual Studio版本创建加载项需要进行一些重新排列(如下文迁移到.NET 2.0部分所述),并且项目Implementation已被复制(ImplementationVS7ImplementationVS8ImplementationVS9)以构建新环境的加载项。请注意,所有Implementation项目共享相同的源代码,使用条件编译来区分特定于不同环境的代码部分。 

该加载项最初使用永久命令栏。永久命令栏仅创建一次,当Visual Studio首次安装加载项后运行时,Visual Studio会在会话之间保存其位置。此外,加载项命令的按钮和菜单项可以自由复制并移动到其他工具栏/菜单。另一方面,临时命令栏在每次Visual Studio启动时创建,在每次Visual Studio关闭时销毁。加载项必须负责保存临时工具栏和菜单的位置及其布局。 

由于一些第三方加载项导致VCB菜单和工具栏在每次运行Visual Studio时都会重复,因此添加了带有临时栏的附加实现项目(ImplementationVSxTemporaryBars)和相应的Setup。实现项目共享大部分代码,因此它们包含相同的源文件。 

关注点 

项目中的最大挑战是利用VS.NET环境自动化,因为它文档很少且难以调试。此外,还使用了几个自定义控件和独特的解决方案。其中一些在以下各节中进行了描述。 

连接到Visual Studio环境

加载项通过Connect类与Visual Studio环境建立连接,该类的骨架由Add-in Wizard自动生成。该类的以下方法被使用:

  • OnConnection:  
    • 接收对应用程序对象的引用,该对象实际上是Visual Studio环境(EnvDTE)对象,并将其存储供工具进一步使用。
    • 选择VS环境中的当前线程UI文化(用于可选的本地化资源)并加载相应的本地化资源。
    • 创建加载项的工具栏和菜单。
    • 存储对Build和Cancel Build命令的引用,这些命令用于动态启用或禁用加载项工具命令。 
  • OnDisconnection:存储当前配置并移除工具栏和菜单栏。
  • OnStartupComplete:更新加载项命令的状态。
  • QueryStatus:禁用和启用加载项命令(使用Build和Cancel Build命令的状态作为参考);例如,当没有打开解决方案或VS环境正在编译或构建过程中时,加载项将被禁用。
  • Exec:打开GUI或执行批量命令之一。

SolutionBrowser类 

抽象的SolutionBrowser是“主力”VSSolutionBrowserVS7SlnFileReaderVS8SlnFileReaderDswFileReader类的基类,它们管理项目信息。VSSolutionBrowser在加载项中使用,并利用Visual Studio .NET自动化来浏览解决方案并收集所有包含的项目信息。它处理项目信息,例如所有与版本更新相关的项目项、文件保存时间比较以及VS环境设置。命令行实用程序的对应项(VS7SlnFileReaderVS8SlnFileReaderDswFileReader)通过解析相应的解决方案(*.sln*或*.dsw*)文件以及包含的项目文件来完成相同的工作。

在工具启动时,SolutionBrowser派生类会浏览选定的解决方案,并收集每个项目的信息:项目类型、存储版本的AssemblyInfo(以及可选的*.rc*和*.vdproj*)文件的完整名称(包括路径)、所有版本类型的当前值以及一个指示项目自上次版本更新以来是否已修改的标志。

AssemblyVersions类包含一组ProjectVersion,每个ProjectVersion代表一种版本类型。ProjectVersion能够比较和递增版本,以及应用带通配符的字符串模式。ProjectInfo类包含实际显示在ListView中的项目信息。AssemblyInfoStreamResourceFileStreamSetupVersionStream类派生自抽象的VersionStream类,并负责在相应文件中检索和存储版本。

主窗体

MainForm类表示主窗口,包含三个选项卡式ProjectsListView(派生自ListView类),显示所有项目的当前和建议的下一个版本,每个版本类型一个列表视图。为了避免在TabControl调整大小时出现众所周知的闪烁问题,使用了派生自UserControl的控件。

主窗口在ProjectsListView的右侧包含几个按钮,用于管理项目选择,以及触发保存和构建操作的按钮。它还包含一个VersionUpDown编辑框,用户可以在其中手动定义要应用于选定项目的新版本模式。

ProjectsListView

ProjectsListView是一个自定义绘制的列表视图控件。需要自定义绘制以允许动态更改项的外观:项根据版本可用性和有效性以不同的颜色显示,或者在项未选中时显示为灰色。通过实现“无闪烁ListView in .NET - 第2部分”文章中描述的技术,减少了过度的闪烁。

嵌入到ProjectsListView中的派生自TextBox的控件允许“待版本”的内联编辑,如“ListView子项的内联编辑”文章所述。需要注意的是,嵌入的TextBoxMultiline属性默认为false,其最小尺寸是有限的。这个尺寸大于列表视图单元格的尺寸,使得内联编辑控件的外观不协调。为了解决这个问题,EmbeddedTextBox被设置为多行,并重写了OnKeyPress方法来捕获Enter键并避免跳到下一行。

ProjectsListView还重写了OnItemCheck方法,以防止选中无效版本的项。

VersionTextBox

VersionUpDown控件是一个用户控件,由两个控件组成:VersionTextBoxSpinButtonVersionTextBox是一个控件,它对用户施加限制,即在输入版本时,只能使用由点分隔的四个整数、星号或加号字符序列。SpinButton派生自VScrollBar类。

VersionTextBox派生自TextBox,并重写了一些事件处理程序以确保特定行为。必须重写OnKeyPress以防止用户输入除数字或星号以外的任何内容。此外,版本序列的四个部分被虚拟地分为四个块,每个块都有自己的Tab停止。为了实现这一点,必须重写PreProcessMessage方法来处理TAB、HOME、END、BACKSPACE、DELETE和箭头键。 

为了使内部选项卡顺序与对话框选项卡顺序同步(当对话框中的下一个控件是back-tabbed时,最后一个块必须被选中),定义了两个委托实例并将其添加到Next和Previous控件的LostFocus事件中。

override protected void OnParentVisibleChanged(EventArgs e)
{
    base.OnParentVisibleChanged(e);
    if (TopLevelControl != null)
    {
        Control nextControl = GetNextTabControl(Parent, true);
        if (nextControl != null)
            nextControl.LostFocus += new System.EventHandler(
            OnNextControlLostFocus);
        Control previousControl = GetNextTabControl(Parent, false);
        if (previousControl != null)
            previousControl.LostFocus += new System.EventHandler(
            OnPreviousControlLostFocus);
    }
}
// searches for the next control that has a tab stop

private Control GetNextTabControl(Control ctl, bool forward)
{
    do
    {
        ctl = TopLevelControl.GetNextControl(ctl, forward);
        if (ctl == null || ctl == this)
        return null;
    }
    while (ctl.TabStop == false);
    return ctl;
}
// selects the last block

private void OnNextControlLostFocus(object sender, EventArgs e)
{
    SelectionStart = Text.Length - 1;
}
// selects the first block

private void OnPreviousControlLostFocus(object sender, EventArgs e)
{
    SelectionStart = 0;
}

为了防止选择跨越分隔点,有必要重写OnMouseDownOnMouseMoveOnMouseUp事件处理程序。此外,通过重写WndProc方法,将“全选”命令限制为单个块,同时禁用了上下文菜单、撤销操作以及所有剪贴板相关操作。

其他相关类

WindowAdapter类用于在显示MainFormPromptUnsavedDocumentsDialog作为模态窗体时,将VS环境主窗口作为它们的父窗口。PromptUnsavedDocumentsDialog模拟当“项目和解决方案”页面上的“生成和运行选项”设置为“提示保存更改…”时弹出的对话框。即,为了防止当加载项已启动时弹出此对话框(从而阻塞其执行),应用程序将首先检查未保存的文档,然后(如果需要)弹出PromptUnsavedDocumentsDialog,最后暂时禁用对打开文档的保存。

MessageFilter类用于处理调用Visual Studio自动化时经常出现的“应用程序忙”和“被调用方拒绝调用”错误,这些错误可能会阻止加载项启动(参见修复“应用程序忙”和“被调用方拒绝调用”错误文章)。

AssemblyInfoStreamResourceFileStreamSetupVersionStream类(派生自抽象的VersionStream类)用于读取当前版本并保存新版本。正则表达式用于定位、提取和保存新版本。

迁移到.NET 2.0

.NET 2.0中,Framework类库发生了一些变化。例如,命令栏已从Microsoft.Office移至Microsoft.VisualStudio.CommandBars程序集,并且倾向于使用EnvDTE80.DTE2而不是旧的EnvDTE.DTE类。尽管所用类的功能没有显著改变(其中大部分已扩展),但某些类被移至新的Framework程序集这一事实使得早期版本的加载项在没有代码修改的情况下对新IDE无用。

由于无论.NET Framework如何更改,加载项的功能都保持不变,因此代码可以进行一些小的源代码修改后重新编译,并更新对.NET Framework程序集的引用。但是,在这种方法中,将丢失与以前版本的VS IDE的兼容性。为了使源代码与以前的.NET Framework兼容,已在必要时插入了条件编译语句。实际上,除了一个例外情况,在所有情况下,插入

#if VS8
using EnvDTE80;
using DTE = EnvDTE80.DTE2;
#endif

到每个使用DTE类的源文件中就足够了。

使用以下条件预处理器指令解决了命令栏定义在不同程序集中的问题。

#if VS7
using Microsoft.Office.Core;
#elif VS8
using Microsoft.VisualStudio.CommandBars;
#endif

为了从相同的源代码生成两个不同的程序集,相应的项目文件被复制,两个项目都包含完全相同的源代码,但定义了不同的条件编译常量(VS 200x的VS7和VS 2005/2008的VS8)并引用了不同的.NET Framework程序集。当然,为了区分版本,输出被命名为不同的名称:*BuildAutoIncrementVS7*和*BuildAutoIncrementVS8*。

为了使用一个安装集并只有一个加载项注册用于所有IDE版本,代码被拆分为通用部分和每个版本特有的部分。通用启动代码检测当前活动的是哪个Framework,并加载相应的が主程序集。通过使用反射,在实现IAddin接口的が主类在程序集中被搜索,并创建一个该类的实例。IAddin接口定义在*Common*程序集中。下面提供了一个简化的代码:

int runtimeVersion = Environment.Version.Major;
Assembly assembly;
switch (runtimeVersion)
{
case 1:
    assembly = Assembly.Load("BuildAutoIncrementVS7");
    break;
case 2:
    assembly = Assembly.Load("BuildAutoIncrementVS8");
    break;
default:
    return;
}
// in the main assembly find the type that implements IAddin

// interface and create an instance of it

Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
    if (type.IsClass)
    {
         if (type.GetInterface("IAddin", true) != null)
         {
             ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
             m_addin = (IAddin)ci.Invoke(new object[0]);
         }
    }
}

启动模块中的方法仅将调用转发给が主实现类的相应方法。

SourceSafe下的文件

该应用程序还能处理SourceSafe控制下的代码:它会在必要时自动签出项目。但是,要充分利用这种自动化,请注意,SourceSafe必须配置为将本地文件的日期和时间设置为签出时的修改日期和时间(参见下图),而不是默认的“当前”值。

此外,建议您将“签入项被编辑时”(在Visual Studio的“源控件”类别下的“选项”对话框中)设置为“自动签出”。否则,每次都会提示您手动签出项目。而且,在这种情况下,从代码中签出项目非常棘手,因为对以下方法的调用会失败:

public static bool CheckOutItem(string fileName, DTE dte)
{
    if (dte.SourceControl.IsItemUnderSCC(fileName) &&
        !dte.SourceControl.IsItemCheckedOut(fileName))
        return dte.SourceControl.CheckOutItem(fileName);
    return true;
}

为避免这种情况,实现了Catalin Stavaru提供的想法:以编程方式选择VS环境的解决方案浏览器中的项,然后发出签出命令。有兴趣的读者可以在SolutionExplorerCheckoutHelper类中找到实现细节。

使用加载项

安装后,将添加一个名为**VCB**的菜单以及一个新的**版本控制构建**工具栏(见下图)。它们包含四个项目,如下所述:

  1. **版本控制构建**将打开一个窗口,如本文开头所示。已准备好进行版本更新的项目会自动选中,但用户可以根据自己的意愿修改版本。
  2. **更新版本后构建**将把新版本应用于已修改的项目并触发“构建解决方案”命令。
  3. **更新版本后重新生成**将把新版本应用于已修改的项目并触发“重新生成解决方案”命令。
  4. **保存更新后的版本**将首先保存所有已修改的文件,然后保存已修改项目的版本。

根据VS环境“生成和运行选项”(“选项” - “环境” - “项目和解决方案”)中的选择,操作1、2和3将首先保存所有当前打开的文件。用户可以为任何上述操作分配快捷键(这是几个用户的要求)。

此外,VCB菜单包含四个额外的条目:

  1. **保存版本**将当前版本导出到文件。
  2. **打印版本**将打印当前版本。
  3. **配置**启动配置对话框。
  4. **关于**弹出信息框。

GUI

当启动GUI命令时,加载项将浏览当前打开的解决方案中的所有项目,并显示其当前版本(如果可用)。它还根据工具设置中定义的增量模式建议下一个版本。已检测到代码更改的项目项以绿色显示,并自动标记为更新。未检测到代码更改或未找到有效版本信息的项最初显示为灰色。

版本显示在三个选项卡式的列表视图中,每个列表视图对应一种版本类型:AssemblyVersionAssemblyFileVersion(即FileVersion)和AssemblyInformationalVersion(即ProductVersion)。可以通过单击列表视图上方的相应按钮或使用Ctrl+Tab键组合来切换选项卡。

用户可以根据自己的意愿选中/取消选中项目(只有具有有效版本的项才能选中)——所有命令将仅应用于选中的项。请注意,根据配置设置,可能会出现一个项目在一个列表视图中被选中而在另一个列表中未被选中——在这种情况下,将仅处理选中的版本。

通过“应用于所有选项卡”复选框,用户可以控制GUI命令是分发到所有列表视图(即所有版本选项卡)还是仅应用于当前可见的列表视图。它会覆盖工具配置中类似的设置。

应用版本模式

列表视图下方的文本框包含一个可以应用于列表中选定项目的模式。在加载项启动时,此文本框包含建议的最大的“待版本”。但是,用户可以将其更改为任何有效版本。此外,可以使用星号(*)或加号(+)字符后跟可选整数的模式。任何版本位置(主版本号、次版本号、内部版本号或修订号)上的星号将阻止该位置被修改。这可能很有用,例如,当用户想同时递增多个或所有项目的次版本号,但保留各个内部版本和修订号不变时。加号字符将按提供的整数递增相应版本位置,如果未提供,则递增1。例如,“1.0.*.+2”模式分别将主版本号和次版本号设置为1和0,保持内部版本号不变,并将修订号增加2。

当文本框的内容被修改时,列表视图中的版本将与版本模式进行比较。如果模式可能导致版本低于项目当前版本,则项目将以红色显示,作为给用户的视觉警告。

按下“应用”按钮后,文本框中的模式将应用于列表视图中的所有选定项目。请注意,文件中的实际版本直到用户单击“命令”按钮之一(如下面的“应用更改”子部分所述)才会被更改。

增加主版本号、次版本号、内部版本号或修订号

提供一组四个按钮,仅用于增加标记项目中某个版本组件。其他版本组件将不会被修改,除非进行相应配置(参见下面的“设置”部分)。主版本更改时,次版本组件始终重置为0。

手动修改版本

对于现有版本,可以手动编辑建议的版本:只需单击“待版本”列中的版本,或选择相应项并按F2键。新版本将经过验证,只允许至少有两个由点分隔的整数和一个可选的星号字符的版本。

应用更改

应该指出的是,在单击“保存”、“构建”或“重新生成”按钮之前,新版本不会实际保存。“保存”按钮仅将新版本保存到相应的文件中,而“构建”和“重新生成”按钮还会向Visual Studio环境发出相应的命令。

批量命令

批量命令等同于GUI中的“保存”、“构建”和“重新生成所有”命令,不同之处在于它们立即执行,无需用户干预。项目的版本将根据工具的设置自动递增,如下所述。

命令行实用程序

命令行实用程序支持VC++ 6.0 DSW文件以及VS2002/2003/2005/2008/2010/2012/2013 SLN文件。它与加载项版本共享配置设置,但用户可以使用适当的启动开关覆盖这些设置。请检查安装程序中包含的*CommandLine.txt*文件,以获取简要说明和启动开关列表。

在命令行实用程序安装过程中,将在“程序”菜单中添加相应的菜单,包含两个项目。“AutoVer”条目以`/g`开关启动命令行实用程序,打开与加载项相同的GUI。

配置

设置存储在用户*ApplicationData*文件夹中的*Configuration.xml*文件中。此文件还存储主窗体的大小和列表视图中列的宽度。当用户在工具安装后首次启动Visual Studio时,将创建一个包含默认值的配置文件。由于它创建在用户配置文件中,因此每个用户都可以独立配置该工具。

设置对话框包含四个选项卡页,将在以下各节中介绍。

通用

在“通用”选项卡页上,用户可以选择启动时在主窗体中显示哪个版本(AssemblyVersionAssemblyFileVersionAssemblyInformationalVersion)。此外,此默认版本将是工具栏和菜单上的最后三个按钮或菜单项相对应的“批量”命令所处理的版本。如果选中“应用于所有版本类型”,所有版本类型将独立处理,除非选中“为每个项目同步所有版本类型”。通过“允许任意信息版本”,用户可以手动输入自由格式文本(不符合文章开头中描述的版本模式)到相应的列表视图条目中,如手动修改版本子节中所述。“包括VC++资源文件”包括处理相应*.RC*文件中包含的ProductVersionFileVersion

要包含Visual Studio安装项目进行处理,必须选中“包括安装项目”选项。还有一个选项可以在修改安装项目版本时自动生成新的ProductCodePackageCode

再次需要指出的是,由于安装项目只包含一个*.vdproj*文件,因此无法检查任何更改,所以用户必须手动标记安装项目进行版本更改。

编号方案

“编号方案”选项卡页允许用户微调自动编号方案。选择“默认情况下,递增:”选项,用户可以选择哪个版本部分被自动递增。这对于那些喜欢保留星号作为内部版本和修订号(如Microsoft最初提出的)并仅递增次版本号的人来说可能很有用:内部版本号和修订号的星号掩码将保持不变(除非用户选择下面的“重置...”选项之一)。

当选中“基于日期和时间的内部版本号和修订号编号”选项时,内部版本号和修订号的数字将使用本文开头提到的日期和时间规则生成,用实际整数替换星号。数字在工具启动时根据当前本地日期和时间生成。

重置选项提供了更精细的控制,用于在增加主版本号、次版本号或内部版本号时对较低有效数字进行处理。请注意,主版本号递增时,次版本号始终会重置。

如果“用组件值替换星号”未选中,版本中的星号将不会被整数值替换。

外观

此选项卡允许用户修改一些显示选项:用于突出显示列表视图项的着色方案以及项在列表视图中的外观。对于颜色选择,已在其他地方开发了一个单独的控件。

批量命令

批量命令选项卡提供了对批量命令的额外控制。用户还可以禁止在执行批量命令时显示的报告对话框。 

文件夹 

此选项卡包含SourceSafe命令行(VCB命令行实用程序必需)的路径和IIS根文件夹的路径。这些值通常在VCB安装时检测到,因此用户无需修改它们。

导出 

此选项卡包含打印版本和导出到文件的设置。可以选择版本以及导出顺序,定义缩进深度(用于导出到文件中的字符数或打印时的行高)。还可以为打印机输出选择字体。对于CSV文件输出,可以选择分隔符;根据本地化设置,逗号字符并不总是被识别为分隔符。 

安装说明 

如果您已安装此工具的任何先前版本,建议先卸载它。

有用于加载项的独立安装程序,带有永久命令栏(*BuildAutoIncrement.msi*)和用于加载项的安装程序,带有临时命令栏(*BuildAutoIncrementTemporaryBars.msi*),适用于所有Visual Studio版本(即2003、2005、2008、2010、2012和2013)。 

加载项无法安装在Visual Studio的Express版本上,因为它们不允许加载项。命令行工具没有先决条件,除了必须安装.NET 2.0或更高版本。

鸣谢 

我要感谢Don Bailes、Carl Mercier、David Smith以及许多其他人测试加载项并帮助我修复错误。 

历史 

  • 版本 1.0
    • 初始版本(于2004年1月15日发布)。 
  • 版本 1.1
    • 支持VB.NET项目,并对UI进行了一些外观上的更改。请注意,此版本的安装程序将自动删除之前的版本。
  • 版本 1.2
    • 添加了对托管VC项目的支持,文本编码设置为默认值(允许使用扩展字符),添加了MessageFilter以处理经常阻止应用程序的COM消息,也显示了缺少AssemblyInfo文件的项目,添加了用于增加选定项目的主版本、次版本或内部版本号的按钮(默认情况下修订号始终递增),并添加了一个仅保存更新后的AssemblyInfo文件的“保存”按钮。
  • 版本 1.3
    • 添加了设置对话框,设置会在会话之间保存(参见上面的“设置”部分),并进行了一些错误修复。
  • 版本 1.4
  • 版本 1.5
  • 版本 1.6
  • 版本 1.7
  • 版本 1.8
  • 版本 1.9
    • 修复了版本1.8引入的“企业模板子项目未显示”错误。
  • 版本 2.0
    • 支持VS 2005(请注意,加载项仅在VS 2005的beta 2版本上进行了测试;我还没有机会在IDE的发布版本上测试该加载项)。设置中添加了附加选项,用于选择默认情况下递增版本号的哪个部分。小的错误修复。重新排列了解决方案,以便能够同时为VS 2002/2003和VS 2005进行构建。
  • 版本 2.1
    • 修复了2.0版本的安装问题,为AssemblyVersionAssemblyFileVersionAssemblyInformationalVersion(即产品版本)添加了单独的选项卡。**注意**:此版本与VS2002/2003和VS2005兼容。但是,在某些情况下,VS 2005工具栏/菜单上的图标,由于未知原因,将不会显示。
  • 版本 2.2
    • 代码重构,小的错误修复(例如版本字符串周围的空格问题),GUI的小改动(选项卡式列表视图之间的滚动位置同步,高亮颜色配置),实现了“待版本”的内联编辑,为批量命令添加了报告对话框,增加了对安装项目的支持。
  • 版本 2.3
    • 修复了解决方案文件夹未显示错误;安装包已拆分(有一个用于VS2002/2003/2005的安装程序,以及一个用于仅有VS2005的系统的独立安装程序);工具栏/菜单已设为永久,因此用户可以修改相应的图标(如果它们在VS2005中未显示);列表视图中的项目按解决方案资源管理器中的顺序显示(安装项目放在最后);解决方案文件夹和企业模板中的项目可以缩进显示(如“设置”对话框的“外观”选项卡中所选)。已知问题:与某些第三方加载项冲突。
  • 版本 2.4
    • 包含了命令行实用程序,该实用程序支持VC++ 6.0 DSW文件以及VS2002/2003/2005 SLN文件(请检查*CommandLine.txt*文件以获取简要说明);
    • 一些代码重组和重构,一些小的错误修复。
  • 版本 2.5
  • 版本 3.0
    • 代码重构,修复了一些错误并实现了新功能(我没有在Vista上测试该工具,所以请检查VistaVista RC2消息以获取安装问题)。
    • 加载项可以安装在Visual Studio 2008(beta2)上,并且命令行实用程序可以与Visual Studio 2008项目一起使用。
    • 修复了VS2005中复制按钮和菜单项的错误
    • 修复了无效路径的错误;这也解决了网络共享上的项目问题
    • 现在可以正确处理解决方案文件夹中的安装项目。
    • 修复了Web项目版本未显示的错误。它也应该在命令行实用程序中工作。首次启动时,实用程序会检查IIS是否已安装,并应自动获取相应的根文件夹。此文件夹显示在设置对话框的“文件夹”选项卡中,但可以手动修改。
    • 修复了SourceSafe命令行无效路径的错误。此外,此路径可以在设置对话框的“文件夹”选项卡中手动设置。
    • 在配置(编号方案选项卡)中添加了从1开始重新生成生成和修订版本的选项。
    • 在配置(通用选项卡)中添加了在加载项命令开始前保存所有文件的选项。
    • 如果C++项目的资源(*.rc*)文件中的FileVersionProductVersion不包含所有组件(主版本.次版本.内部版本.修订号),则只更新.RC文件中存在的组件
    • 如果C++项目包含多个带有版本字符串的资源(*.rc*)文件,则会更新所有文件中的版本。
    • 在配置(编号方案选项卡)中添加了定义版本增量步长的选项。
    • 可以在配置(通用选项卡)中为AssemblyInformationalVersion(即非C++项目的产品版本)输入任意文本的选项。此选项也适用于命令行实用程序。
    • 现在可以通过在GUI的“待版本”框前面加上'+'字符来输入任何版本增量,例如“1.0.0.+10”(将当前修订号增加10)。
    • 命令行实用程序已完成。请参阅实用程序随附的用户指南*CommandLine.txt*以获取详细信息。请注意,几个命令行开关已修改/重命名。
  • 版本 3.1
    • 添加了打印当前版本或将其保存到文本/CSV文件的选项,支持Windows视觉样式,以及一些错误修复。
      **注意**:如果您安装了VS2005/2008的3.0版本(适用于VS2005/2008)并在安装了VS 2008的系统上,由于其安装中的一个错误,您需要按照以下步骤操作:
      1. 先卸载前一版本。
      2. 检查VS2008中是否仍然存在**命令**(不是工具栏/菜单):工具 - 自定义 - 命令选项卡,在类别列表中选择加载项,然后查看它是否包含GUIBuildRebuildSaveConfigureAbout条目。如果其中任何一个存在,请从Visual Studio 2008命令提示符运行以下命令:
        devenv /resetaddin BuildAutoIncrement.Connect
        此命令将清理剩余的命令。
      3. 运行新安装程序。
  • 版本 3.2
    • 支持Visual Studio 2010项目。
    • 支持Merge module、Cab和Web安装项目。
    • 在64位系统上正确识别*SourceSafe*文件夹。
    • 命令行工具中的`/V`标志将覆盖配置/默认值。
  • 版本 3.3
    • 提供了两个安装程序:*BuildAutoIncrement.msi*用于带有永久VCB工具栏/菜单的加载项,*BuildAutoIncrementTemporaryBars.msi*用于带有临时VCB工具栏/菜单的加载项。请参阅安装程序存档中的*readme.txt*文件以获取更多详细信息。
    • 解决了每次启动Visual Studio 2010时菜单/工具栏项复制的问题。
    • F#项目将被显示,并且包含F#项目的解决方案文件夹将正确显示,包括其中的所有项目。
    • Setup、Merge module、CAB和Web安装项目的版本将正确显示。
    • 当Visual Studio的视觉主题被禁用时,GUI正常打开。
    • 卸载过程中,将显示一个选项对话框,允许用户选择是否自动移除VCB菜单和工具栏。请参阅安装程序存档中的*readme.txt*文件以获取更多详细信息。
    • 修正了Michel Gerber指出的关于`*`的问题。 
    • 非常感谢Thomas Klähn、Stefano Leardini和Pierre Granger帮助我识别了复制/消失的工具栏问题。
  • 版本 3.4
    • **注意**:如果您安装了先前版本,强烈建议先卸载它。
    • 支持Visual Studio 2012和2013(在公开预览版上测试)。
    • 命令行实用程序支持.vcxproj(Visual Studio 2010引入的C++项目文件格式)。
    • 包括对InstallShield LE的支持。
    • Visual Studio 2008/2009/2010/2012/2013的加载项使用基于XML文件的注册。Visual Studio 2003和2005的加载项仍使用COM注册。
  • 版本 3.5
    • 修复了菜单索引问题。 
    • Addin对TFS的支持已恢复。
© . All rights reserved.