Tuesday, March 26, 2013

Failed Web Service Call Due to Big Time Difference Between Servers

The other day, a working web site was suddenly down. Its registration and login related functionalities were all failed.
The error was caught but the error message was kind of “Unknown”. Dug to the code, the caught exception “e” in below code is a null:
   1:  try
   2:  {                   
   3:      return client.Proxy.IdentityTypeList();
   4:   }
   5:  catch (Exception e)
   6:  {
   7:      this.HandleException(e);
   8:   }

what line 3 does is calling a web service, but it was failed and throwing an null exception. As there was no message text at all, it seemed it was getting into a dead end in for trouble shooting.

It finally turned out it was caused by there was a big time different between the tow machines (the calling web server and the web service server). The difference was more than 5 minutes.

What I have done to find out the cause was I wrote a test program in C#. The test program was a WinForm application. The function of the application was to call the same web service as above code did.

When the application was deployed to the web service, it failed to call the web service and threw an exception. This time the exception did have a error message text complaining that the web service returned in future time and the time in the future was longer than 5 minutes.

What is still mystery to me from the above case is that the same code in Web application and WinForm application throws different exception. The exception threw in Web application does not make sense at all which make it very difficult to do the trouble shooting.

Tuesday, March 12, 2013

XML Data Binding in Delphi 2007 (2)

In my previous blog [XML Data Binding in Delphi 2007 (1)], I have described there were issues when using XML Data Binding facility in Delphi 2007.

We are going to solve name space issue in this blog.

Let’s have a look at the schemas we are going to map.

Book.xsd:

  1: <?xml version="1.0" encoding="utf-8"?>
  2: <xs:schema targetNamespace="http://www.bochenlin.com/book"
  3:     elementFormDefault="qualified"
  4:     xmlns="http://tempuri.org/XMLSchema.xsd"
  5:     xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
  6:     xmlns:xs="http://www.w3.org/2001/XMLSchema"
  7: 	xmlns:a="http://www.bochenlin.com/author"
  8: >
  9: 	<xs:import namespace ="http://www.bochenlin.com/author"
 10: 			   schemaLocation ="author.xsd"></xs:import>
 11: 	<xs:element name="book">
 12: 		<xs:complexType>
 13: 			<xs:sequence>
 14: 				<xs:element name ="title" type="xs:string" ></xs:element>
 15: 				<xs:element name ="subject" type ="xs:string"></xs:element>
 16: 				<xs:element ref ="a:author" ></xs:element>
 17: 			</xs:sequence>
 18: 		</xs:complexType>
 19: 	</xs:element> 		
 20: </xs:schema>
 21: 

Author.xsd:


 



  1: <?xml version="1.0" encoding="utf-8"?>
  2: <xs:schema targetNamespace="http://www.bochenlin.com/author"
  3:     elementFormDefault="qualified"
  4:     xmlns="http://tempuri.org/XMLSchema.xsd"
  5:     xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
  6:     xmlns:xs="http://www.w3.org/2001/XMLSchema"
  7: >
  8: 	<xs:element name ="author">
  9: 		<xs:complexType>
 10: 			<xs:sequence >
 11: 				<xs:element name ="title" type ="xs:string"></xs:element>
 12: 				<xs:element name ="firstName" type ="xs:string"></xs:element>
 13: 				<xs:element name ="lastName" type ="xs:string"></xs:element>
 14: 			</xs:sequence>
 15: 		</xs:complexType>
 16: 	</xs:element>
 17: </xs:schema>
 18: 

 

