This page is home to my Garage Sale Code, bits and pieces that I wrote over the years that are generally no longer relevant or interesting to me. They're here as a piece of my software history, and for those that are looking for bits they may have used in the past.
The .NET Framework provides an exceptionally useful feature in the System.Xml.Serialization namespace - the XmlSerializer. This class takes classes that you have developed and turns them into an XML representation. It can then turn an XML representation of your class back into a class instance. Very useful.
When you first try to serialize a type the XmlSerializer creates some C# code which reads and writes values to and from the type. It then compiles this code into an in-memory assembly. Unfortunately, sometimes this doesn't work and you either get a bunch of exceptions telling you why or a cryptic "can't load xyzxyzab.dll" exception. Both of these error types are caused by your type being incompatible with XmlSerializer. The second type of error, though, doesn't tell you why it's incompatible.
How can XmlSerializer Workshop help?
This tool allows you to load an assembly and safely try to create an XmlSerializer for any type in that assembly. If an XmlSerializer cannot be created the software shows you why - including allowing you to view the source code created by the serializer.
XSW is released under a BSD-style open-source license - hopefully it will help others. The source shows a couple of interesting techniques including using a separate AppDomain to host the main application so that the application can delete temporary assemblies after running. If you have improvements please do send them back so that I can merge them in and release them for others to use.
This tool was heavily inspired by Chris Sells' XmlSerializerPrecompiler tool which helped me immensely when I was having difficulties with XmlSerializer. Thanks Chris!
I have been doing a lot of development work in Visual C++ recently and have frequently been frustrated by the number of files that it leaves lying around - especially when I want to zip up some source and e-mail it!
DirCleaner is a tool I wrote in Visual C++ to help with this problem, it scans from a given directory and lists all files with certain extensions. The user then has the option to delete the files which have been found.
DirCleaner is free for anybody to download, develop and re-distribute. The only thing I ask is that the about box remains intact with my name on it, and that a link remains to this page.
Some tasks for NAnt that I have found useful at various points:
Download: untidytasks.zip (28k, source and binaries).
This task calls the Inno Setup compiler with a setup script. The task uses the registry to attempt to find where the compiler is installed - if this path cannot be found then iscc.exe needs to be in the path. The task can also search specifically for the ISX (Inno Setup eXtensions) compiler executable.
<iscompiler filename="installer.iss" />
This task allows you to perform common MKS SI operations such as creating a sandbox, updating a sandbox, and tagging files (or rather it will do, only sandbox is implemented currently). e.g.
<mkssi project="\\mks\sources\project1\project.pj" dir="c:\sandbox" />
- Create a sandbox in "c:\sandbox" for the project "\\mks\sourc...".
This is a set of tasks from reading and writing version numbers with a variety of file types. You can read/write from a resource file's (.rc) VERSIONINFO block, a simple file with a version number in it, and any type of file using a regular expression.
One part of these tasks is the VersionNumber type. This type can either define a version number or read one from a source file. Any of the output file types can be used as input file types. When doing this, you can change all parts of the version number either by incrementing/decrementing them or setting them to a specific value.
You can write a version number out to several types of file (or use the version number as a string stored in a property). Each file type takes a Version sub-element which can either be a VersionNumber reference or a complete VersionNumber item. Different file types support different extra features. For example, Suffixes can be placed on the end of the version number strings for File or Product entries in VERSIONINFO blocks.
All version numbers are generally represented as major.minor.revision.build, e.g. 22.214.171.1244.
Some examples of using the different tasks:
<versioninfo filename="myproduct.rc"><br /> <version source="VersionInfoFile" file="myproduct.rc" id="vn" build="1" /><br /> </versioninfo>
- increment the build part of a version number read from a .rc file and then write it back to the same file. You can choose whether to update the file or product part of the VERSIONINFO structure or to update both (the default). This is set with the type parameter - set it to File, Product or Both. The task also allows you to set a suffix on either of these version fields using the filesuffix and productsuffix attributes.
<versionnumber source="VersionNumberFile" file="myproduct.version"<br /> major="2" id="theversion" /> <versionnumberfile filename="myproduct.version"> <version refid="theversion" /> </versionnumberfile> <versioninfo filename="myproduct.rc" productsuffix="-internal"> <version refid="theversion" /> </versioninfo>
- load the version number from the file "myproduct.version", increment the major part by 2, and store it in both "myproduct.rc" and "myproduct.version". The version number file contains a single line with the version number surrounded in quotes.
<version source="RegExFile" file="version.h" setversion="126.96.36.199" id="version"<br /> regex='#define version _T\("((?<a>[0-9]+)\.(?<b>[0-9]+)\. ignore line wrap... (?<c>[0-9]+)\.(?<d>[0-9]+))"\)"\)' /> <versionregex filename="version.h" regex='#define version _T\("([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)"\)'><br /> <version refid="version" /> </versionregex>
- read the version number from a file using a regular expression, then set the version to be something completely different (yes, I'm aware this doesn't make sense, but it squeezes examples up!) and finally write the new version back to a file using a different regular expression.
There are two types of regular expression in use here. The first is the one used to find a place in a file to replace with a version number. This can either be a simple expression to match - the entire expression will be replaced - or it can be an expression with a single group in it (groups are surrounded by brackets). The group will be replaced with the version. The example above uses a group.
The second type of regular expression is the one used to read a version number from a file. This is more complicated because it has to find particular parts of the version number. Each part (major, minor, revision, build) is represented by a named group (a, b, c and d respectively). Unfortunately, .NET uses the angle-bracket symbol to name groups and this character is invalid in XML attributes. You therefore need to use the < and > replacements. You can match any form of version number with this regex.
You can also change the format that the version number is written out in by adding a format parameter to the versionregex task. The format string uses a single character to represent each part of the version number 'M' is major, 'm' is minor, 'r' is revision, 'b' is build and 's' is suffix. The suffix is specified in the optional suffix parameter. e.g. format="M.m.r-s (b)" suffix="devel"
This is a simple task to create a .lock file while a build is running. The lock file is removed when the build finishes. e.g.
<lock name="mylock.lock" />