Version Build

An automated method to generate meaningful version numbers in a MS Devstudio project's version resources has been a surprisingly popular topic. After following leads to a variety of solutions, none that I came across quite do what I would like. Here is a solution that suits my needs, perhaps it will suit yours too.

The resource version number is a structure of two double word values, the Most Significant Value (MSV) and the Least Significant Value (LSV). Each value is broken into two parts, the high word and the low word. In a resource script, this is represented by something like "FILEVERSION 1,0,0,1" or "PRODUCTVERSION 1,0,0,1".   The "1,0" is the high word/low word of the MSV. The "0,1" is the high word/low word of the LSV. There is also a string representation of the versions in the StringFileInfo block.

I find it desirable to to use the LSV to track incremental builds. Generally, marketing types like to dictate the MSV. So while I may be working on what I consider a Beta release, they want it stamped as version 2.1. But I digress.... :-)

The protocol I use for development versioning is to set the high word of the LSV to a value that indicates the year and day of the build. The low word counts the builds in the given day.

The way the high word is formulated is this: Using the ASCII decimal representation of the year, take the first digit ( e.g, 1998=1, 1999=1, 2000=2 ), multiply times 10, then add the last digit of the year (e.g., 1998=8, 1999=9, 2000=0), then multiply the sum by 1000 (e.g., 1998=18000, 1999=19000, 2000=20000). Now add the day of the year (e.g., Jan 1= 1, Jan 31=31, Feb 1=32). The high word for February 1, 1999 would therefore be 19032, the high word for December 25, 1998 would be 18356, while the high word for June 23, 2000 would be 20175.

The low word is started at 1 for the first build of the day, and incremented by 1 for each ensuing build.

Armed with this information, it is possible to go back in the source control application and find the version of the source that generated any given build. But of course it is tedious and demands more diligence than I can muster to reliably maintain the version by manual input. Thus I present this Devstudio macro that does all this for me, "VersionBuild".

When invoked, VersionBuild will attempt to locate the version resource. If successful, it will modify the FILEVERSION entry according to the protocol outlined above. If successful, VersionBuild will continue to build the project currently active.

By default, VersionBuild will synchronize the LSV of the PRODUCTVERSION as well as the StringFileInfo block's FileVersion and ProductVersion. There are two variables at the top of the macro, bPRODUCTVERSION and bStringFileInfo, which may be set appropriately to control which version types you want modified.