By using the XML Data Binding Wizard in XE, we can get following code:

  1: unit book;
  2: 
  3: interface
  4: 
  5: uses xmldom, XMLDoc, XMLIntf;
  6: 
  7: type
  8: 
  9: { Forward Decls }
 10: 
 11:   IXMLBook = interface;
 12: 
 13: { IXMLBook }
 14: 
 15:   IXMLBook = interface(IXMLNode)
 16:     ['{C013C828-0F4C-4537-ACD3-B7C550D3B813}']
 17:     { Property Accessors }
 18:     function Get_Title: WideString;
 19:     function Get_Subject: WideString;
 20:     function Get_Author: WideString;
 21:     procedure Set_Title(Value: WideString);
 22:     procedure Set_Subject(Value: WideString);
 23:     procedure Set_Author(Value: WideString);
 24:     { Methods & Properties }
 25:     property Title: WideString read Get_Title write Set_Title;
 26:     property Subject: WideString read Get_Subject write Set_Subject;
 27:     property Author: WideString read Get_Author write Set_Author;
 28:   end;
 29: 
 30: { Forward Decls }
 31: 
 32:   TXMLBook = class;
 33: 
 34: { TXMLBook }
 35: 
 36:   TXMLBook = class(TXMLNode, IXMLBook)
 37:   protected
 38:     { IXMLBook }
 39:     function Get_Title: WideString;
 40:     function Get_Subject: WideString;
 41:     function Get_Author: WideString;
 42:     procedure Set_Title(Value: WideString);
 43:     procedure Set_Subject(Value: WideString);
 44:     procedure Set_Author(Value: WideString);
 45:   end;
 46: 
 47: { Global Functions }
 48: 
 49: function Getbook(Doc: IXMLDocument): IXMLBook;
 50: function Loadbook(const FileName: string): IXMLBook;
 51: function Newbook: IXMLBook;
 52: 
 53: const
 54:   TargetNamespace = 'http://www.bochenlin.com/book';
 55: 
 56: implementation
 57: 
 58: { Global Functions }
 59: 
 60: function Getbook(Doc: IXMLDocument): IXMLBook;
 61: begin
 62:   Result := Doc.GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
 63: end;
 64: 
 65: function Loadbook(const FileName: string): IXMLBook;
 66: begin
 67:   Result := LoadXMLDocument(FileName).GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
 68: end;
 69: 
 70: function Newbook: IXMLBook;
 71: begin
 72:   Result := NewXMLDocument.GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
 73: end;
 74: 
 75: { TXMLBook }
 76: 
 77: function TXMLBook.Get_Title: WideString;
 78: begin
 79:   Result := ChildNodes['title'].Text;
 80: end;
 81: 
 82: procedure TXMLBook.Set_Title(Value: WideString);
 83: begin
 84:   ChildNodes['title'].NodeValue := Value;
 85: end;
 86: 
 87: function TXMLBook.Get_Subject: WideString;
 88: begin
 89:   Result := ChildNodes['subject'].Text;
 90: end;
 91: 
 92: procedure TXMLBook.Set_Subject(Value: WideString);
 93: begin
 94:   ChildNodes['subject'].NodeValue := Value;
 95: end;
 96: 
 97: function TXMLBook.Get_Author: WideString;
 98: begin
 99:   Result := ChildNodes['a:author'].Text;
100: end;
101: 
102: procedure TXMLBook.Set_Author(Value: WideString);
103: begin
104:   ChildNodes['a:author'].NodeValue := Value;
105: end;
106: 
107: end.

In above Delphi code, there are two problems. First it does not generate correct code for element “author”. In line 27, type of property is WideString instead of a class type. Secondly, the generated Delphi code only specify the target name space http://www.bochenlin.com/book , no other name space http://www.bochenlin.com/author  is specified anywhere else, in stead, it uses fixed tag name “a:author” to map the element “author” in the name space http://www.bochenlin.com/author.  Even “author” is a simple type, this is only fine for XML instance which uses “a” as the prefix for name space http://www.bochenlin.com/author. If the final application will only deal with the XML coming from one source, it probably will be OK. It definitely has problem if the XML instances are coming from different sources in which they might have choose different prefixes for the same name space. Besides, the XML instance generated by using above code will be invalid as it will be missing the name space http://www.bochenlin.com/author for the element “author”. To solve these problems, schema “author” needs to have a small tweak.



Tweaked Author.xsd


  1: <?xml version="1.0" encoding="utf-8"?>
  2: <xs:schema targetNamespace="http://www.bochenlin.com/author"
  3:     elementFormDefault="qualified"
  4:     xmlns="http://tempuri.org/XMLSchema.xsd"
  5:     xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
  6:     xmlns:xs="http://www.w3.org/2001/XMLSchema"
  7:     xmlns:a="http://www.bochenlin.com/author"		   
  8: >
  9: 	<xs:element name ="author">
 10: 		<xs:complexType>
 11: 			<xs:sequence >
 12: 				<xs:element name ="title" type ="xs:string"></xs:element>
 13: 				<xs:element name ="firstName" type ="xs:string"></xs:element>
 14: 				<xs:element name ="lastName" type ="xs:string"></xs:element>
 15: 			</xs:sequence>
 16: 		</xs:complexType>
 17: 	</xs:element>
 18: </xs:schema>
 19: 


