<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2.3" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Mark NelsonWork &#187; </title>
	<link>http://marknelson.us</link>
	<description>Programming, mostly.</description>
	<pubDate>Thu, 26 Aug 2010 13:32:59 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2.3</generator>
	<language>en</language>
			<item>
		<title>Don Killen RIP</title>
		<link>http://marknelson.us/2006/08/25/don-killen-rip/</link>
		<comments>http://marknelson.us/2006/08/25/don-killen-rip/#comments</comments>
		<pubDate>Fri, 25 Aug 2006 21:02:50 +0000</pubDate>
		<dc:creator>Mark</dc:creator>
		
		<category><![CDATA[People]]></category>

		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">/2006/08/25/don-killen-rip/</guid>
		<description><![CDATA[I worked for Don Killen at Greenleaf Software for quite a few years in the late 80s and 90s. Don was a pioneer in the world of commercial C and C++ libraries, and I received the sad news that he passed away this week.]]></description>
			<content:encoded><![CDATA[<p><img src="http://marknelson.us/attachments/2006/misc/don.gif" class="alignleft">I received a sad email from Andy Johnson of <a href="http://www.greenleafsoft.com/" class="newpage">Greenleaf Software</a> yesterday, giving me the news that Greenleaf&#8217;s founder <a href="http://www.donkillen.com/" class="newpage">Don Killen</a> died in his sleep Monday, August 21, 2006. </p>
<p>Don was a pioneer in the world of desktop C and C++ programming, since he sat down in 1982 and hammered out his flagship product, Greenleaf Functions. Back in the days when MS-DOS programmers still had to use the Lattice C compiler, Don saw that there was potential big market for a library that provide glue between the BIOS, the DOS API, and C programmers. Armed with references and a copy of MASM, he created the product, placed a few ads, and found himself with enough orders to go into the business full time. (Mind you, this was back in the early 80s, and Don was managing to get over $200 a pop for this library.) You can follow Don&#8217;s version of that history <a href="http://www.donkillen.com/personal.asp" class="newpage">here</a>.</p>
<p>I went to work for Greenleaf in 1989 after burning most of my bridges with telephony startup SRX (later absorbed by <a href="http://www.teltronics.com/" class="newpage">Teltronics</a>.) It was a big change for me - Greenleaf was a small family business and I had to try to learn how to operate in that kind of environment. During all my years with Greenleaf, I could never forget that it was Don&#8217;s world, and we were lucky to get to play in it.</p>
<p>Greenleaf had quite a few good years, but as the 90s waxed the product mix wasn&#8217;t attracting the kind of sales that it needed to keep the place going, and Don&#8217;s health was always an issue. Despite a fortunate kidney transplant, as he got older, I don&#8217;t think he had the energy and vigor he needed to reinvent the company for the new millenium. Seeing the writing on the wall, the development team branched off to form a contract programming company called <a href="http://addisoft.com/" class="newpage">Addisoft Consulting</a>. Tammie Williams, Patrick Little and Ruby Hjelte are still there, and worked with Don and Greenleaf from time to time.</p>
<p>Working with Don was a great experience, and I can honestly say that I learned more about the software business from both him and Tammie than I could have managed anywhere else. It was a rare opportunity for an inexperienced programmer, and I really feel luck to have had the opportunity, and to have gotten to know Don.</p>
<p>May he rest in peace.</p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2006/08/25/don-killen-rip/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fun With Version Control</title>
		<link>http://marknelson.us/2000/06/01/version-control/</link>
		<comments>http://marknelson.us/2000/06/01/version-control/#comments</comments>
		<pubDate>Thu, 01 Jun 2000 16:01:37 +0000</pubDate>
		<dc:creator>Mark</dc:creator>
		
		<category><![CDATA[Work]]></category>

		<category><![CDATA[Magazine Articles]]></category>

		<guid isPermaLink="false">/2000/06/01/version-control/</guid>
		<description><![CDATA[An article written with Ping Ni in which we describe some of the joys of keeping versions straight when developing complex Windows programs.]]></description>
			<content:encoded><![CDATA[



<table border="0">
<tr>
<td style="width: 33%"><img alt="DDJ Cover from June, 2000" src="http://marknelson.us/attachments/2000/version-control/ddj_2000_06.jpg" /></td>
<td style="width: 66%"><strong>Dr. Dobb's Journal</strong> June, 2000<br/>by Mark Nelson and Ping Ni</td>
</tr>
</table>
<p>Windows users are all familiar with the concept of DLL hell. This occurs when applications try to work with mismatched versions of DLLs, resulting in bugs, poor performance, and even system crashes. Although all operating systems are vulnerable to versioning troubles, Windows seems to be particularly prone to problems in this area.</p>
<p>Under certain circumstances, DLL hell can become magnified to an excruciating level. We found ourselves in position over the last several months while working on a large development project. This project involves geographically scattered teams of programmers, distributed object technology, and dozens of DLLs and executables.  With interfaces and capabilities changing on a daily basis, we found that a good system of version management was crucial to our continued progress. When the system breaks down, mass confusion can idle dozens of highly paid programmers and Q/A personnel. This is not a good thing.</p>
<h4>Where we need it</h4>
<p>To get this problem under control, we first identified four critical places where we need to know the version of an executable or DLL.</p>
<h4>1: When looking directly at a file</h4>
<p>Working with developers when a project is changing rapidly can be very frustrating for Q/A people. It seems that no matter what sort of problem they report, the immediate response from development goes something like “You need to get the latest version, that bug has been fixed.”</p>
<p>Because of this sort of response, it is vital that end users be able to easily determine what version of a DLL or executable is installed on their system. To make this as easy as possible, Microsoft created a standardized method for setting product versions under Windows. One of the standard resource types that can be bound to a project is a Version resource. Our project is built using Visual C++, which stores the version resource in an RC file. Figure 1 shows a typical view of this version information from the IDE.</p>
<p><center><br />
<img src="http://marknelson.us/attachments/2000/version-control/Figure1.gif"><br />
Figure 1<br />
Version information in a Visual Studio project<br />
</center></p>
<p>Note that the resource shown in Figure 1 appears to have duplicates of the version information. The Key values named <span class="inline_code">FILEVERSION </span>and <span class="inline_code">PRODUCTVERSION </span>in the upper half of the display are in the fixed-info section of the resource. These two values are stored as <span class="inline_code">DWORDs </span>in the EXE or DLL file, and as such are useful for using in numerical tests of version properties. The values labeled <span class="inline_code">FileVersion </span>and <span class="inline_code">ProductVersion </span>are string parameters, and are useful for displaying to end users or printing in trace files. Keeping numbers in two places certainly makes us more vulnerable to mistakes, but sometimes we have to make compromises to do things the Microsoft way!</p>
<p>Once the version information is bound into the executable or DLL, an end user can view it by simply asking for the properties of the file from an Explorer view. Figure 2 shows the version information that Windows displays from this view. (Note that the O/S shows the string values, not the fixed-info numeric values.)</p>
<p><center><br />
<img src="http://marknelson.us/attachments/2000/version-control/Figure2.gif"><br />
Figure 2<br />
The Win32 file properties dialog<br />
</center></p>
<h4>2: When reading trace files</h4>
<p>One very common technique used to capture debugging information is the use of a trace or log file. This is usually a simple ASCII text file that can be easily viewed or printed out. Q/A testers know that if they can attach a trace file to a bug report the odds of a fix improve greatly. Unfortunately, developers will always want to know what version of the program was used to create the trace file.</p>
<p>A proactive way to deal with this question is to always print the component version number as one of the first lines in a trace file. That can be done with a line as simple as this:</p>
<div class="igBar"><span id="lcode-1"><a href="#" onclick="javascript:showPlainTxt('code-1'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-1">
<div class="code">
<ol>
<li class="li1">
<div class="de1">Log &lt;&lt;<span class="st0">"FOO.EXE version 1.2<span class="es0">\n</span>"</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<h4>3: Checking versions at run time</h4>
<p>A standard part of any Windows program is the generic About Box. Good programmers always take care to include version information in the About Box. Figure 3 shows a sample of this dialog from a typical Windows application.</p>
<p><center><br />
<img src="http://marknelson.us/attachments/2000/version-control/Figure3.gif"><br />
Figure 3<br />
The About Box from Microsoft Outlook Express<br />
</center></p>
<p>The About Box is just a simple Windows Dialog, which is usually defined in the RC file along with other resource information. The simplest (and probably most common) way to put the version information in the dialog is to create a static text resource that contains the ASCII text verbatim.</p>
<h4>4: Checking out modules from source code control</h4>
<p>Source code control is a key component of modern team-based development. Every source code control system in use today allows programming teams to label a package of files with a version number. That package can then be retrieved by name at any time in the future, which gives developers an easy way to follow the life history of bugs. We frequently find that Q/A is testing a product release that is a few versions behind what development is presently testing.</p>
<p>We use Visual Source Safe for our source code control system. Most of our development staff uses the GUI based front end for this program. When we want to identify a particular version of our package, we right click on a project, and then select the Label menu item. This brings up a dialog box as shown in Figure 4. Typing in the version number causes Visual Source Safe to create a checkpoint for every file in that project. At any time in the future we can ask VSS for copies of all the files for that particular version. (This can include executable and DLL versions as well.) </p>
<p><center><br />
<img src="http://marknelson.us/attachments/2000/version-control/Figure4.gif"><br />
Figure 4<br />
Labeling a project in Visual Source Safe<br />
</center></p>
<h4>What’s wrong with this picture?</h4>
<p>At this point it might seem that we’ve got our version control problem pretty well under control. But experienced programmers should see right away that we’ve got a real problem. We’ve got one piece of data, the version number, and it has to be stored in four different places. This situation should set off alarms any time you see it, because we’ve set up a system that only works if we have perfect adherence to a multi-step procedure. Updating version numbers means editing an RC file in at least two places, locating and editing trace file function calls, and correctly determining the projects to label in the source code control system.</p>
<p>A typical situation we run into at work might have a team of ten people working on the release of fifteen or twenty components. To make sure that we update all version information correctly might involve as many as fifty separate procedures. What are the chances that someone might forget to update the version number in a single About Box, or incorrectly label the VSS project in question? A single mistake such as this can cause immense confusion the next time a bug is reported for a incorrectly identified component.</p>
<p>While it would be possible to create a written procedure list and require people to verify each and every step, it’s infinitely better to set up a system that allows for one-step version setting system. By updating all version information in one step, we are no longer vulnerable to human frailty. If the process is set up properly one time, it should work correctly every time it is used in the future.</p>
<h4>The Perl Solution</h4>
<p>Physicists have been battling for years to unify the four fundamental forces of nature: gravity, electromagnetism, the weak force, and the strong force. While it may have been hubris on our part, we were determined to find a unified way to set the versions in the four different areas of our development process.</p>
<p>The key to the solution was finding a programmatic way to update the version numbers used everywhere in the program. The only thing we needed to do in order to make this happen was to modify the version resource in each component’s RC file. This meant doing a bit of simple parsing and text modification. And without a doubt, the tool most suitable to this task has to be Perl.</p>
<p>Using Perl, it was a quick matter to write a script that we now use to increment either the major or minor version of an entire batch of components. The resulting script, <em>IncVersion.pl</em>, is shown in Listing 1.</p>
<p><em>IncVersion.pl</em> is invoked with an initial argument of major or minor, followed by a list of projects. It then works its way through each of the projects, modifying the RC file for each project. There are two lines in each RC file that need to be modified. The first looks something like this:</p>
<div class="igBar"><span id="lcode-2"><a href="#" onclick="javascript:showPlainTxt('code-2'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-2">
<div class="code">
<ol>
<li class="li1">
<div class="de1">FILEVERSION&nbsp; &nbsp; &nbsp; &nbsp;<span class="nu0">5</span>,<span class="nu0">0</span>,<span class="nu0">1</span>,<span class="nu0">0</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>And the second looks like this:</p>
<div class="igBar"><span id="lcode-3"><a href="#" onclick="javascript:showPlainTxt('code-3'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-3">
<div class="code">
<ol>
<li class="li1">
<div class="de1">VALUE <span class="st0">"FileVersion"</span>,&nbsp; &nbsp; &nbsp;<span class="st0">"5.1<span class="es0">\0</span>"</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The Perl script locates this line in each RC file, and updates the version number in one of two ways. If the initial argument is minor, the last digit in the version is incremented. For example, the version in the lines shown above will change from 5.1 to 5.2. If the initial argument is major, the first digit in the version is incremented. The version above would change from 5.1 to 6.0. (Note that this simple example uses version numbers with just two components.) The <span class="inline_code">FILEVERSION </span>string in the two examples would change to either 5,0,2,0 or 6,0,0,0.</p>
<h4>Some programming details</h4>
<p>The Perl script <em>IncVersion.pl</em> provides an automated way to change the version resource for a given DLL or EXE. By executing it with the correct list of projects, it's possible to automatically update all the components of a big project in an automated way. This is clearly going to cut down on procedural and typing mistakes. But it is still a long way from a unified version system. This only affects the first place where we need version information, which is in the Windows property view. The remaining three cases don't get any help from this at all.</p>
<p>As it turns out, two of the remaining cases are fixed with just a bit of code. In the strategy we were using previously, the version numbers sent to the trace file and shown in the About Box were both hard-coded. A better strategy is to extract the version information from the RC file. Listing 2 shows a C++ routine that can be used to get the version number from the RC file for a given module. We provide routines to read the version information from either the fixed-info or string version resources. (In practice you can arbitrarily choose one or the other.) Now my logging output should look something like this:</p>
<div class="igBar"><span id="lcode-4"><a href="#" onclick="javascript:showPlainTxt('code-4'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-4">
<div class="code">
<ol>
<li class="li1">
<div class="de1">Log &lt;&lt;<span class="st0">"FOO.EXE version "</span> &lt;&lt;StringModuleVersion<span class="br0">&#40;</span><span class="br0">&#41;</span> &lt;&lt;<span class="st0">"<span class="es0">\n</span>"</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Likewise, the About Box code can be generated dynamically as well. If your About Box is a standard Windows Dialog, you only have to override the <span class="inline_code">WM_INITDIALOG</span> message and insert the appropriate text into a static text control. In an MFC app, the code might look something like this:</p>
<div class="igBar"><span id="lcpp-5"><a href="#" onclick="javascript:showPlainTxt('cpp-5'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C++:</span>
<div id="cpp-5">
<div class="cpp">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">BOOL</span> CAboutDlg::<span class="me2">OnInitDialog</span><span class="br0">&#40;</span><span class="br0">&#41;</span> </div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; stringstream s;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; s &lt;&lt;<span class="st0">"GuiFoo.exe version "</span> &lt;&lt;ModuleVersion<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; SetDlgItemText<span class="br0">&#40;</span> IDC_VERSION_BOX, s.<span class="me1">str</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">c_str</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; CDialog::<span class="me2">OnInitDialog</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;i</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">TRUE</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<h4>BAT file considered helpful</h4>
<p>By using these minor modifications, we now have automatic version number control in three of the four designated places. Unfortunately, the fourth target of our version control system is a little more difficult to deal with. Remember that each new version of our project needs to have a label associated with it under our version control system. It would be nice if Visual Source Safe could just read the contents of the version resource in each project's RC file, but at this time it doesn't know how to do that. Accordingly, we have to manually label each new version of our project after it has been checked in.</p>
<p>Although we usually use Visual Source Safe's GUI interface, it can also be invoked from the command line. We make use of this in our versioning system by having <em>IncVersion.pl</em> generate a BAT file that will apply the appropriate label to the currently selected project in Visual Source Safe. A typical <em>LABEL.BAT</em> file will look like this:</p>
<div class="igBar"><span id="lcode-6"><a href="#" onclick="javascript:showPlainTxt('code-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-6">
<div class="code">
<ol>
<li class="li1">
<div class="de1">ss label -C -L<span class="st0">"PROJECT 2.1"</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The Perl script can be modified to generate the project label you want, the important thing is that the version number in the label is identical to that placed in the RC files.</p>
<p>Given the existence of <em>LABEL.BAT</em>, tying all the pieces of the puzzle together is done via one master BAT file. Ours is called <em>UPDATE.BAT</em>, and it looks something like this:</p>
<div class="igBar"><span id="lcode-7"><a href="#" onclick="javascript:showPlainTxt('code-7'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-7">
<div class="code">
<ol>
<li class="li1">
<div class="de1">call checkout.<span class="me1">bat</span></div>
</li>
<li class="li2">
<div class="de2">IncVersion.<span class="me1">pl</span> minor FOO_A FOO_B FOO_C FOO_D </div>
</li>
<li class="li1">
<div class="de1">all makeall.<span class="me1">bat</span></div>
</li>
<li class="li2">
<div class="de2">call checkin.<span class="me1">bat</span></div>
</li>
<li class="li1">
<div class="de1">ss CP $/Projects/FOO</div>
</li>
<li class="li2">
<div class="de2">call label.<span class="me1">bat</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The BAT files called to check out the projects, build the components, then check them back in are all very specific to our projects, and will need to be tailored to each projects needs. <em>CHECKIN.BAT</em> and <em>CHECKOUT.BAT</em> just make calls to the command line interface of Visual Source Safe. <em>MAKEALL.BAT</em> invokes the command line <em>NMAKE</em> tool supplied with Visual Source Safe.</p>
<h4>Conclusion</h4>
<p>Managing version information in a large project doesn't have a nice tidy management solution, at least not with our Win32 development tools. However, by making a few modifications to our source code, and resorting to some old-fashioned command line tools, we have developed a system that does a great job of protecting us from minor version snafus. It does this by doing all version updates in one fell swoop, which makes sure that the process occurs across all components of the system at once. It isn't perfect, and may not even be ideal, but it's working for us. </p>
<h4>Listings</h4>
<p>Listing 1<br />
<em>IncVersion.pl</em>:</p>
<div class="igBar"><span id="lperl-8"><a href="#" onclick="javascript:showPlainTxt('perl-8'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PERL:</span>
<div id="perl-8">
<div class="perl">
<ol>
<li class="li1">
<div class="de1"><span class="co1">#####################################################################################</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1"># This program will change the FileVersion and FILEVERSION accordingly and set them</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1"># consistently across all the directories.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">#</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1"># To use this program, run as</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IncVersion.pl major project-1 project-2 ...</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">#&nbsp; or</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IncVersion.pl minor project-1 project-2 ...</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">#</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1"># The version info will be used to generate label.bat that can be call to label files</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">#&nbsp; &nbsp; &nbsp; &nbsp;in SourceSafe.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">#####################################################################################</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="re0">$maxMajor</span> = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="re0">$maxMinor</span> = <span class="nu0">0</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="re0">$count</span> = <span class="nu0">1</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co1"># find the max of major and minor version number</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="re0">$count</span> &lt;= $<span class="co1">#ARGV) {</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$file1</span> = <span class="re0">$ARGV</span><span class="br0">&#91;</span><span class="re0">$count</span><span class="br0">&#93;</span>.<span class="st0">"<span class="es0">\\</span>"</span>.<span class="re0">$ARGV</span><span class="br0">&#91;</span><span class="re0">$count</span><span class="br0">&#93;</span>.<span class="st0">".rc"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/eval.html"><span class="kw3">eval</span></a> <span class="br0">&#123;</span> SetMax<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> $@;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$count</span>++;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$ARGV</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> eq <span class="st0">"major"</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$maxMajor</span>++;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$maxMinor</span> = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$maxMinor</span>++;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1"># write a batch file to be called later to set labels in SourceSafe</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="re0">$labelFile</span> = <span class="st0">"label.bat"</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/open.html"><span class="kw3">open</span></a><span class="br0">&#40;</span>OutLabel, <span class="st0">"&gt;$labelFile"</span><span class="br0">&#41;</span> || <a href="http://www.perldoc.com/perl5.6/pod/func/die.html"><span class="kw3">die</span></a> <span class="st0">"Failed to open $labelFile to write<span class="es0">\n</span><span class="es0">\t</span>$!<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> OutLabel <span class="st0">"ss label -C- -L<span class="es0">\"</span>PROJECT $maxMajor<span class="es0">\.</span>$maxMinor<span class="es0">\"</span><span class="es0">\n</span>"</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/close.html"><span class="kw3">close</span></a><span class="br0">&#40;</span>OutLabel<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="re0">$count</span> = <span class="nu0">1</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="re0">$count</span> &lt;= $<span class="co1">#ARGV) {</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$file1</span> = <span class="re0">$ARGV</span><span class="br0">&#91;</span><span class="re0">$count</span><span class="br0">&#93;</span>.<span class="st0">"<span class="es0">\\</span>"</span>.<span class="re0">$ARGV</span><span class="br0">&#91;</span><span class="re0">$count</span><span class="br0">&#93;</span>.<span class="st0">".rc"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$file2</span> = <span class="re0">$ARGV</span><span class="br0">&#91;</span><span class="re0">$count</span><span class="br0">&#93;</span>.<span class="st0">"<span class="es0">\\</span>"</span>.<span class="re0">$ARGV</span><span class="br0">&#91;</span><span class="re0">$count</span><span class="br0">&#93;</span>.<span class="st0">".tmp"</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/eval.html"><span class="kw3">eval</span></a> <span class="br0">&#123;</span> ProcessFile<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>$@<span class="br0">&#41;</span> <span class="br0">&#123;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> $@;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/eval.html"><span class="kw3">eval</span></a> <span class="br0">&#123;</span> CopyFile<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> $@;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$count</span>++;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw2">sub</span> SetMax <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> <span class="st0">"Find the max in $file1<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/open.html"><span class="kw3">open</span></a><span class="br0">&#40;</span>InRC, <span class="st0">"$file1"</span><span class="br0">&#41;</span> || <a href="http://www.perldoc.com/perl5.6/pod/func/die.html"><span class="kw3">die</span></a> <span class="st0">"Failed to open $file1 to read<span class="es0">\n</span><span class="es0">\t</span>$!<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="re0">$_</span> = <span class="re4">&lt;InRC&gt;</span><span class="br0">&#41;</span>&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$_</span> =~/FILEVERSION/<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re0">@currentLine</span> = <a href="http://www.perldoc.com/perl5.6/pod/func/split.html"><span class="kw3">split</span></a><span class="br0">&#40;</span><span class="st0">' '</span>, <span class="re0">$_</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="re0">@oldVersion</span>&nbsp; = <a href="http://www.perldoc.com/perl5.6/pod/func/split.html"><span class="kw3">split</span></a><span class="br0">&#40;</span><span class="st0">','</span>, <span class="re0">$currentLine</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$oldVersion</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>&gt; <span class="re0">$maxMajor</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$maxMajor</span> = <span class="re0">$oldVersion</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$oldVersion</span><span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span>&gt; <span class="re0">$maxMinor</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$maxMinor</span> = <span class="re0">$oldVersion</span><span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">elsif</span> <span class="br0">&#40;</span><span class="re0">$_</span>&nbsp; =~/FileVersion/<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="re0">@currentLine</span> = <a href="http://www.perldoc.com/perl5.6/pod/func/split.html"><span class="kw3">split</span></a><span class="br0">&#40;</span><span class="st0">' '</span>, <span class="re0">$_</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re0">@item</span>&nbsp; &nbsp; &nbsp; &nbsp; = <a href="http://www.perldoc.com/perl5.6/pod/func/split.html"><span class="kw3">split</span></a><span class="br0">&#40;</span><span class="st0">'&quot;'</span>, <span class="re0">@currentLine</span><span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="re0">@vItem</span>&nbsp; &nbsp; &nbsp; &nbsp;= <a href="http://www.perldoc.com/perl5.6/pod/func/split.html"><span class="kw3">split</span></a><span class="br0">&#40;</span>/\\/, <span class="re0">@item</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re0">@version</span>&nbsp; &nbsp; &nbsp;= <a href="http://www.perldoc.com/perl5.6/pod/func/split.html"><span class="kw3">split</span></a><span class="br0">&#40;</span><span class="st0">'<span class="es0">\.</span>'</span>, <span class="re0">$vItem</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$version</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>&gt; <span class="re0">$maxMajor</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$maxMajor</span> = <span class="re0">$version</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$version</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>&gt; <span class="re0">$maxMinor</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$maxMinor</span> = <span class="re0">$version</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/close.html"><span class="kw3">close</span></a> <span class="br0">&#40;</span>InRC<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">sub</span> ProcessFile <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> <span class="st0">"Converting $file1 to $file2<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/open.html"><span class="kw3">open</span></a><span class="br0">&#40;</span>InRC, <span class="st0">"$file1"</span><span class="br0">&#41;</span> || <a href="http://www.perldoc.com/perl5.6/pod/func/die.html"><span class="kw3">die</span></a> <span class="st0">"Failed to open $file1 to read<span class="es0">\n</span><span class="es0">\t</span>$!<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/open.html"><span class="kw3">open</span></a><span class="br0">&#40;</span>OutRC, <span class="st0">"&gt;$file2"</span><span class="br0">&#41;</span> || <a href="http://www.perldoc.com/perl5.6/pod/func/die.html"><span class="kw3">die</span></a> <span class="st0">"Failed to open $file2 to write<span class="es0">\n</span><span class="es0">\t</span>$!<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="re0">$_</span> = <span class="re4">&lt;InRC&gt;</span><span class="br0">&#41;</span>&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$_</span> =~/FILEVERSION/<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> OutRC <span class="st0">" FILEVERSION $maxMajor,0,$maxMinor,0<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">elsif</span> <span class="br0">&#40;</span><span class="re0">$_</span>&nbsp; =~/FileVersion/<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> OutRC <span class="st0">"<span class="es0">\t</span>&nbsp; &nbsp; VALUE <span class="es0">\"</span>FileVersion<span class="es0">\"</span>, <span class="es0">\"</span>$maxMajor.$maxMinor<span class="es0">\\</span>0<span class="es0">\"</span><span class="es0">\n</span>"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> OutRC <span class="st0">"$_"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/close.html"><span class="kw3">close</span></a> <span class="br0">&#40;</span>InRC<span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/close.html"><span class="kw3">close</span></a> <span class="br0">&#40;</span>outRC<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">sub</span> CopyFile <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> <span class="st0">"Copying $file2 to $file1<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/unlink.html"><span class="kw3">unlink</span></a><span class="br0">&#40;</span><span class="re0">$file1</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/open.html"><span class="kw3">open</span></a><span class="br0">&#40;</span>InRC, <span class="st0">"$file2"</span><span class="br0">&#41;</span> || <a href="http://www.perldoc.com/perl5.6/pod/func/die.html"><span class="kw3">die</span></a> <span class="st0">"Failed to open $file2 to read<span class="es0">\n</span><span class="es0">\t</span>$!<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/open.html"><span class="kw3">open</span></a><span class="br0">&#40;</span>OutRC, <span class="st0">"&gt;$file1"</span><span class="br0">&#41;</span> || <a href="http://www.perldoc.com/perl5.6/pod/func/die.html"><span class="kw3">die</span></a> <span class="st0">"Failed to open $file1 to write<span class="es0">\n</span><span class="es0">\t</span>$!<span class="es0">\n</span>"</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="re0">$_</span> = <span class="re4">&lt;InRC&gt;</span><span class="br0">&#41;</span>&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/print.html"><span class="kw3">print</span></a> OutRC <span class="st0">"$_"</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/close.html"><span class="kw3">close</span></a> <span class="br0">&#40;</span>InRC<span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <a href="http://www.perldoc.com/perl5.6/pod/func/close.html"><span class="kw3">close</span></a> <span class="br0">&#40;</span>outRC<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Listing 2<br />
Getting VersionInfo in C++:</p>
<div class="igBar"><span id="lcpp-9"><a href="#" onclick="javascript:showPlainTxt('cpp-9'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C++:</span>
<div id="cpp-9">
<div class="cpp">
<ol>
<li class="li1">
<div class="de1"><span class="co2">#include &lt;string&gt;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co2">#include &lt;vector&gt;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">using</span> <span class="kw2">namespace</span> std;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// This routine will extract the fixed-info version</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// information from the version resource in the RC</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// file for the current module. The four integers</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// that make up the fixed-info version information are</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// formatted into a string and returned to the caller.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//</span></div>
</li>
<li class="li2">
<div class="de2">string FixedModuleVersion<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw4">char</span> file_name<span class="br0">&#91;</span> MAX_PATH <span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; GetModuleFileName<span class="br0">&#40;</span> ::<span class="me2">GetModuleHandle</span><span class="br0">&#40;</span> <span class="kw2">NULL</span> <span class="br0">&#41;</span>, file_name, MAX_PATH <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; DWORD dwDummyHandle; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; DWORD len = GetFileVersionInfoSize<span class="br0">&#40;</span> file_name, &amp;dwDummyHandle <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; vector&lt;BYTE&gt; buf<span class="br0">&#40;</span> len <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ::<span class="me2">GetFileVersionInfo</span><span class="br0">&#40;</span> file_name, <span class="nu0">0</span>, len, buf.<span class="me1">begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> ver_length;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; LPVOID lpvi;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; ::<span class="me2">VerQueryValue</span><span class="br0">&#40;</span> buf.<span class="me1">begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">"<span class="es0">\\</span>"</span>, </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;lpvi,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;ver_length <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; VS_FIXEDFILEINFO fileInfo;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; fileInfo = *<span class="br0">&#40;</span>VS_FIXEDFILEINFO*<span class="br0">&#41;</span>lpvi;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; stringstream s;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; s &lt;&lt;HIWORD<span class="br0">&#40;</span>fileInfo.<span class="me1">dwFileVersionMS</span><span class="br0">&#41;</span> &lt;&lt;<span class="st0">"."</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &lt;&lt;LOWORD<span class="br0">&#40;</span>fileInfo.<span class="me1">dwFileVersionMS</span><span class="br0">&#41;</span> &lt;&lt;<span class="st0">"."</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &lt;&lt;HIWORD<span class="br0">&#40;</span>fileInfo.<span class="me1">dwFileVersionLS</span><span class="br0">&#41;</span> &lt;&lt;<span class="st0">"."</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &lt;&lt;LOWORD<span class="br0">&#40;</span>fileInfo.<span class="me1">dwFileVersionLS</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> s.<span class="me1">str</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co1">//</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// This routine will extract the version string from the</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// string version resource in the RC file for the current module.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// Note that you must add version.lib to your project to</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// link to the Win32 versioning API calls. The actual call</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// VerQueryValue() uses a value of 040904B0 for the language</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// and character set. This value is equivalent to English</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// language text encoded using Unicode.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">//</span></div>
</li>
<li class="li1">
<div class="de1">string StringModuleVersion<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">char</span> file_name<span class="br0">&#91;</span> MAX_PATH <span class="br0">&#93;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; GetModuleFileName<span class="br0">&#40;</span> ::<span class="me2">GetModuleHandle</span><span class="br0">&#40;</span> <span class="kw2">NULL</span> <span class="br0">&#41;</span>, file_name, MAX_PATH <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; DWORD dwDummyHandle; </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; DWORD len = GetFileVersionInfoSize<span class="br0">&#40;</span> file_name, &amp;dwDummyHandle <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; vector&lt;BYTE&gt; buf<span class="br0">&#40;</span> len <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; ::<span class="me2">GetFileVersionInfo</span><span class="br0">&#40;</span> file_name, <span class="nu0">0</span>, len, buf.<span class="me1">begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">char</span> *version;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw4">unsigned</span> <span class="kw4">int</span> ver_length;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; ::<span class="me2">VerQueryValue</span><span class="br0">&#40;</span> buf.<span class="me1">begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">"<span class="es0">\\</span>StringFileInfo<span class="es0">\\</span>040904B0<span class="es0">\\</span>FileVersion"</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="kw4">void</span> **<span class="br0">&#41;</span> &amp;version,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&amp;ver_length <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">return</span> string<span class="br0">&#40;</span> version, ver_length <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<h4>Recommended Reading</h4>
<p>If you are interested in version control, the material below might be helpful. If you make a purchase after clicking through one of the links below, you'll be expanding your knowledge and supporting this site at the same time. Thanks. (Note: all links will open in a new window.)<br />
<center></p>
<table border="0">
<tr>
<td><iframe src="http://rcm.amazon.com/e/cm?t=theinternetdatac&#038;o=1&#038;p=8&#038;l=as1&#038;asins=0977616657&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;lc1=0000FF&#038;bc1=000000&#038;bg1=FFFFFF&#038;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</td>
<td>
<iframe src="http://rcm.amazon.com/e/cm?t=theinternetdatac&#038;o=1&#038;p=8&#038;l=as1&#038;asins=B000BT8TR6&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;lc1=0000FF&#038;bc1=000000&#038;bg1=FFFFFF&#038;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</td>
<td>
<iframe src="http://rcm.amazon.com/e/cm?t=theinternetdatac&#038;o=1&#038;p=8&#038;l=as1&#038;asins=0596004486&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;lc1=0000FF&#038;bc1=000000&#038;bg1=FFFFFF&#038;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</td>
<td>
<iframe src="http://rcm.amazon.com/e/cm?t=theinternetdatac&#038;o=1&#038;p=8&#038;l=as1&#038;asins=0596527039&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;lc1=0000FF&#038;bc1=000000&#038;bg1=FFFFFF&#038;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
</td>
</tr>
</table>
<p></center></p>
]]></content:encoded>
			<wfw:commentRss>http://marknelson.us/2000/06/01/version-control/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
