Build and Publish .NET with MSBUILD with Powershell – Part 1

November 24, 2009

This post will explain the process of automating your build / publish (web or windows) with windows Powershell and MSBUILD

What I use ?
1) MSBUILD
2) VS 2008 – The sample that i will provide will depend upon a windows application and a web application
3) Powershell – ease of scripting, next generation script for windows, search for Windows Powershell to learn more
4) SVN – Source code repos (you can alternatively use any source code repos for integrating)

Before you Start(I mean : prerequisites)
1) Install MSBUILD – (if you already don’t have it)
2) open PowerShell and type – MSBUILD, you must see something like this
Microsoft (R) Build Engine Version 3.5.21022.8
[Microsoft .NET Framework, Version 2.0.50727.1433]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.

–if you get this then you have MSBUILD properlly installed
– if not then you probably must add the Env. Variables – to do this – right click my computer –> props –> Env. variables –> select path and add “C:\WINDOWS\Microsoft.NET\Framework\v3.5″ (for vs2008 installations, this might differ for vs2005 as it uses the 2.0 framework)
3) Make sure you have MSBUILD community tasks – its a freely available over the net…
4) SVN – a source code control management
5) I Tunes or any other music player – a good collection of songs – my favorite was OST – Batman, The Dark kinght .

ok, this is how it works
MSBUILD is blah blah blah, there is already enuf said abt this throughout the net…
We need to give a solution file / .proj file with some target specified to msbuild to perform the BUILD. So create a fine named yourproject.proj, copy the following contents to it…
<?xml version=”1.0″ encoding=”utf-8″?>

<Project DefaultTargets=”Build” xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″>
<Import Project=”$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets”/>

<PropertyGroup>
<Major>2</Major>
<Minor>2</Minor>
<Build>0</Build>
<Revision>0</Revision>
</PropertyGroup>

<ItemGroup>
<DefaultExclude Include=”**\.svn\**” />
<DefaultExclude Include=”**\bin\**” />
<DefaultExclude Include=”**\obj\**” />
<DefaultExclude Include=”**\Release\**” />
<DefaultExclude Include=”**\Debug\**” />
<DefaultExclude Include=”**\Test\**” />
<DefaultExclude Include=”**\TestResults\**” />
<DefaultExclude Include=”**\doc\**” />
<DefaultExclude Include=”**\www\**” />
<DefaultExclude Include=”**\*.user” />
<DefaultExclude Include=”**\*.suo” />
<DefaultExclude Include=”**\*.zip” />
<DefaultExclude Include=”**\*.txt” />
<DefaultExclude Include=”**\*.pdb” />
</ItemGroup>