Sub VersionBuild()
'DESCRIPTION: Sets LSV of version number: Hi word = 1st digit of year + last digit of year + day of year; Lo word = 1 if new Hi word or previous + 1 if same Hi word
'Patrick Dell'Era
'patrickd@sirius.com
'
    Dim i
    Dim strHiWord
    Dim strLoWord
    Dim nHiWord, nOldHiWord
    Dim LSV
    Dim strTemp
    Dim strMsg
    Dim bPRODUCTVERSION, bStringFileInfo

    ' Set to True if you want the PRODUCTVERSION synchronized
    bPRODUCTVERSION = True
    ' Set to True if you want the StringFileInfo block synchronized
    bStringFileInfo = True

    strMsg = "There was a problem modifying your version resource. Could not locate "

    ' Open the resource file as text
    ' NOTE: You will probably be informed that the resource is
    ' already opened in the resource editor. You'll need to confirm
    ' that you want to close that and open the file as text. Otherwise,
    ' we will return an error informing you that the resource file is
    ' not in the documents collection

    ' Trap errors for likely suspects
    On Error Resume Next
    ' Attempt to open the document
    Documents.Open (ActiveProject.Name + ".rc"), "Text"
    If Err.Number <> 0 Then
        MsgBox ("Error 0x" & Hex(Err.Number) & ":  " & Err.Description)
        Exit Sub
    End If
    ' Try to bring it to the fore
    Windows(ActiveProject.Name + ".rc").Active = True
    If Err.Number <> 0 Then
        MsgBox ("Error 0x" & Hex(Err.Number) & ":  " & Err.Description)
        Exit Sub
    End If
    ' Seek out the version resource block
    If ActiveDocument.Selection.FindText("VS_VERSION_INFO VERSIONINFO", dsMatchWord + dsMatchCase) = False Then
        MsgBox strMsg + """VS_VERSION_INFO VERSIONINFO"""
        Exit Sub
    End If
    ' Seek the binary FILEVERSION entry
    If ActiveDocument.Selection.FindText("FILEVERSION", dsMatchWord + dsMatchCase) = False Then
        MsgBox strMsg + """FILEVERSION"""
        Exit Sub
    End If
    ' Skip first two entries for the MSV portion of the version
    For i = 1 To 2
        If ActiveDocument.Selection.FindText(",") = False Then
            MsgBox strMsg + "comma #" + Trim(CStr(i)) + " in ""FILEVERSION""."
            Exit Sub
        End If
    Next
    ' Move off comma
    ActiveDocument.Selection.CharRight
    ' Select the entire number
    ActiveDocument.Selection.WordRight dsExtend
    ' Copy the number string
    strTemp = ActiveDocument.Selection.Text
    ' Convert the number string into an integer
    nOldHiWord = CInt(strTemp)
    ' Get the current year as a string
    strTemp = CStr(DatePart("yyyy", Now))
    ' Make the high word of the LSV equal to the first digit
    ' of the year ( 1998 = 1; 1999 = 1; 2000 = 2 ...) and
    ' the last digit of the year ( 1998 = 8; 1999 = 9; 2000 = 0 ...)
    strHiWord = CStr(Left(strTemp, 1)) + CStr(Right(strTemp, 1))
    ' Convert the string into an integer value times 1000 to allow
    ' room for the day of the year value that is calculated next
    nHiWord = CInt(strHiWord) * 1000
    ' Find out the day of the year for today
    LSV = CInt(DatePart("y", Now))
    ' Add it to the previously calculated year-based value
    nHiWord = nHiWord + LSV
    ' Preserve a copy of the value as a string
    strHiWord = CStr(nHiWord)

    ' If the current value of the high word of the LSV is not the
    ' same as the newly calculated one, then replace the old with
    ' the new
    If nHiWord <> nOldHiWord Then   ' new day
        strHiWord = CStr(nHiWord)
        ActiveDocument.Selection = strHiWord
    End If
    ' Let's find the low word of least significant value and adjust it
    If ActiveDocument.Selection.FindText(",") = False Then
        MsgBox strMsg + "comma #3" + " in ""FILEVERSION""."
        Exit Sub
    End If
    ' Move off the comma
    ActiveDocument.Selection.CharRight
    ' Select the entire number
    ActiveDocument.Selection.WordRight dsExtend
    ' If the high word of the LSV has changed, then we have begun a
    ' new day of compilation fun. So reset the low word to 1
    If nHiWord <> nOldHiWord Then   ' new day, restart counter
        LSV = 1
    Else
        ' Same day, new compilation, so increment the low word of
        ' the LSV
        ' Grab the number into a text string
        strTemp = ActiveDocument.Selection.Text
        ' Convert it into an integer
        LSV = CInt(strTemp)
        ' Increment the integer
        LSV = LSV + 1
    End If
    ' Convert the low word of the LSV into a string
    strLoWord = CStr(LSV)
    ' Copy the string into the selected text
    ActiveDocument.Selection = strLoWord

    ' NOTE: The following code will synchronize the PRODUCTVERSION, FileVersion, and ProductVersion
    ' entries of the resource file with the FILEVERSION. This is done with the same techniques.
    ' Set the bPRODUCTVERSION and bStringFileInfo values at the top of the macro appropriately.

    If bPRODUCTVERSION Then
        ' Now seek out PRODUCTVERSION and synchronize
        If ActiveDocument.Selection.FindText("PRODUCTVERSION", dsMatchWord + dsMatchCase) = False Then
            MsgBox strMsg + """PRODUCTVERSION"""
            Exit Sub
        End If
        For i = 1 To 2
            If ActiveDocument.Selection.FindText(",") = False Then
                MsgBox strMsg + "comma #" + Trim(CStr(i)) + " in ""PRODUCTVERSION""."
                Exit Sub
            End If
        Next
        ActiveDocument.Selection.CharRight
        ActiveDocument.Selection.WordRight dsExtend
        ActiveDocument.Selection = strHiWord
        If ActiveDocument.Selection.FindText(",") = False Then
            MsgBox strMsg + "comma #3" + " in ""PRODUCTVERSION""."
            Exit Sub
        End If
        ActiveDocument.Selection.CharRight
        ActiveDocument.Selection.WordRight dsExtend
        ActiveDocument.Selection = strLoWord
    End If

    If bStringFileInfo Then
        ' Now seek out FileVersion in the string block and synchronize
        If ActiveDocument.Selection.FindText("FileVersion", dsMatchWord + dsMatchCase) = False Then
            MsgBox strMsg + """FileVersion"""
            Exit Sub
        End If
        For i = 1 To 3
            If ActiveDocument.Selection.FindText(",") = False Then
                MsgBox strMsg + "comma #" + Trim(CStr(i)) + " in ""PRODUCTVERSION""."
                Exit Sub
            End If
        Next
        ActiveDocument.Selection.WordRight
        ActiveDocument.Selection.WordRight dsExtend
        ActiveDocument.Selection = strHiWord
        If ActiveDocument.Selection.FindText(",") = False Then
            MsgBox strMsg + "comma #4" + " in ""PRODUCTVERSION""."
            Exit Sub
        End If
        ActiveDocument.Selection.WordRight
        ActiveDocument.Selection.WordRight dsExtend
        ActiveDocument.Selection = strLoWord

        If bPRODUCTVERSION Then
            ' Now seek out ProductVersion in the string block and synchronize
            If ActiveDocument.Selection.FindText("ProductVersion", dsMatchWord + dsMatchCase) = False Then
                MsgBox strMsg + """ProductVersion"""
                Exit Sub
            End If
            For i = 1 To 3
                If ActiveDocument.Selection.FindText(",") = False Then
                    MsgBox strMsg + "comma #" + Trim(CStr(i)) + " in ""ProductVersion""."
                    Exit Sub
                End If
            Next
            ActiveDocument.Selection.WordRight
            ActiveDocument.Selection.WordRight dsExtend
            ActiveDocument.Selection = strHiWord
            If ActiveDocument.Selection.FindText(",") = False Then
                MsgBox strMsg + "comma #4" + " in ""ProductVersion""."
                Exit Sub
            End If
            ActiveDocument.Selection.WordRight
            ActiveDocument.Selection.WordRight dsExtend
            ActiveDocument.Selection = strLoWord
        End If  ' bPRODUCTVERSION
    End If ' bStringFileInfo

    'close RC file
    ActiveDocument.Close
    If Err.Number <> 0 Then
        MsgBox ("Error 0x" & Hex(Err.Number) & ":  " & Err.Description)
        Exit Sub
    End If
    'build active project
    ExecuteCommand "BuildToggleBuild"

