Sunday, October 19, 2008

RegEx - To validate emails...

Hey All,

You can use this to validate emails!

[a-zA-Z0-9_]+\.{0,1}[a-zA-Z0-9_]*\.{0,1}[a-zA-Z_]*[\@][a-zA-Z]+[\.][a-zA-Z]+[\.]{0,1}[a-zA-Z]*

Happy coding :)

Saturday, October 11, 2008

Power of LINQ - Querying ArrayLists

Hey all!

Welcome back :)

This posting is about querying ArrayLst's using LINQ. Following is an example of the same. Explanations follow after the code..

using System;
using System.Linq;
using System.Collections;

namespace QueryArrayList
{
public class Report
{
public int reportNo;
public string reportName;
}

public class QueryArrayList
{
private static bool found = false;

public QueryArrayList()
{
}

public static void Main(string[] args)
{
string query_text = "null";

if (args.Length == 1)
{
query_text = args[0];
}

ArrayList aList = new ArrayList();

for (int i=0; i < 10; i ++)
{
Report report = new Report();
report.reportNo = i;
report.reportName = "Report " + i.ToString();

aList.Add(report);
}

var query =
(from Report reportList in aList
where reportList.reportName.Contains(query_text)
select new { reportList });

if (query != null)
{
foreach (var report in query)
{
Report rpt = new Report();
rpt.reportNo = report.reportList.reportNo;
rpt.reportName = report.reportList.reportName;

Console.WriteLine("Report retrieved: Report Number: {0} and Report Name: {1}",rpt.reportNo,rpt.reportName);

found = true;
}
}

if (! found)
Console.WriteLine("Empty result set");
}
}
}


The code is pretty straight forward. So I will get into the LINQ related part directly. There is a class called Report and the class QueryArrayList creates 10 objects of Report. The following LINQ query takes in as a parameter some text that is used to select a set of reports containing that text.

var query = (from Report reportList in aList
where reportList.reportName.Contains(query_text)
select new { reportList });


Here 'aList' is the ArrayList that contains the list of "Report" objects and using this part

from Report reportList

we specify that we are querying an ArrayList of type "Report".

where reportList.reportName.Contains(query_text)

The above part is to limit rows with the query text and finally

select new { reportList }

is to select the reports satisfying the condition and place it in a variable called reportList

In the foreach part I get each row in the set, create a new object of type "Report" and print it to the console.

That's it! We have successfully queried an ArrayList!!

Happy coding :)

Friday, October 10, 2008

Creating a Setup project in VS 2008 w/ Custom Actions

Hi!

This post elaborates ALL the steps required to create a setup project that is used deploy an application, in a step by step manner. What makes this post special is that it deals w/ custom actions. Normal setup projects doesn't allow us to do more than some set of pre-defined actions. So we need to override those settings w/ "Custom Installers". This post deals w/ the ways to create a custom setup project, that allows you to do specific actions during install/uninstall and various other events as described below. All tutorials out there in the internet tend to leave something or the other as far as I have seen. So I thought that I could post one that describes and/or implements everything that is required for a setup project, so that when you build and test it, everything works. Here we go!

The solution ("HelloWorld") for this contains 3 projects:

HelloWorld -

This is the application. This application just displays a form w/ the message "Hello World" and displays a text area that displays a text file deployed along w/ the setup and displays the message "Nothing to read" if the file is not present (input.txt is the input file copied during setup)

HelloWorldCustomInstaller -

This project helps us implement the customized installer. Details later.

HelloWorldSetup -

This project is of type "Setup and Deployment". Details later

You can download the entire solution as a zip file here

(Tested in Win XP/ VS 2008)


Steps:

* HelloWorld application: The code for the application in simple

[Form1.cs]

using System;
using System.Collections.Generic;
using System.ComponentModel;

using System.Data;
using System.Drawing;

using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace HelloWorld

{

public partial class Form1 : Form
{
private string str = "";


public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)

{

try

{

StreamReader sin = new StreamReader(new FileStream("input.txt", FileMode.Open));


while ((str = sin.ReadLine()) != null)

{

textBox1.AppendText(str);
}
}
catch { textBox1.Text = "Nothing to read"; }
}
}
}

I am not going to explain the code as it is out of scope for this post.

[Form1.cs Design view]
























* Here comes the fun part. Let us now discuss the "HelloWorldCustomInstaller" project which is used to create custom actions during installation/uninstallation

- To create this project you do the following steps
- Right click solution, Choose "New Project" - "Visual C#" - "Windows" - "Class Library"
- Name it "HelloWorldCustomInstaller"
- Delete the default "Program.cs"
- Right click the project "HelloWorldCustomInstaller", Choose Add -> New Item
- In this choose "Installer class"
- The class is created and if you view the code file you can see this:

using System;
using System.Collections;
using System.Collections.Generic;