Line 7 in above tweaked Author.xsd is added for Delphi to generated correct type for element “author”, updated unit book is provided below:

  1: unit book;
  2: 
  3: interface
  4: 
  5: uses xmldom, XMLDoc, XMLIntf;
  6: 
  7: type
  8: 
  9: { Forward Decls }
 10: 
 11:   IXMLBook = interface;
 12:   IXMLAuthor_a = interface;
 13: 
 14: { IXMLBook }
 15: 
 16:   IXMLBook = interface(IXMLNode)
 17:     ['{C873AF71-B66F-4FC1-8273-93F023EFAFBB}']
 18:     { Property Accessors }
 19:     function Get_Title: WideString;
 20:     function Get_Subject: WideString;
 21:     function Get_Author: IXMLAuthor_a;
 22:     procedure Set_Title(Value: WideString);
 23:     procedure Set_Subject(Value: WideString);
 24:     { Methods & Properties }
 25:     property Title: WideString read Get_Title write Set_Title;
 26:     property Subject: WideString read Get_Subject write Set_Subject;
 27:     property Author: IXMLAuthor_a read Get_Author;
 28:   end;
 29: 
 30: { IXMLAuthor_a }
 31: 
 32:   IXMLAuthor_a = interface(IXMLNode)
 33:     ['{23B0F904-2759-4810-9DDA-4E79248128E8}']
 34:     { Property Accessors }
 35:     function Get_Title: WideString;
 36:     function Get_FirstName: WideString;
 37:     function Get_LastName: WideString;
 38:     procedure Set_Title(Value: WideString);
 39:     procedure Set_FirstName(Value: WideString);
 40:     procedure Set_LastName(Value: WideString);
 41:     { Methods & Properties }
 42:     property Title: WideString read Get_Title write Set_Title;
 43:     property FirstName: WideString read Get_FirstName write Set_FirstName;
 44:     property LastName: WideString read Get_LastName write Set_LastName;
 45:   end;
 46: 
 47: { Forward Decls }
 48: 
 49:   TXMLBook = class;
 50:   TXMLAuthor_a = class;
 51: 
 52: { TXMLBook }
 53: 
 54:   TXMLBook = class(TXMLNode, IXMLBook)
 55:   protected
 56:     { IXMLBook }
 57:     function Get_Title: WideString;
 58:     function Get_Subject: WideString;
 59:     function Get_Author: IXMLAuthor_a;
 60:     procedure Set_Title(Value: WideString);
 61:     procedure Set_Subject(Value: WideString);
 62:   public
 63:     procedure AfterConstruction; override;
 64:   end;
 65: 
 66: { TXMLAuthor_a }
 67: 
 68:   TXMLAuthor_a = class(TXMLNode, IXMLAuthor_a)
 69:   protected
 70:     { IXMLAuthor_a }
 71:     function Get_Title: WideString;
 72:     function Get_FirstName: WideString;
 73:     function Get_LastName: WideString;
 74:     procedure Set_Title(Value: WideString);
 75:     procedure Set_FirstName(Value: WideString);
 76:     procedure Set_LastName(Value: WideString);
 77:   end;
 78: 
 79: { Global Functions }
 80: 
 81: function Getbook(Doc: IXMLDocument): IXMLBook;
 82: function Loadbook(const FileName: string): IXMLBook;
 83: function Newbook: IXMLBook;
 84: 
 85: const
 86:   TargetNamespace = 'http://www.bochenlin.com/book';
 87: 
 88: implementation
 89: 
 90: { Global Functions }
 91: 
 92: function Getbook(Doc: IXMLDocument): IXMLBook;
 93: begin
 94:   Result := Doc.GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
 95: end;
 96: 
 97: function Loadbook(const FileName: string): IXMLBook;
 98: begin
 99:   Result := LoadXMLDocument(FileName).GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
100: end;
101: 
102: function Newbook: IXMLBook;
103: begin
104:   Result := NewXMLDocument.GetDocBinding('book', TXMLBook, TargetNamespace) as IXMLBook;
105: end;
106: 
107: { TXMLBook }
108: 
109: procedure TXMLBook.AfterConstruction;
110: begin
111:   RegisterChildNode('author', TXMLAuthor_a);
112:   inherited;
113: end;
114: 
115: function TXMLBook.Get_Title: WideString;
116: begin
117:   Result := ChildNodes['title'].Text;
118: end;
119: 
120: procedure TXMLBook.Set_Title(Value: WideString);
121: begin
122:   ChildNodes['title'].NodeValue := Value;
123: end;
124: 
125: function TXMLBook.Get_Subject: WideString;
126: begin
127:   Result := ChildNodes['subject'].Text;
128: end;
129: 
130: procedure TXMLBook.Set_Subject(Value: WideString);
131: begin
132:   ChildNodes['subject'].NodeValue := Value;
133: end;
134: 
135: function TXMLBook.Get_Author: IXMLAuthor_a;
136: begin
137:   Result := ChildNodes['author'] as IXMLAuthor_a;
138: end;
139: 
140: { TXMLAuthor_a }
141: 
142: function TXMLAuthor_a.Get_Title: WideString;
143: begin
144:   Result := ChildNodes['title'].Text;
145: end;
146: 
147: procedure TXMLAuthor_a.Set_Title(Value: WideString);
148: begin
149:   ChildNodes['title'].NodeValue := Value;
150: end;
151: 
152: function TXMLAuthor_a.Get_FirstName: WideString;
153: begin
154:   Result := ChildNodes['firstName'].Text;
155: end;
156: 
157: procedure TXMLAuthor_a.Set_FirstName(Value: WideString);
158: begin
159:   ChildNodes['firstName'].NodeValue := Value;
160: end;
161: 
162: function TXMLAuthor_a.Get_LastName: WideString;
163: begin
164:   Result := ChildNodes['lastName'].Text;
165: end;
166: 
167: procedure TXMLAuthor_a.Set_LastName(Value: WideString);
168: begin
169:   ChildNodes['lastName'].NodeValue := Value;
170: end;
171: 
172: end.