<PropertyGroup>
<SourceFileRootFolder>TODO: YOUR WORKING FOLDER PATH</SourceFileRootFolder>
<WebFolder>TODO: YOUR WEB SITE DIRECTORY FOLDER PATH</WebFolder>
<ReleaseFolder>TODO: GIVE THE PATH OF THE PUBLISH FOLDER(C:\PublishedSource</ReleaseFolder>
</PropertyGroup>

<ItemGroup>
<ZipFiles Include=”../MyProject/bin/Release/*.*;” Exclude=”@(DefaultExclude)” />
</ItemGroup>

<ItemGroup>
<DefaultBinFiles Include=”$(SourceFileRootFolder)\DefaultBinFiles\*.*”/>
<ProjectBinFiles Include=”$(SourceFileRootFolder)\$(WebFolder)\bin\*.*”/>
</ItemGroup>

<Target Name=”Compile”>
<MSBuild Projects=”../MyProject/MyProject.csproj” Properties=”Configuration=Release” />
</Target>

<Target Name=”CleanSource”>
<Message Text=”Removing all source files from $(ReleaseFolder)” />
<RemoveDir Directories=”$(ReleaseFolder)” />
</Target>

<Target Name=”PublishWeb” DependsOnTargets=”Mimify”>
<MSBuild Projects=”$(SourceFileRootFolder)\$(WebFolder)\WebProject.csproj” Targets=”Clean;Build” />
<CallTarget Targets=”CleanSource”/>
<MSBuild Projects=”$(SourceFileRootFolder)\$(WebFolder)\WebProject.csproj” Targets=”_CopyWebApplication;_BuiltWebOutputGroupOutput” Properties=”OutDir=$(ReleaseFolder)\” ></MSBuild>
<Copy SourceFiles=”@(DefaultBinFiles)” DestinationFolder=”$(ReleaseFolder)\$(WebFolder)\bin\”></Copy>
<Copy SourceFiles=”@(ProjectBinFiles)” DestinationFolder=”$(ReleaseFolder)\$(WebFolder)\bin\”></Copy>
</Target>

<Target Name=”BuildWeb” DependsOnTargets=”PublishWeb”>
<Message Text=”Build of web application complete”/>
</Target>

<Target Name=”Zip” DependsOnTargets=”Compile”>
<Zip Files=”@(ZipFiles)” ZipFileName=”SOMENAME.v$(Major).$(Minor).$(Build).$(Revision).zip” />
</Target>

<Target Name=”BuildTool” DependsOnTargets=”Zip”>
<Message Text=”Tool build completed”/>
</Target>
<UsingTask
TaskName=”CompressorTask”
AssemblyFile=”Yahoo.Yui.Compressor.dll” />
<PropertyGroup>
<CssOutputFile Condition=” ‘$(CssOutputFile)’==” “>SylesSheetFinal.css</CssOutputFile>
<JavaScriptOutputFile Condition=” ‘$(JavaScriptOutputFile)’==” “>$(SourceFileRootFolder)\$(WebFolder)\myjs\</JavaScriptOutputFile>
</PropertyGroup>

<Target Name=”Mimify”>
<!–
ItemGroup\CssFiles or ItemGroup\JavaScriptFiles: add zero to many files you wish to include in this compression task.
Don’t forget, you can use the wildcard (eg. *.css, *.js) if you feel up to it.
Finally, at least one item is required – either a css file or a js file.

CssFiles/JavaScriptFiles data format: Please do not touch this.
DeleteCssFiles: [Optional] True | Yes | Yeah | Yep | True | FoSho | Fo Sho. Default is False. Anything else is False. (eg. blah = false, xxxx111 = false, etc)
CssCompressionType: YuiStockCompression | MichaelAshsRegexEnhancements | HaveMyCakeAndEatIt or BestOfBothWorlds or Hybrid; Default is YuiStockCompression.
ObfuscateJavaScript: [Optional] refer to DeleteCssFiles, above.
PreserveAllSemicolons: [Optional] refer to DeleteCssFiles, above.
DisableOptimizations: [Optional] refer to DeleteCssFiles, above.
EncodingType: [Optional] ASCII, BigEndianUnicode, Unicode, UTF32, UTF7, UTF8, Default. Default is ‘Default’.
DeleteJavaScriptFiles: [Optional] refer to DeleteCssFiles, above.
LineBreakPosition: [Optional] the position where a line feed is appened when the next semicolon is reached. Default is -1 (never add a line break).
0 (zero) means add a line break after every semicolon. (This might help with debugging troublesome files).
LoggingType: None | ALittleBit | HardcoreBringItOn; Hardcore also lists javascript verbose warnings, if there are any (and there usually is :P ).
ThreadCulture: [Optional] the culture you want the thread to run under. Default is ‘en-gb’.
IsEvalIgnored: [Optional] compress any functions that contain ‘eval’. Default is False, which means a function that contains
‘eval’ will NOT be compressed. It’s deemed risky to compress a function containing ‘eval’. That said,
if the usages are deemed safe this check can be disabled by setting this value to True.
–>
<ItemGroup>
<JavaScriptFiles Include=”$(SourceFileRootFolder)\$(WebFolder)\Javascript\*.js” />
<CSSFiles Include=”$(SourceFileRootFolder)\$(WebFolder)\Themes\*.css” />
</ItemGroup>
<CompressorTask
DeleteCssFiles=”false”
CssOutputFile=”%(CSSFiles.Identity)”
CssCompressionType=”YuiStockCompression”
JavaScriptFiles=”@(JavaScriptFiles)”
CSSFiles=”@(CSSFiles)”
ObfuscateJavaScript=”True”
PreserveAllSemicolons=”False”
DisableOptimizations=”Nope”
EncodingType=”Default”
DeleteJavaScriptFiles=”false”
LineBreakPosition=”-1″
JavaScriptOutputFile=”%(JavaScriptFiles.Identity)”
LoggingType=”ALittleBit”
ThreadCulture=”en-au”
IsEvalIgnored=”false”
/>
</Target>

</Project>

Change your relevant project details in it – i have placed TODO: to specify what has to be done.

There are lot of targets specified in my .proj fle
Compile – compiles the source files
PublishTool – publishes the windows application
PublishWeb – publishes the web application
Mimify – Obfuscate Javascript and CSS files – uses external dll, freely available on net

I have several things in my build project…like for example all my JAVASCRIPT and CSS will be obfuscated during the publish time so that i don’t allow anyone to re-engineer my JS logic…

Execute the build
To execute the build
1) open powershell / command prompt
2) msbuild.exe c:\whereever\yourproject.proj (remember the target file we created in the previous step)
you can provide a target as
msbuild.exe c:\whereever\yourproject.proj /t:Publishweb

so its pretty much of it…any questions please feel free to email me – consoleart@gmail.com

in my next article we shall see how to automate the build process…

These concepts may be little old, but there are several projects who are struggling with build automation, may be this article will help them to provide a bit of understanding…

thnx to the people who have shown me that there are several tools that exists to make our life easier…


Configure SVN with Apache – Windows Server / XP

November 24, 2009

I googled a lot about configuring SVN repository with Apache server and thought that I should write my experience on how i succeeded in configuring it

A Preface:
I earlier used SVN server with IIS by running a SVN service, it really messed up a lot(or atleast with the info that I had) and most of the time I happen to netwrk-share my SVN repos directory and connect from other machines, then we decided to move our SVN to a apache web server…so here is the configuration details…

What you need ?
1) Apache 2.x
2) SVN
3) Tortoise SVN Client

1) Install apache – you can change the default port number(80) if you have IIS running on that machine.

http://httpd.apache.org/download.cgi

2) Install SVN – i used this MSI for installation Setup-Subversion-1.6.4.msi
3) Install Tortoise SVN – On the client machine – we dont need this on teh server unless you want to have a working directory(for build purpose, more of this in my next article) on your server
tortoisesvn.net/downloads

– after all this restart your machine once(not needed if you are using a windows server, if you are using XP then restart is advisable)

Create repository -this is the easiest of all the tasks
Create a directory – C:\SourceCodeRepos
once you have installed SVN you will find the bin folder contains svnadmin, use this to create a repos
open command Prompt> svnadmin create “C:\SourceCodeRepos”
(if you get an error bad command or filename then add the SVN bin path to the environment variables Mycomputer –> right click –> props –> Env Variables –> Path –> Edit –> dont overwrite the existing one–> copy the bin path of SVN in the end.)

Configure APACHE – a little less easier than the prev one
apache step 1)
Create a folder c:\etc — this directory will hold the config files of your SVN repos and apache auth files.

Create three files inside this directory (c:\etc)
a) File name: subversion.conf
Content of the file

DAV svn
SVNPath C:\SourceCodeRepos

AuthType Basic
AuthName “Subversion Kinetics repository”
AuthUserFile c:/etc/svn-auth-file

Require valid-user

AuthzSVNAccessFile c:/etc/svn-acl

b) File Name: svn-acl
Content:
# groups foes here
[groups]
developers = username1,username2,username3

# developers group has a read/write access to source code repository
[SourceCodeRepos:/]
@developers = rw
* = r

c) File name: svn-auth-file
no content for this file…

apache step 2)

copy the modules “mod_authz_svn.so” and “mod_dav_svn.so” to your apache modules directory
c:\Program Files\Apache Software Foundation\Apache2.2\modules\

apache step 3)

Add these lines to you httpd.conf (located at c\Program Files\Apache Software Foundation\Apache2.2\conf)
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

apache step 4)
add this line to the end of the same file (httpd.conf)
Include c:/etc/subversion.conf
#this step will load the SVN configuration of our repos to apache

restart your apache server…

we are almost done…
the final step is to create usernames and store them in the auth file
here is the step to create username using htpasswd

htpasswd -m “c:\etc\svn-auth-file” ausername
a help link is here

http://httpd.apache.org/docs/2.0/programs/htpasswd.html

(the htpasswd is available under the apache directory)

Check the URL by typing
http://localhost/SourceCodeRepos – you must be prompted with a username and password, if it is so then you have succeeded, congratulations !!

now from any client machine you can access the repos using the url

http://servername/SourceCodeRepos…

use TortoiseSVN to access the repos URL…

I will be glad to help you in any step, do let me know…


Encrypt and Decrypt – Basic version

October 24, 2009

This is a basic version of encrypt-decrypt function…we used this from one of the .NET sites, since i am not able to find teh reference link , iam posting it here so that others can use it…
public class MyEnctDect
{
private Byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
private Byte[] iv = { 65, 110, 68, 26, 69, 178, 200, 219 };

public string Encrypt(string plainText)
{
//’ Declare a UTF8Encoding object so we may use the GetByte
//’ method to transform the plainText into a Byte array.
String outString;
UTF8Encoding utf8encoder = new UTF8Encoding();
Byte[] inputInBytes = utf8encoder.GetBytes(plainText);
//’ Create a new TripleDES service provider
TripleDESCryptoServiceProvider tdesProvider = new TripleDESCryptoServiceProvider();
//’ The ICryptTransform interface uses the TripleDES
//’ crypt provider along with encryption key and init vector
//’ information
ICryptoTransform cryptoTransform = tdesProvider.CreateEncryptor(key, iv);
//’ All cryptographic functions need a stream to output the
//’ encrypted information. Here we declare a memory stream
//’ for this purpose.
MemoryStream encryptedStream = new MemoryStream();
CryptoStream cryptStream = new CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write);
//’ Write the encrypted information to the stream. Flush the information
//’ when done to ensure everything is out of the buffer.
cryptStream.Write(inputInBytes, 0, inputInBytes.Length);
cryptStream.FlushFinalBlock();
encryptedStream.Position = 0;
//’ Read the stream back into a Byte array and return it to the calling
//’ method.
// Dim result(encryptedStream.Length – 1) As Byte
byte[] result = new byte[encryptedStream.Length];
encryptedStream.Read(result, 0, (int)encryptedStream.Length);
cryptStream.Close();
//’test section
//’Convert to / fro the memory stream to a base64 string
//’compare decText to result
outString = System.Text.ASCIIEncoding.Default.GetString(result);

string encText = Convert.ToBase64String(encryptedStream.ToArray());
byte[] decText = Convert.FromBase64String(encText);
string sDec = Decrypt(decText);
return outString;
}

public String Decrypt(Byte[] inputInBytes)
{
//’ UTFEncoding is used to transform the decrypted Byte Array
//’ information back into a string.
UTF8Encoding utf8encoder = new UTF8Encoding();
TripleDESCryptoServiceProvider tdesProvider = new TripleDESCryptoServiceProvider();
//’ As before we must provide the encryption/decryption key along with
//’ the init vector.
ICryptoTransform cryptoTransform = tdesProvider.CreateDecryptor(key, iv);
//’ Provide a memory stream to decrypt information into
MemoryStream decryptedStream = new MemoryStream();
CryptoStream cryptStream = new CryptoStream(decryptedStream, cryptoTransform, CryptoStreamMode.Write);
cryptStream.Write(inputInBytes, 0, inputInBytes.Length);
cryptStream.FlushFinalBlock();
decryptedStream.Position = 0;
//’ Read the memory stream and convert it back into a string
Byte[] result = new byte[decryptedStream.Length];
decryptedStream.Read(result, 0, (int)decryptedStream.Length);
cryptStream.Close();
UTF8Encoding myutf = new UTF8Encoding();
return myutf.GetString(result);
}
}
usage
MyEnctDect classDeclartion = new MyEnctDect();
classDeclartion.Encrypt(text);
classDeclartion.Decrypt(bytearray);

Its a good one for beginners, there are other methods available as well


Creating controls with javascript

October 23, 2009

Thought this will be helpful for beginners

Create static combo
Create password field
create textbox
create textarea, all samples are subject to COPY rights…i mean you can use them for freee…

function CreateStaticCombo(sCtrlId, Width, list, value, defaultValue) {

var optGroup = document.createElement(’select’)
var arr = list.split(‘###’);

optGroup.setAttribute(‘className’, ‘ComboBoxStyle’);
optGroup.onblur = function() { };
optGroup.id = sCtrlId;
optGroup.name = sCtrlId;

var objOption = document.createElement(“option”)
objOption.innerText = “”;
objOption.value = “”;
optGroup.appendChild(objOption)

for (var i = 0; i < arr.length; i++) {
if (arr[i] != "") {
var objOption = document.createElement("option")
objOption.innerText = arr[i];
objOption.value = arr[i];

if (arr[i] == value.trim())
objOption.selected = true;

optGroup.appendChild(objOption)
}
}
optGroup.style.border = 0;
optGroup.onkeyup = function() { };
return optGroup;

}

function CreateLookupIcon(sCtrlId, IsLookupConditionAvailable) {
var imageNode = document.createElement("input");
imageNode.type = 'image';
imageNode.id = "imagetext"
imageNode.src = '../images/asmall.gif';

imageNode.onclick = function() { someJavascriptFunction(someParameters); return false; };
return imageNode;
}
function CreateHiddenField(sCtrlId) {
var txtbox = document.createElement('input');
txtbox.type = 'hidden';
txtbox.id = sCtrlId.replace('TD', 'D');
txtbox.name = sCtrlId.replace('TD', 'D');
return txtbox;
}

function CreatePassword(sCtrlId) {
var txtbox = document.createElement('input');
txtbox.onblur = function() { SetHiddenValue(this.id, this.value); EvaluateExpression('ALL', sCtrlId.toString().split('~')[2]) };
txtbox.type = 'password';
txtbox.passwordText = '*';
txtbox.id = sCtrlId;
txtbox.name = sCtrlId;
txtbox.setAttribute('className', 'MVTextBoxStyle');
txtbox.style.border = 1;
txtbox.style.bordercolor = "black";
txtbox.style.borderStyle = "solid"
return txtbox;
}

function CreateTextArea(sCtrlId, Width) {
var txtbox = document.createElement('textarea');
txtbox.rows = "2";
txtbox.style.height = "40px";
txtbox.onblur = function() { SetHiddenValue(this.id.replace('txt', ''), this.value); EvaluateExpression('ALL', sCtrlId.toString().split('~')[2]) };
txtbox.id = "txt" + sCtrlId;
txtbox.name = "txt" + sCtrlId;
txtbox.setAttribute('className', 'MVTextBoxStyle');

return txtbox;
}


Fruits, Flowers and Sea !!!

June 26, 2009

Camera Version – Canon – i have replaced my earlier pic with this new one
flowervase3

Fruits
Fruits
Seashore
SeaShore


one of my earlier sketches

June 25, 2009

This one is my favorite
IMAGE_00076


Copied from real life – redrawn by me

June 24, 2009

IMAGE_00055


Some of my random sketches

June 24, 2009

All sketches were done with Stedler pencils….
Bridge
IMAGE_00069

Far Far Away !!!!
IMAGE_00057

Natraj – Thai Crown version
IMAGE_00056


Malesome Model

June 24, 2009

A sketch of a model…AKA Washing Powder Nirma !!!

IMAGE_00065


Small scale IT companies

June 23, 2009

This was how we used to work our ass off…its hard to beleive that i remember each dialogue that happened some 8 years before, they still haunt me at times…this conversation is in tamil, iam not sure whether this will give the same meaning when i translate this in English, so iam not trying out one…the characters…. P: is the boss : JM and J are the workers, there were some more people in the room, but they were totally dumbstruck!!!!…i hope you can imagine…

howwereact

most of the small scale IT companies management think the same way…the workers will always give this look…poor but fun…