Licensing automated builds with NAnt
Published 01 March 2013
Microsoft Visual Studio can licence SQL Comparison SDK assemblies automatically. This can also be done without the need to have Visual Studio installed, for instance on a server that automates software builds using the NAnt automated build tool.
Before you start, ensure that any prerequisites are installed. In addition to the .NET Framework, the .NET Framework Software Development Kit (SDK) must also be installed to provide licensing functionality. This is a free download from Microsoft. Finally, install SQL Comparison SDK, which will provide the .NET assemblies necessary to create a licence available to the build server.
First, a licence needs to be created on the server. Because a form is presented requesting the SQL Comparison SDK serial number, this needs to be done manually, before any builds are configured.
- Open a command prompt and browse to the SDK folder (cd C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin)
- Notepad licence.txt
- Enter these contents into licence.txt:
RedGate.SQLCompare.Engine.Database, RedGate.SQLCompare.Engine<return>
If you were also referencing Data Compare's engine, you would mention it on the next line.
- Save the file and exit.
- Run the licence compiler:
lc.exe /target:"MyApp.exe" /complist:"licence.txt" /i:"c:\program files (x86)\Red Gate\SQL Comparison SDK 10\Assemblies\SQL Compare\RedGate.SQLCompare.Engine.dll"
At this point, you can enter your SQL Comparison SDK serial number from your Red Gate invoice, and a SQL_Toolkit_v_x.lic file will be created in the profile for all users of the computer. Once this file is present, you should never need to enter the serial number again, and automated builds of any SQL Toolkit project can be licensed automatically by NAnt.
The next step is to configure your build. Following the instructions in the SQL Comparison SDK documentation, create a licenses.licx file in your SQL Toolkit project and check it into your source control system. When your source control provider checks out the source code again, this file will be present in your build folder so that the NAnt licensing task can process it.
Now add a license task to your NAnt build script, specifying the location to licenses.licx in your build folder and the location of the Red Gate assembly references required:
<target name="licence"> <license input="${build.dir}MyProject\licenses.licx" target="MyProject.exe" output="${build.dir}MyProject\obj\MyProject.exe.licenses"> <assemblies> <include name="${DataCompare.path}RedGate.SQLCompare.Engine.dll" /> <include name="${DataCompare.path}RedGate.SQLDataCompare.Engine.dll" /> </assemblies> </license> </target>
This action will create a file called MyProject.exe.licenses in the obj subfolder of your build folder. The final step is to link the .licenses file into the resources of your output assembly, however, you cannot include the .licenses file in the references section of the <vbc> or <csc> task, because this resource is already compiled and the <resources> section is meant for resources that have not yet been compiled using resgen.exe.
For this reason, an <arg> section is needed inside your <csc> or <vbc> task in order to force the compiler into including the .licences resource in the compiled assembly:
<arg line="/res:${build.dir}\MyProject\obj\MyProject.exe.licenses" />
Here is an example NAnt build script for a Visual Basic project build with the necessary Toolkit licensing in place.
<?xml version="1.0"?> <project name="Toolkit Licensing Nunit Test" default="build"> <property name="build.dir" value="c:\NantBuilds\MyProject\" /> <property name="DataCompare.path" value="c:\program files\red gate\sql data compare 6\" /> <target name="licence"> <license input="${build.dir}MyProject\licenses.licx" target="MyProject.exe" output="${build.dir}MyProject\obj\MyProject.exe.licenses"> <assemblies> <include name="${DataCompare.path}RedGate.SQLCompare.Engine.dll" /> <include name="${DataCompare.path}RedGate.SQLDataCompare.Engine.dll" /> </assemblies> </license> </target> <target name="build"> <vbc target="winexe" output="${build.dir}MyProject\bin\Debug\MyProject.exe" debug="true" main="MyProject.Form1" optioncompare="text" optionexplicit="true" optionstrict="true" rootnamespace="MyProject" removeintchecks="true" verbose="true"> <sources> <include name="${build.dir}MyProject\*.vb" /> </sources> <arg line="/res:${build.dir}\MyProject\obj\MyProject.exe.licenses" /> <resources dynamicprefix="false" basedir="${build.dir}MyProject\obj" prefix="MyProject"> <include name="${build.dir}MyProject\*.resx"/> </resources> <imports> <import namespace="RedGate.SQLCompare.Engine" /> <import namespace="RedGate.SQL.Shared" /> <import namespace="RedGate.SQLDataCompare.Engine" /> <import namespace="System.Threading" /> <import namespace="System.Windows.Forms" /> <import namespace="Microsoft.VisualBasic" /> <import namespace="System.Collections" /> <import namespace="System.Diagnostics" /> <import namespace="System.Drawing" /> </imports> <references> <include name="${DataCompare.path}RedGate.SQLCompare.Engine.dll" /> <include name="${DataCompare.path}RedGate.SQLDataCompare.Engine.dll" /> <include name="${DataCompare.path}RedGate.SQL.Shared.dll" /> <include name="Microsoft.VisualBasic.dll" /> <include name="System.dll" /> <include name="System.Data.dll" /> <include name="System.Deployment.dll" /> <include name="System.Drawing.dll" /> <include name="System.Windows.Forms.dll" /> <include name="System.Xml.dll" /> </references> </vbc> </target> </project>