using System.ComponentModel;

using System.Configuration.Install;

using System.Linq;


namespace HelloWorldCustomInstaller

{

[RunInstaller(true)]
public partial class Installer1 : Installer
{
public Installer1()
{
InitializeComponent();
}
}
}


A reference to System.Configuration.Install is required and this is added automatically along w/ the using clause.

See that the class "Installer1" inherits "Installer". Other requirements are that you should add [RunInstaller(true)] above class definition.

Now you are all set. To over ride the normal uninstall or install process you need to "override" the corresponding events. The following events are available for you to override:

* Commit
* Install
* OnAfterInstall
* OnAfterRollback
* OnAfterUninstall
* OnBeforeInstall
* OnBeforeRollback
* OnBeforeUninstall
* OnCommitted
* OnCommitting
* Rollback
* Uninstall

The names imply the use of each. The custom installer for this project just overrides Install and the Uninstall events. The code is given below:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.IO;

namespace HelloWorldCustomInstaller
{
[RunInstaller(true)]
public partial class HelloWorldInstaller : Installer
{
public HelloWorldInstaller()
{
InitializeComponent();
}

public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);

//Create a log file in the users desktop [delete it while uninstallation]
try
{
StreamWriter sout = new StreamWriter(new FileStream("C:\\Documents and Settings\\" + Environment.UserName + "\\Desktop\\HelloWorldLog.txt", FileMode.Append));
sout.WriteLine("Installing HelloWorld " + DateTime.Now.ToString());
sout.Close();
}
catch (InstallException)
{
}
}

public override void Uninstall(IDictionary savedState)
{
base.Uninstall(savedState);

//Delete the file created
try
{
if (File.Exists("C:\\Documents and Settings\\" + Environment.UserName + "\\Desktop\\HelloWorldLog.txt"))
{
File.Delete("C:\\Documents and Settings\\" + Environment.UserName + "\\Desktop\\HelloWorldLog.txt");
}
}
catch (InstallException)
{
}
}
}
}


During the "Install" event a log file is created in the user's desktop and during the "Uninstall" event the log file created is deleted. And note that the try - catch blocks catch "InstallException" and not the normal exceptions we usually "catch" (e.g. Exception).

* Its now time to get in to creating a setup project, so that this application can be deployed to other computers as well. Follow these steps.

- Right click on the solution file "HelloWorld"
- Choose Add -> New Project -> Other Project Types -> Setup and Deployment -> Setup Project
- Name the project "HelloWorldSetup"
- The project "HelloWorldSetup" is added to the solution.
- Now click on the project's name and view the toolbars in the solution explorer.




















- Here the 2nd icon is the "File System Editor", after this icon we have Registry editor, File Types, User Interface, Custom actions editor, Launch conditions editor
- Click on "File System Editor"
- You will see the following page w/ 2 panes: The left pane has the following tree structure

File System on Target Machine
Application Folder
User's Desktop
User's Program Menu

- Click on Application Folder
- Now right click on the right pane choose Add -> Project Output
- In the dialog that appears there is a drop down box w/ 2 items

* HelloWorld (our application)
* HelloWorldCustomInstaller (custom installer class)
- Choose HelloWorld, in the list box below, choose "Primary Output", click OK
- Repeat the same steps and not add the primary output of "HelloWorldCustomInstalle"
- Now create a text file called "input.txt"
- Right click in the right pane again, choose Add -> File
- The "Add Files" dialog box appears, choose the "input.txt" file
- Following is the view after all of this is done












- Now click the "Custom Actions Editor" icon in the solution explorer (refer image above - 4th icon from "File System Editor"
- You will see the following tree in this window

Custom Actions
Install
Commit
Rollback
Uninstall

- Right click on Install, choose "Add Custom Action". In the dialog box that appears choose
File System on Target Machine -> Application Folder -> Primary output from HelloWorldCustomInstaller (Active)
- Repeat the same procedure and add a custom action to Uninstall
- We are doing this because during the setup we need the custom actions defined for Install/Uninstall to be called. Without this step the custom actions won't be called

This is a screen print of the custom actions editor











That's it! You are ready!

Build the solution and the setup files will be present the "Debug" folder of the "HelloWorldSetup" project!

Leave a comment if there are any mistakes in the post and i will correct them. Also let me know your questions/ comments/ suggestions or whatever!

Happy Coding :)

Hey!

Hey!

Welcome to the .Net way! This blog is for posting a lot of things related to C#/ C#.Net that people find it almost impossible after long hours of search. Yeah, I wasted a lot of time in searching for these things and so wanted to keep these things easily accessible, so that it would also serve as a reference to me.

I have had a number of blogs over various time periods, but I never had the time to maintain them, as I am not so good in writing stories :) So I thought I will do what I am capable of!

And so, here I am!

Thanks for visiting this blog! Welcome again and watch out for the posts!