Although above code has generated “author” as a class instead of a WideString, it has not put in its name space http://www.bochenlin.com/author at all. It can be solved by modify line 111 in above code:



111:   RegisterChildNode(‘author’, TXMLAuthor_a, ‘http://www.bochenlin.com/author’);


Yes, it is simple, but it is not perfect yet. If the schemas are as simple as these two in this blog and you are pretty sure they won’t going to be changed, congratulations, you have done the job. But if the number of involved schemas is large and they are likely to change in the near future, it means you are going to regenerate the code again and again so that you are going to loose the modifications and have to redo manually. Don’t know if you have noticed that it does not only loose the changes you have put in but also the GUIDs of the interfaces are changed every time the code is regenerated. So the maintenance of the code becomes very trivial and difficult. I have a better solution in terms of maintaining these auto-generated code. I will introduce Class Helpers to solved this problem in my next blog.

Wednesday, February 6, 2013

XML Data Binding in Delphi 2007 (1)

Problem overview

  1. Wizards. There is a wizard named “XML Data Binding” in Delphi to help you generate a new unit which contains classes and interfaces mapped to a specified XML schema.
    image
    (F1: XML Data Binding in Delphi 2007)
    image
    (F2: XML Data Binding in Delphi XE)
    As the same wizard in Delphi XE is much advanced than the same one in Delphi 2007, I strongly suggest that you should use XE’s to generated the unit and copy it to your Delphi 2007’s project. Basically the unit generated by Delphi 2007 is not useful when the schema is complex (i.e it contains multiple name spaces and multiple imports etc.) The wizard in afterwards is always the one in Delphi XE.
  2. Name spaces. When the schema contains multiple name spaces, although the wizard can still generated the correct structure of the schema, the elements are always in the target name space regardless which name space they are actual in, according to the schema. This is due to the generated code does not use any name space to register a child node at all. This is not DOM’s problem, the MSXMLDOM has the capability to represent multiple name spaces. It is the implementation of the wizard that makes assumption that the XML has all elements in only one name space which is the target name space.
  3. Conformance to the schema. XML Data Binding is a mapping between the XML schema and the Delphi class. They describe the same thing in different format. These two formats have  overlap which covers most of the thing they are describing. But there are some areas that a Delphi class cannot easily achieve as same as the XML schema can. One of these area is the “sequence” restriction to element. XML Data Binding uses properties to represent the child element. Before reading from or writing to the property, the corresponding element has not been created into the DOM yet, it creates it immediately once a reading or writing operation is occurred. In another word, the order of the element is created by the order of the properties reading and writing. And this reading or writing order is totally decided by the programmer according to his/her taste. When it is time to output the final XML document, the order of the element will be the same of their creation order. This order might or might not conform the order specified by the XML schema it is mapping.

I have provided the solution for the first problem, in the next blog, I will provide solutions for the other two problems.

Monday, January 21, 2013

ASP.Net 4.5 + Report Viewer 11.0 having blank report

Recently, I did a ASP.Net application. It is developed by VS 2012. There is a page showing a report by using Report Viewer which comes with VS2012.

 

Everything runs OK in my local machine until the application is deployed onto a remote server. The issue was that the report content is blank. It seems

no error at all until the debug window of the browser is opened. In the Console tab, it complains that “Ajax client-side framework failed to load”.

 

According to Khaled in the below thread (http://stackoverflow.com/questions/3695351/ajax-client-side-framework-failed-to-load-asp-net-4-0),

it is fixed by having below section:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

 

without changes in Global.asax.

Tuesday, January 15, 2013

CC.Net sample Files

ccnet.config:

<?xml version="1.0" encoding="utf-8"?>
<cruisecontrol>
    <project name="cc-config">
        <!--Project for updating this config file when this config file is also managed in a SVN repository-->
        <triggers>
            <intervalTrigger seconds="30"/>
        </triggers>
        <sourcecontrol type="multi">
            <sourceControls>
                <svn>
                    <workingDirectory>C:\Program Files\CruiseControl.NET\server\cc.net</workingDirectory>
                    <trunkUrl>http://MySVNServer/repos/AutoBuild/CC.Net</trunkUrl>
                    <executable>C:\Program Files\CollabNet Subversion Client\svn.exe</executable>
                    <username>autobuildername</username>
                    <password>password</password>
                </svn>
                <svn>
                    <workingDirectory>C:\MyWorkingFolder\Common\trunk</workingDirectory>
                    <trunkUrl>http://MySVNServer/repos/common/trunk</trunkUrl>
                    <executable>C:\Program Files\CollabNet Subversion Client\svn.exe</executable>
                    <username>autobuildername</username>
                    <password>password</password>
                </svn>
            </sourceControls>
        </sourcecontrol>
    </project>
   
    <project>
        <name>MyProject</name>
        <webURL></webURL>
        <triggers>
            <intervalTrigger seconds="1800"/>
        </triggers>
        <workingDirectory>C:\MyWorkingFolder\MyProject</workingDirectory>
        <modificationDelaySeconds>300</modificationDelaySeconds>
        <labeller type="assemblyVersionLabeller">
            <major>1</major>
            <minor>8</minor>
            <build>4</build>
            <incrementOnFailure>false</incrementOnFailure>
        </labeller>
        <sourcecontrol type="multi">
            <sourceControls>
                <!-- Updating dependedcy 1 -->
                <svn>
                    <trunkUrl>http://MySVNServer/repos/Nsis/trunk/headers</trunkUrl>
                    <executable>C:\Program Files\CollabNet Subversion Client\svn.exe</executable>
                    <username>autobuildername</username>
                    <password>password</password>
                    <workingDirectory>C:\MyWorkingFolder\installer\NsisCommon\headers</workingDirectory>
                </svn>
                <svn>
                    <trunkUrl>http://MySVNServer/repos/dependency1/trunk</trunkUrl>
                    <executable>C:\Program Files\CollabNet Subversion Client\svn.exe</executable>
                    <username>autobuildername</username>
                    <password>password</password>
                    <workingDirectory>C:\MyWorkingFolder\dependency1\trunk</workingDirectory>
                </svn>
                <svn>
                    <trunkUrl>http://MySVNServer/repos/MyProject/trunk</trunkUrl>
                    <executable>C:\Program Files\CollabNet Subversion Client\svn.exe</executable>
                    <username>autobuildername</username>
                    <password>password</password>
                    <workingDirectory>C:\MyWorkingFolder\Trunk</workingDirectory>
                </svn>
            </sourceControls>
        </sourcecontrol>
        <tasks>
            <exec>
                <executable>C:\Windows\System32\cmd.exe</executable>
                <buildArgs>/c DEL /q /s "build result\*.*" </buildArgs>
                <buildTimeoutSeconds> 1200 </buildTimeoutSeconds>
            </exec>           
            <msbuild>
                <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
                <workingDirectory>C:\MyWorkingFolder\dependency1\Trunk</workingDirectory>
                <projectFile>C:\MyWorkingFolder\dependency1\Trunk\dependency1.msbuild</projectFile>
                <buildArgs>/noconsolelogger /p:Configuration=Release /v:diag /t:BuildProjectRes;BuildSelfUpdateRes;Build</buildArgs>
                <timeout>900</timeout>
                <logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
                <environment>
                    <variable name="BDS" value="C:\Program Files\Codegear\RAD Studio\8.0"/>
                    <variable name="Path" value="C:\Program Files\Codegear\RAD Studio\8.0\bin;%Path%"/>
                    <variable name="Win32LibraryPath" value="C:\Program Files\CodeGear\RAD Studio\8.0\lib\Win32\Release"/>                   
                    <variable name="DXVCL" value="C:\Delphi\Third Party Packages\DevEx.VCL.56"/>
                </environment>
            </msbuild>           
            <msbuild>
                <executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
                <workingDirectory>C:\MyWorkingFolder\MyProject\trunk\src</workingDirectory>
                <projectFile>MyProject.msbuild</projectFile>
                <buildArgs>/noconsolelogger /t:BuildProjectRes;Build /p:Configuration=Release;DCC_ExeOutput="..\bin" /v:diag</buildArgs>
                <timeout>900</timeout>
                <logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
                <environment>
                    <variable name="BDS" value="C:\Program Files\Codegear\RAD Studio\8.0"/>
                    <variable name="Path" value="C:\Program Files\Codegear\RAD Studio\8.0\bin;%Path%"/>
                    <variable name="Win32LibraryPath" value="C:\Program Files\CodeGear\RAD Studio\8.0\lib\Win32\Release"/>
                    <variable name="DXVCL" value="F:\Delphi\Third Party Packages\DevEx.VCL.56"/>
                </environment>
            </msbuild>
            <exec>
                <executable>C:\Windows\System32\cmd.exe</executable>
                <buildArgs>/c xcopy /Y "bin\MyProject.exe" "Build Result\Indivisual File\bin\"</buildArgs>
                <!-- above path is related to workingDirectory of Project -->
            </exec>
            <exec>
                <!-- add EurekaLog -->
                <executable>C:\Program Files\CodeGear\RAD Studio\8.0\Bin\ecc32.exe</executable>
                <buildArgs> --el_alter_exe"src\MyProject.dproj;bin\MyProject.exe" --el_config"src\MyProject.dproj"</buildArgs>
                <buildTimeoutSeconds>900</buildTimeoutSeconds>
            </exec>
            <!-- below two build msi installer -->
            <exec>
               
                <executable>C:\Program Files\WiX Toolset v3.6\bin\candle.exe </executable>
                <buildArgs>@installer\MyProject-candle-response.txt</buildArgs>
                <buildTimeoutSeconds>1200 </buildTimeoutSeconds>
            </exec>
            <exec>
                <executable>C:\Program Files\WiX Toolset v3.6\bin\light.exe</executable>
                <buildArgs>@installer\MyProject-light-response.txt</buildArgs>
                <buildTimeoutSeconds>1200 </buildTimeoutSeconds>
            </exec>
            <exec>
                <executable>C:\Program Files\NSIS\makensis.exe</executable>
                <buildArgs>/V3 /DOS_Platform_Specification=MyProject32BitSpecification /DOutputDir="..\Build Result\Installer" "installer\MyProject.nsi"</buildArgs>
                <buildTimeoutSeconds>1200</buildTimeoutSeconds>
            </exec>
            <exec>
                <executable>C:\Windows\System32\cmd.exe</executable>
                <buildArgs>/c del "Build Result\Installer\*.wixpdb"</buildArgs>
                <buildTimeoutSeconds> 1200 </buildTimeoutSeconds>
            </exec>
        </tasks>
        <publishers>
            xmllogger=""
            <statistics/>
            <email mailport="25" includeDetails="TRUE" mailhostUsername="autobuildername" mailhostPassword="password" useSSL="FALSE">
                <from>productauto.builder@MyCompany.com</from>
                <mailhost>My-SMTP-Server</mailhost>
                <users>
                    <user name="BuildGuru" group="buildmaster" address="master@MyCompany.com"/>
                    <user name="Developer1" group="developers" address="developer1@MyCompany.com"/>
                    <user name="Tester1" group="testers" address="tester1@MyCompany.com"/>
                </users>
                <groups>
                    <group name="developers">
                        <notifications>
                            <notificationType>Failed</notificationType>
                            <notificationType>Fixed</notificationType>
                        </notifications>
                    </group>
                    <group name="testers">
                        <notifications>
                            <notificationType>Fixed</notificationType>
                        </notifications>
                    </group>
                    <group name="buildmaster">
                        <notifications>
                            <notificationType>Always</notificationType>
                        </notifications>
                    </group>
                </groups>
                <converters>
                    <!-- regexConverter find="$" replace="@TheCompany.com" /
-->
                </converters>
                <modifierNotificationTypes>
                    <NotificationType>Failed</NotificationType>
                    <NotificationType>Fixed</NotificationType>
                </modifierNotificationTypes>
                <subjectSettings>
                    <subject buildResult="StillBroken" value="Build is still broken for My Project"/>
                </subjectSettings>               
            </email>
            <buildpublisher>
                <sourceDir>Build Result</sourceDir>
                <publishDir>\\MyServer\Installs\MyProject\Installation Files\Version 1.8.4\Builds</publishDir>
                <useLabelSubDirectory>true</useLabelSubDirectory>
                <alwaysPublish>false</alwaysPublish>
            </buildpublisher>
        </publishers>
    </project>   
</cruisecontrol>

MSBuild file:

<?xml version="1.0" encoding="utf-8"?>
<Project
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
    >
    <!-- below import only works when this .msbuild file has the same name as the Delphi project file name -->
    <Import
        Project="$(MSBuildProjectName).dproj"
        />
    <!-- these two target are for debugging path purpose -->
    <Target
        Name="ShowDelphiProjectToBuild"
        >
        <Message
            Text="$(MSBuildProjectName).dproj"
            />
    </Target>
    <Target
        Name="ShowDCCPath"
        >
        <Message
            Text="$(DCC_UnitSearchPath)"
            />
    </Target>
    <UsingTask
        TaskName="DCC"
        AssemblyFile="$(BDS)\bin\Borland.Build.Tasks.Delphi.dll"
        />
    <Target
        Name="GetRevision"
        ><!-- SvnVersion is in the MSBuild Community Tasks Targets -->
        <SvnVersion
            LocalPath="$(MSBuildProjectDirectory)"
            >
            <Output
                TaskParameter="Revision"
                PropertyName="Revision"
                />
        </SvnVersion>
    </Target>
    <Target
        Name="BuildProjectRes"
        DependsOnTargets="Versioning"
        >
        <Microsoft.Build.Tasks.Exec
            Command="brcc32 $(ProjectName).rc $(ProjectName).res"
            />
    </Target>
    <!-- use Microsoft HTML Workshop for building CHM help file -->
    <Target
        Name="MakeHelp"
        >
        <Microsoft.Build.Tasks.Exec
            Command="hhc &quot;ProjectHelp.hhp&quot;"
            WorkingDirectory="$(ProjectRoot)\Help\"
            />
        <Microsoft.Build.Tasks.Copy
            SourceFiles="$(ProjectRoot)\Help\ProjectHelp.chm"
            DestinationFolder="$(PackingRoot)\InstallFiles\Project\Help"
            />
    </Target>
    <Target
        Name="PrepareDirForPublish"
        DependsOnTargets="BuildProjectRes"
        >
        <Microsoft.Build.Tasks.MakeDir
            Directories="$(CCNetWorkingDirectory)\$(MajorVer).$(MinorVer).$(ReleaseVer).$(Revision)"
            />
        <Microsoft.Build.Tasks.Copy
            SourceFiles="$(PackingRoot)\Output\$(MSBuildProjectName)Setup.exe"
            DestinationFolder="$(CCNetWorkingDirectory)\$(MajorVer).$(MinorVer).$(ReleaseVer).$(Revision)"
            />
        <Microsoft.Build.Tasks.Copy
            SourceFiles="$(PackingRoot)\InstallFiles\Project\Bin\$(MSBuildProjectName).exe"
            DestinationFolder="$(CCNetWorkingDirectory)\$(MajorVer).$(MinorVer).$(ReleaseVer).$(Revision)"
            />
    </Target>
    <Import
        Project="C:\Program Files\MSBuild\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"
        />
    <!--PropertyGroup-->
    <PropertyGroup>
        <ThirdPartyComponents>F:\Delphi\Third Party Packages</ThirdPartyComponents>
        <Abbrevia>$(ThirdPartyComponents)\Abbrevia\4.0\source</Abbrevia>
        <ComponentRoot></ComponentRoot>
        <DelphiColl>$(ThirdPartyComponents)\Delphi-coll\Library</DelphiColl>
        <DevExpress>$(ThirdPartyComponents)\DevEx.VCL.56\Library\Delphi15</DevExpress>
        <EurekaLog>$(ThirdPartyComponents)\EurekaLog 6\Delphi15</EurekaLog>
        <InstallScriptSourceDir></InstallScriptSourceDir>
        <JEDI>$(ThirdPartyComponents)\Jedi345</JEDI>
        <JCL>$(JEDI)\jcl</JCL>
        <JCLLib>$(JCL)\lib\d15;$(JCL)\source\common;$(JCL)\Source\windows;$(JCL)\Source;$(JCL)\Source\include</JCLLib>
        <JVCL>$(JEDI)\jvcl</JVCL>
        <JVCLLib>$(JVCL)\lib\d15;$(JVCL)\common;$(JVCL)\resources;$(JVCL)\run</JVCLLib>
        <ProjectRoot></ProjectRoot>
        <PackingRoot>$(ProjectRoot)\Installer</PackingRoot>
        <PublishRootDir></PublishRootDir>
        <TMS>$(ThirdPartyComponents)\TMS 6.0.3.0\</TMS>
        <VT>$(ThirdPartyComponents)\Soft Gems\Virtual Treeview 4.8.7\Source</VT>
        <OmniXML>$(ThirdPartyComponents)\OmniXML</OmniXML>
    </PropertyGroup>
    <PropertyGroup>
        <DCC_UnitSearchPath>$(BDS)\Lib\Win32\Release;$(Abbrevia);$(DevExpress);$(EurekaLog);$(FastMM);$(JCLLib);$(JVCLLib);$(TMS);$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
        <DCC_UnitSearchPath>$(SqliteLib);$(ClaimsLib);F:\Build\delphi_client\trunk\Common;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
        <DCC_UnitSearchPath>$(ManagedDLL);$(VT);$(Zip);$(OmniXML);$(BDS)\Lib\Indy10;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
        <DCC_UnitSearchPath>$(DelphiColl);$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
        <UnitSearchPath>$(DCC_UnitSearchPath)</UnitSearchPath>
        <!-- DCC_Define>compiler directives are specified in the .dproj file, they are not necessary to define here</DCC_Define -->
        <DCC_ObjPath>$(DCC_ObjectPath);$(UnitSearchPath)</DCC_ObjPath>
        <DCC_ResourcePath>$(DCC_ResourcePath);$(UnitSearchPath)</DCC_ResourcePath>
        <DCC_IncludePath>$(DCC_IncludePath);$(UnitSearchPath)</DCC_IncludePath>
        <ObjPath>$(UnitSearchPath)</ObjPath>
        <ResourcePath>$(UnitSearchPath)</ResourcePath>
        <IncludePath>$(UnitSearchPath)</IncludePath>
        <DCC_ExeOutput>C:\MyWorkingFolder\MyProject\Output</DCC_ExeOutput>
        <DCC_DcuOutput></DCC_DcuOutput>
        <ProjectName>MyProject</ProjectName>
        <MajorVer>1</MajorVer>
        <MinorVer>8</MinorVer>
        <ReleaseVer>4</ReleaseVer>
        <ProductVersion>$(MajorVer),$(MinorVer)</ProductVersion>
        <CompanyName>My Company Name</CompanyName>
        <Comments/>
    </PropertyGroup>
    <Target
        Name="MsBuildBinPath"
        >
        <Message
            Text="$(MSBuildBinPath)"
            />
    </Target>
    <Target
        Name="Versioning"
        DependsOnTargets="GetRevision"
        >
        <ItemGroup>
            <Tokens
                Include="MajorVer"
                >
                <ReplacementValue>$(MajorVer)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="MinorVer"
                >
                <ReplacementValue>$(MinorVer)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="ReleaseVer"
                >
                <ReplacementValue>$(ReleaseVer)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="Revision"
                >
                <ReplacementValue>$(Revision)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="ProductVersion"
                >
                <ReplacementValue>$(ProductVersion)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="CompanyName"
                >
                <ReplacementValue>$(CompanyName)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="FileDescription"
                >
                <ReplacementValue>$(FileDescription)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="InternalName"
                >
                <ReplacementValue>$(InternalName)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="LegalCopyRight"
                >
                <ReplacementValue>$(LegalCopyRight)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="LegalTrademarks"
                >
                <ReplacementValue>$(LegalTrademarks)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="OriginalFilename"
                >
                <ReplacementValue>$(OriginalFilename)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="ProductName"
                >
                <ReplacementValue>$(ProductName)</ReplacementValue>
            </Tokens>
            <Tokens
                Include="Comments"
                >
                <ReplacementValue>$(Comments)</ReplacementValue>
            </Tokens>
        </ItemGroup>
        <TemplateFile
            Template="versioninfo.template.rc"
            OutputFilename="$(ProjectName).rc"
            Tokens="@(Tokens)"
            />
        <TemplateFile
            Template="$(MSBuildProjectDirectory)\..\..\installer\product-version.template.nsh"
            OutputFilename="$(MSBuildProjectDirectory)\..\..\installer\product_version.nsh"
            Tokens="@(Tokens)"
            />
    </Target>
</Project>

 

Versioninfo.template.rc:

VS_VERSION_INFO VERSIONINFO
FILEVERSION ${MajorVer},${MinorVer},${ReleaseVer},${Revision}
PRODUCTVERSION ${ProductVersion}
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "080904B0"
    BEGIN
      VALUE "CompanyName",      "${CompanyName}\0"
      VALUE "FileDescription",  "${FileDescription}\0"
      VALUE "FileVersion",      "${MajorVer}.${MinorVer}.${ReleaseVer}.${Revision}\0"
      VALUE "InternalName",     "${InternalName}\0"
      VALUE "LegalCopyright",   "${LegalCopyRight}\0"
      VALUE "LegalTrademarks",  "${LegalTrademarks}\0"
      VALUE "OriginalFilename", "${OriginalFilename}\0"
      VALUE "ProductName",      "${ProductName}\0"
      VALUE "ProductVersion",   "${ProductVersion}\0"
      VALUE "Comments",         "${Comments}\0"
    END
  END

  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x809,1200
  END
END