End Sub






Comments

  • Goal

    Posted by snareenactina on 11/14/2012 02:13pm

    clapper Follow us: There is a massive oversupply of graduates in China, many of whom are taking very lowly jobs to pay the rent. Huge numbers remain unemployed. Any slow down of the Chinese economy will make matters worse of course. As Supamonkey points out, doing well in exams in China does not make you clever, but may make you good at passing exams (not necessarily useful in the real world). China's economy will need to keep growing at 9% for the forseeable future just to help mop up the growing army of graduates in a wide spectrum of average-earning jobs. GDP is one thing but where are all the profits going? Back to the US corporations who've exploited the Chinese people and a little is kept in China to keep the gov't happy so they continue to sell tehir people as slave labour. classroomthe One important factor not mentioned in the article is demographics. America maintains a healthy demographic profile with comfortable birth rates, which implies continued growth, while the EU’s small or negative birth rate foretells slower growth and mounting pressure on government pension programs. Long term forecasts by The Economist and other think tanks agree that demographics alone will mean the US continues its traditional lead in GDP growth versus the EU, such that by 2020 EU per capita share of GDP in the EU will be only half of that in the USA. taitensis Government also provides many kinds of help to businesses and individuals. It offers low-interest loans and technical assistance to small businesses, and it provides loans to help students attend college. Government-sponsored enterprises buy home mortgages from lenders and turn them into securities that can be bought and sold by investors, thereby encouraging home lending. Government also actively promotes exports and seeks to prevent foreign countries from maintaining trade barriers that restrict imports. outclass I salute your vision and hope to see the people of Botswana achieve it. attachmentk Track the Fed's efforts over the course of the recovery. dluhy+a+jejich+řešení+vyšší+úrokovou+sazbou+než+v+případě+bankovní+půjčky&d=archimagazine.com&oq=Archi+Magazine "sias Today steel prices soared to record highs as a report released by world steel producers confirmed worries that current production has failed to keep pace with world demand. One industry official, who did not wish to be named said.. brunt After viewing product detail pages or search results, look here to find an easy way to navigate back to pages you are interested in. terrific For those of you who don't understand, read post 82.

    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 …

  • Packaged application development teams frequently operate with limited testing environments due to time and labor constraints. By virtualizing the entire application stack, packaged application development teams can deliver business results faster, at higher quality, and with lower risk.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds