Saturday, February 23, 2013

Dropkick: A custom dropdown jquery plugin

In one of my projects we were working on rewriting an existing application from Silver light platform to HTML5. As part of this we had to come up with a solution for all the dropdowns to look exactly as in Silverlight version. But we were not able customize the dropdowns with html select control to look exactly as in Silverlight version.

I did lot of research in Google, found some Jquery/javascript plugins and approaches and explored all of them. After trying with most of the approaches and plugins I have felt that that the Jquery plugin DropKick well suits for my requirement. You can download this plugin at the following url.
http://jamielottering.github.com/DropKick/

 How to use dropkick in your code?
1. Write the markup code for regular html dropdown as shown below
<select id="ddlCountry">
 <option value="1">India</option>
 <option value="2">USA</option>
 <option value="3">UK</option>
 <option value="4">Russia</option>
</select>
2. Add the dropkick javascript reference to your page in header section
3. Dropkick works for Jquery so you must also make sure you added reference to Jquery
4. Apply dropkick effect to your regular dropdown control as shown below
     $('#ddlCountry').dropkick();
5. You might want to handle the change event for the dropkick, in that case you can write the following code snippet.
     $('.ddlCountry').dropkick({
         change: function (value, label) {
         alert('Your selection: ' + label + ':' + value);
     }
     });
6. You also need to add the reference to dropkick css file to make sure you are getting the custom styles applied. And also you can edit the css to customize style effects for your specific requirement.

You can see the sample customised dropdown by dropkick below:



You can find more information at http://jamielottering.github.com/DropKick/

Thursday, May 19, 2011

Sql user defined function to replace HTML text without disturbing HTML elements

You may find many articles on how to strip HTML in SQL. But we rarely find articles on doing replace functionality without disturbing the HTML tags in SQL. This is a very useful requirement where we store content in HTML format in the database.

When I did Google search on this I found some articles on how to strip HTML from SQL and one of those articles inspired me to write a user defined function which does replace within the text and preserves the HTML as it is.

The below is the user defined function written by me as inspired from the article SQL SERVER – 2005 – UDF – User Defined Function to Strip HTML – Parse HTML – No Regular Expression

CREATE FUNCTION [dbo].[udf_ReplaceHTMLContent]
(
@HTMLText VARCHAR(MAX),
@Find VARCHAR(MAX),
@Replace VARCHAR(MAX)
)

RETURNS VARCHAR(MAX)
AS
BEGIN

DECLARE @Start INT
DECLARE @End INT
DECLARE @Length INT
DECLARE @UpdatedHTMLText VARCHAR(MAX)

SET @UpdatedHTMLText = ''
SET @Start = CHARINDEX('<',@HTMLText)
SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
SET @Length = (@End - @Start) + 1


WHILE @Start > 0
AND @End > 0
AND @Length > 0

BEGIN

SET @UpdatedHTMLText = @UpdatedHTMLText + Replace(SUBSTRING(@HTMLText, 0, @Start), @Find, @Replace)

SET @UpdatedHTMLText = @UpdatedHTMLText + SUBSTRING(@HTMLText, @Start,@Length)

SET @HTMLText = STUFF(@HTMLText,1, @Start + @Length - 1,'')

SET @Start = CHARINDEX('<',@HTMLText)

SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))

SET @Length = (@End - @Start) + 1

END


if @UpdatedHTMLText = ''

SET @UpdatedHTMLText = @UpdatedHTMLText + Replace(@HTMLText, @Find, @Replace)


RETURN LTRIM(RTRIM(@UpdatedHTMLText))

END

kick it on DotNetKicks.com

Saturday, December 4, 2010

SQL Server 2008 - MERGE statement

SQL server 2008 has introduced a new feature to merge two tables. It lets you write a single SQL statement to insert, update and delete the records in the target table based on some conditions. It is very useful where you need to sync two tables. It avoids writing separate statements and logic for insert, update and delete.

It's syntax is very simple and straight forward:

MERGE <target_table> [AS table_alias]

USING <table_source> [AS table_alias]

ON <search_condition>

[WHEN MATCHED [AND clause_search_condition]

THEN <merge_matched> ]

[WHEN NOT MATCHED [BY TARGET] [AND clause_search_condition]

THEN <merge_not_matched> ]

[WHEN NOT MATCHED BY SOURCE [AND clause_search_condition]

THEN <merge_ matched> ];

Let me write an example and explain how MERGE works.

Let's say we have two tables named Books_Source and Books_Target which need to be synced periodically. And at one instance

The table Books_Source contains:

BookID BookName Quantity

1 "Learn ASP.Net" 3

3 "SQL tips" 5

4 "Complete Reference of JAVA" 2


The table Books_Target contains:

BookID BookName Quantity

1 "Learn ASP.Net" 2

2 "Learn XML" 4

4 "Complete Reference of JAVA" 4

To merge the above tables our MERGE statement goes like this:

MERGE Books_Target AS t

USING Books_Source AS s

ON t.BookID = s.BookID

WHEN MATCHED AND s.Quantity != t.Qunatity

THEN UPDATE SET t.Quantity = s.Quantity

WHEN NOT MATCHED BY TARGET

THEN INSERT(BookID, BookName, Quantity) VALUES(s.BookID, s.BookName, s.Quantity)

WHEN NOT MATCHED BY SOURCE

THEN DELETE;

  • As you can see in the above code, insert, update and delete actions happen in a single MERGE statement. It lets us add our own conditions to merge conflicts and our own merge actions to take place.
  • In this example we have written update statement where the records exist in both tables but the column Quantity is different. In this case I want to update only when quantity gets changed in Order_Source table.
  • Similarly we have written insert statement where the records exist in source table but not in target table. Here we have not added any additional condition because we wanted to insert all those don't exist in target table.
  • In the same way we have written DELETE statement where the records exist in target table but not in the source table. In this case we don't want the records those are not in source table.
  • MERGE statement is more efficient than separate statements for insert, update and delete operation to merge tables

The final result after the execution of above statement is:

BookID BookName Quantity
1 "Learn ASP.Net" 3
3 "SQL tips" 5
4 "Complete Reference of JAVA" 2

Wednesday, December 1, 2010

Jquery language translation plugin

Many of us know that Google is providing an online tool to translate from one language to another language. Of course this translation may not be accurate but the percentage of accuracy varies from language to language based on the language structure. Basically it translates word by word. This tool is really helpful to understand statements in different languages.

But if we have a our own website which is completely in English and there are users which don't know English and they want to know about our site then it is a problem. In this case they may not know that there is a tool which translates text in English to their native language or they don't have time to translate each and every page or they may not be interested to translate at all. Then they may simply skip reading and ignore your site.

To avoid these kind of risks Google also provided us translator API which lets us develop our website to translate from one language to another language. To know more about Google translator please go through the link http://code.google.com/apis/language/translate/v1/getting_started.html. It is very easy to integrate with our website by following this link.

But the major problem with the Google translate API is its limitation with the length of the text we pass to translator. It does not translate if we pass text with more than 5000 characters. It is only helpful where we need to translate a portion of our web page and that too with less than 5000 characters. If we have to translate the complete web page then we need to write complex logic to split the html code into 5000 character sets and translate thru API and then merge the results. This is really paining.

To solve these problems we have Jquery plugin for translator. You can download this at http://jquery-translate.googlecode.com/files/jquery.translate-1.3.9.min.js. It internally uses Google translator API and applies the above discussed logic and gives us the complete translated html. This takes the complex part and leave us a simplest part to translate complete web page.

The below code will do complete translation of your web page from source language to destination language

$('body').translate( srcLang, destLang );

Eg: $('body').translate( "en", "es"); //translates text from English to Spanish

But to get it working you also need to make sure you have Jquery along with this plugin.

You can also try playing with this plugin and see how it works. Please take a look at http://jsbin.com/emufo/edit and make any changes you want and preview the behavior by clicking Preview link on top left corner.

kick it on DotNetKicks.com

Wednesday, October 13, 2010

Online tool Url Decoder / Encoder

I have come across a need for url decoding as I got a link which was url encoded. And I have found a useful online tool which lets me enter a url encoded text and get the url decoded text. This also has functionality to url encode the given text. You may url encode as many times you want, but you need to decode the encoded text as number of times it was encoded.

I have found this as very useful for my purpose. And this works completely on client side. Please take a look at it.

http://meyerweb.com/eric/tools/dencoder/


Tuesday, October 5, 2010

Sitefinity performance factor - script manager

If you are using sitefinity to build any website then while adding sitefinity inbuilt controls such as menu you will be forced to write Script Manager in the template (master file). If you use script manager anywhere in the website it will load lot of unwanted javascript files along with the target page. It is better we don’t write script manager in any website unless we are building a complex website which needs ajax framework and other javascript libraries. I recommend you manually add menu and menu items in code rather than using sitefinity navigation controls and for ajax calls please use jquery to make server requests. Not having script manager will reduce the amount of javascript resources to a siginificant number.

And on our current project waypoint, we were not using any of the sitefinity inbuilt controls and not ajax framework too. But somehow we were having script manager written in the master file. And due to this it was loading around 350 KB javascript files which were never used by the site. And after I realised, I have removed the script manager tag and noticed a big surprise. The site is perfectly working without any issues and the overall page size was reduced from 500KB to 150KB (Avoiding 350KB for unwanted javascript files).
So I would strongly recommend you to avoid writing Script Manager in your websites and find the alternate solution for that.

kick it on DotNetKicks.com

Friday, July 9, 2010

Changing cookie expiration time

Changing cookie expiration time is not straight forward. It is not as easy as setting the http cookie's property Expires to required value as shown below.

HttpContxt.Response.Cookies["UserID"].Expires = DateTime.Now.AddMinutes(20);

I was using the above line of code in one of my projects as I wanted to make sure the cookie's expiration time gets updated for every user action. I added that line of code in the method where I check for authentication in each page request. But I was wondering with it's strange behavior as it is crashing the web page to load. I did spend some time on fixing it but got no luck.

After a while I got the solution which is explained in an MSDN article http://msdn.microsoft.com/en-us/library/ms178194.aspx. As explained the article, we must recreate the cookie with value and expiration time as we normally do when adding a cookie. So changing cookie is not at all different from creating a cookie in the browser. Finally I changed my code to recreate the cookie where updating cookie expiration time is needed. And it is perfectly working fine.

The correct code it worked was:

HttpContxt.Response.Cookies["UserID"].Value= UserID;
HttpContxt.Response.Cookies["UserID"].Expires = DateTime.Now.AddMinutes(20);

kick it on DotNetKicks.com

Tuesday, June 1, 2010

Installing Red5 on windows

Installing Red5 is easy as explained below.
  1. Before installing Red5 we need to make sure java is installed on the target machine. Because Red5 needs to java.
  2. If java is not installed then download the latest version of java and install it.
  3. Make sure the JAVA_HOME environment variable is set to the java installed root directory.
  4. To set the environment variable, right click "My Computer" in start menu/desktop and go to properties. Go to "Advanced" tab and there you will see a button named "environment variables" at bottom. Clicking it will open a dialog which will let you add your own variable. Click "New" button in the top section i.e., User variables and int the popup eneter JAVA_HOME for variable name and root directory of the java for variabl value as shown below
  5. Now you are ready to install the Red5. Download the latest version of Red5 from http://code.google.com/p/red5/ and install it.
  6. During the installation you may be asked to enter your ip address and port number (for version Red5 0.9.0 Final) to run the http protocol for Red5. You can enter your ip address or the dns name. But you must remember this as this is the one you need to use always. If you enter ip address during installation and use dns name in application then it will not work. You should use the one what you entered during installation. I don't know the reason but I experienced this. But if you are not asked to enter IP address (for version Red5 0.8.0 Final) then there will be no issues with the dns name to access the server. In this case the default port number is 8080.
  7. After Red5 installation is complete then you need to start the service.
  8. You can verify whether the Red5 is running and working fine by browsing to http://ip_address:port_number in any browser. The ip_address and port_numbers should be same as the ones entered during installation. Or the dns name and default port number 8080 will work work in the second case explained in the above step. If the server is working fine then you will be able to the server's home page which will talk about some demos, etc.

Audio recorder in website

One of our clients had a requirement having an audio recorder to be integrated with his website. He wanted record and playback features. This was challenging job to me and I did lot of research in this and finaly found one third party tool which serves exactly. The tool was FLV Audio Recorder developed by AVChat Software. You can get more details in it's website http://flvar.com/.

But this needs one the below media servers. Media servers are same as conventional web servers but they only deal with storing and streaming of videos, audios and images. Media servers use a different protocal called RTMP to accept the video/audio requests same as HTTP is used to accept various kinds of requests.

  1. Red5
  2. FMIS
  3. Wowza

The 1st media server listed above, Red5 is available for free and rest are expensive. I was interested to use Red5 as it was freely available.

To integrate the audio recorder in website I did the following:

  1. I got the 30-day trial version of FLV audio recorder. We need to request for trial version by filling a small form and they will email us with the download details of trial product. This will include a license key which needs to be entered in the product.
  2. I unzipped the archive and placed in some folder. And I created a virtual directory in IIS pointing to this folder. So I have verified all the files in audio recorder are accessed by webserver.
  3. I installed the Red5 media server as explained in the post http://cherupally.blogspot.com/2010/06/installing-red5-on-windows.html.
  4. I followed the installation instructions provided in http://flvar.com/documentation.
  5. I entered my license key in audiorecorder.properties file as instructed.
  6. I changed the avc_settings.php file to point to my red5 server.
  7. That's it. I am done with the integrating stuff. When I opened the audiorecorder-api.html file in browser I have noticed the audio recorder rendered in flash and functioning well.
  8. After completing all steps you may not get the audio recorder working until you reboot the machine. I had to reboot my machine to see the recorder working.



kick it on DotNetKicks.com

Friday, February 12, 2010

Bubbling up events from user control to parent page/control

It is a good practice to use user controls when same controls are repeated in many pages. But there are some cases where the user control has some controls which generate events and those need to be handled by the containing page/user control. For eample there is a button control in the user control and you want to do something in parent page/control when the button in user control is clicked. In this case

1.You need to define an event handler in user conrol as shown below.

public partial class UC_Pagination : System.Web.UI.UserControl
{
...
...

public event EventHandler PageIndexChanged;
...
...
...
}


2. You need to call the event explicitly in the user control's implementation of the event handler of button click as shown here

public partial class UC_Pagination : System.Web.UI.UserControl
{
...
...
protected void Button1_Click(object sender, EventArgs e)
{
...
...
PageIndexChanged(sender, e);
...
...
}
...
...
...
}

3. Implement the event handler bubbled up by user control in the parent page/control in its own way as usual (shown below).


public partial class Coaches : System.Web.UI.Page
{
...
...
protected void ucPaginationPageIndexChanged(object sender, EventArgs e)
{
...
...
...
}

...
...
}

kick it on DotNetKicks.com
Shout it

How to implement paging with LINQ

Before going into how paging is implemented with LINQ, Let's discuss the need for implementing paging.

With large amounts of data, it is not a good practice to pull all records from database when you are showing a fraction of them in one page. It is always recommended to use data on demand approach. When you want to show first 20 records out of the search results then you must get the first 20 records from database and discard the rest. Similarly when you want to show next 20 records of the search results then you need to get the next 20 records from database and discard the rest. This is nothing but called paging.

LINQ has made the paging solution very simple as shown below example.

public List<Client>
GetAllClients(bool? isActive, int pageNumber, int pageSize, out int totalPages)
{
//Actual query which returns large data
var query = dataContext.Clients.Where(p => isActive == null || p.IsActive == isActive);

//Calculating total number of pages by taking ceiling number of the fractional value
totalPages = (int)Math.Ceiling((decimal)query.Count() / (decimal)pageSize);

//Paging logic goes here
return query.Skip((pageNumber - 1)*pageSize).Take(pageSize).ToList();
}


The parameters which play major role in paging are page number and page size. The page number is to identify the page of which the records to be returned. And the page size to identify the number of records to be returned. And there is another out parameter totalPages which is used to hold the total number of pages available within the data returned. This is needed to show the number of pages to the user and also useful in the logic which enables/disables page navigation.
Shout it
kick it on DotNetKicks.com

Saturday, December 19, 2009

How to get Sql server 2008 intellisense working for schema changes

The new feature "intellisense" added in sql server 2008 is making my life easier. And I am enjoying this feature a lot. But I noticed many times that when we make any changes to DB schema like creating / modifying database objects (tables, sprocs, ...) we don't notice the schema changes in intellisense in the same session. This made me too bad and many times I cursed Microsoft for this inclomplete feature. But after making some research on this, I have found the solution to get intellisense for new schema changes in current session.

Actually what happens when you connect to sql server 2008 using sql server management studio is, it queries for the current database schema and saves it somewhere. And It uses this schema information for showing the intellisense when the user is writing queries. But when we create/update the sql objects (sprocs, tables, views, ...) these won't be updated and the intellisense is pulled from old schema. That's why we don't notice the schema changes in intellisense unless we explicitly refresh the cache. In order to get new chema changes we must clear the intellisense cache.

To clear the intellisense cache we need to click Edit -> Intellisense -> RefreshLocalCache in sql server 2008 management studio as shown in below screen.


Shout it
kick it on DotNetKicks.com

Sunday, November 8, 2009

Installing IIS 7.0 on Windows Server 2008

Let me explain my experience on installing IIS 7.0 on windows server 2008. I had a tough time to find a way to install IIS 7.0 on windows server 2008. I thought that it would be same as installing IIS 6.0 on windows server 2003 by going to "control panel" -> "Add or Remove Programs" -> "Add/Remove Windows Components" and install IIS. But I couldn't find this in windows server 2008. After doing a long research I found a link which helped me.

I followed the below steps to install IIS 7.0 on windows server 2008.
  1. Go to "Start" -> "Administrative tools" -> "Service Manager".
  2. Right click the node "Roles" in the "Service Manager" window and click on "Add Roles".
  3. Follow the wizard.
  4. Select web server(IIS) in 2nd step of the wizard.
  5. You might get the following popup immediately. If you get this please click "Add Required Role Services".
  6. You follow the wizard until you get the below step.
  7. Follow the wizard until the final step.
  8. That's it. You are done with installing IIS 7.0 on windows server 2008.
  9. If you face any problems please follow the below link. It has detailed step by step guidelines to install the IIS 7.0 on windows server 2008. http://learn.iis.net/page.aspx/29/installing-iis-70-on-windows-server-2008/

kick it on DotNetKicks.com
Shout it

Thursday, November 5, 2009

C# 4.0 new features: Named and Optional arguments

Microsoft has introduced few new features in C# 4.0. I would like to discuss the below listed new features in this post.

1. Optional arguments
2. Named arguments

Optional arguments: This feature allows you to omit arguments when calling methods. This is done by defining a method with assigning default values to parameters. For better understanding, let's take a look at the below example.

We define a method called "SomeMethod" by proving default values to two of its parameters as shown.

public void SomeMethod(int a, int b = 50, int c = 100);

Now this method can be called in different ways as shown below.

SomeMethod(10, 30, 50); // This is a normal call as 3 arguments were passed

SomeMethod(10, 30); // This call is omitting parameter "c". This call is equalant to SomeMethod(10, 30, 100)

SomeMethod(10); // This call is omitting both "b" and "c". This call is equalant to SomeMethod(10, 50, 100)

As you see, we can omit any number of consecutive parameters from right to left. In the above examples we omitted parameter "c" alone and parameters "b" and "c" together. Do you see a way to omit the parameter "b" in the above example? If you call the method "SomeMethod" by passing one argument as shown below, the compiler assumes that the argument passed was for the first parameter i.e, "a". So we need a way to tell the compiler that this argument was passed to a particular parameter, in this case it is "b". This requirement was fulfilled by c# 4.0's another new feature called "Named Arguments". Let's take a closer look at this feature.

Named Arguments: This feature allows you to pass the arguments by the corresponding parameter names.

For example you can pass the arguments by name as shown below.
SomeMethod(a:10, b:30, c:50);

By this feature, we don't need to pass the arguments in the order of parameters defined in the method. We can rewrite the above method call as shown below.
SomeMethod(c:50, b:30, a:10);

And you can solve the above discussed problem (omitting the middle parameter "b") as shown below.

SomeMethod(a:10, c:50); // This call Omits the parameter "b".

Optional and Named arguments features can also be applied to constructors. This feature is mainly useful where you have methods that have many number of parameters. Because it is very difficult to call a method by passing the parameters in same order as the method was defined. There are many possibilities to make mistakes in the order. So, having named parameters and the ability to pass parameters in any order by explicitly referring the parameter names will make our life easier.

kick it on DotNetKicks.com
Shout it

Wednesday, October 21, 2009

Use of "for" attribute of html label

I have noticed many of the html programmers that, they use an attribute called "for" when writing a label tag. And the attribute value is exactly same as the corresponding html input control such as text box, check box, drop down,... But I never tried to know the actual use of this attribute.

Very recently, I have searched in Google to know the use of it. Now I have come to know that, the "for" attribute of label binds the label with the corresponding control. Binding in the sense, when the user clicks on the label it toggles the corresponding control (control id passed as value for "for" attribute). This way the "for" attribute is used for the label. Now onwards I am going to make a good practice of using "for" attribute of the label control.

Let's see an example of the usage of the "for" attribute of label control

<label for="FirstName">First Name:</label>

<input id="FirstName" type="text">


The above code is rendered as shown below. You can test this behavior by clicking on the label "First Name:". You can notice the text box focused.


Friday, September 25, 2009

Easy way to strip time part in sql date time

Most of the times we wouldn't want the time part of the dates to be stored or retrieved when dealing with only days. But the data type "datetime" in sql always includes the time even though you don't want it. There is no other data type in sql to store or retrieve the date without time. In this case we need to strip the time part from the date and store the remaining in database. To do this favor, I have come up with the below sql code which strips the time part from the date time.

declare @date datetime;
set @date = getdate();
select cast(convert(varchar, @date, 101) as datetime) --Strips time element from the date time

The above code will work like this:
If you have the date time 25/09/2009 12:36:40:654 then this will be converted as
25/09/2009 00:00:00:000

kick it on DotNetKicks.com
Shout it

Tuesday, September 22, 2009

Find common elements in c# generic list

The following code demonstrates how to get the common elements in
given 2 lists using Intersect method of System.Collections.Generic.List.


using
System;
using System.Linq;

namespace ConsoleApplication1
{
static class Program
{
static void Main(string[] args)
{
int[] elementSet1 = { 5, 1, 6, 3, 8 };
int[] elementSet2 = { 3, 7, 8, 6, 5 };

foreach (int element in elementSet1.Intersect(
elementSet2))
{
Console.WriteLine(element);
}
Console.Read();
}
}
}


kick it on DotNetKicks.com

How to find an element in c# Generic List

The following sample code demonstrates you how to find a matching element in the object list.

Let's say we have an object called Person with public properties PersonID, Name, Age, Gender as defined below.

using System.Collections.Generic.List;

public class Person
{
public int PersonID {get; set;}
public string Name {get; set;}
public int Age {get; set;}
public bool Gender {get; set;}
}

class program
{
public static void Main(string[] args)
{
// Let's say we have a method defined as dbAccess.GetPersons() to
//return all the records from Person table and populates the
//list object "persons" as shown below.
List persons = dbAccess.GetPersons();

int personIDToFind = 1234;
//Find person in persons list by PersonID using predicate
//"p=>p.PersonID == personIDToFind"
Person personByFindOperation = persons.Find( p=>p.PersonID == personIDToFind );

string personName = "Kiran"
//Find person in persons list by Name using predicate
//"p=>p.Name == personName"
Person personByFindOperation2 = persons.Find( p=>p.Name == personName );

}
}

Note: The Find method of List returns the first occurrence of the exact match within the entire System.Collections.Generic.List.


kick it on DotNetKicks.com
Shout it

Thursday, September 10, 2009

How to create a windows service in dot net framework

Windows service is an application which always runs in background. We can view all the installed windows services in ControlPanel/Administrativetools/Services. Sql server, Oracle, ... are the good examples of windows service.

Using visual studio it is very easy to create windows service. Please follow the below steps to create a windows service.
  1. Open visual studio and create a new project of template "Windows Service" as shown below
  2. After you click OK in the above step you will see a new solution named "WindowsService1" created as shown below.
  3. Right click on the above screen and click "Add Installer". This will create an installer component which helps us in installing this service.
  4. You can notice a new component "ProjectInstaller.cs" added and opened as shown below. It has 2 controls "ServiceProcessInstaller1" and "ServiceInstaller1".
  5. You can set whether this service is manual, automatic, or disabled by changing the StartType property of "ServiceInstaller1" (Right click -> Properties).
  6. Change the "ServiceProcessInstaller1"'s property "Account" to "LocalSystem"
  7. Right click on Service1.cs in solution explorer and click "View Code"
  8. In code you will see the service event handlers "OnStart", "OnStop".
  9. Write code that initiates a thread in OnStart event handler.
  10. Write code that stops execution of the thread in OnStop event handler.
  11. Please see below for sample code
  12. Build the solution. You have the windows service built ready.
  13. But until we install this service we cannot see it is running or not.
  14. To install this service you need to open the Visual Studio 2005/2008 Command prompt in Start->Visual Studio 2005/2008->Visual Studio Tools
  15. Run the command : InstallUtil.exe Windows_Service_EXE_Full_Path
  16. Here Windows_Service_EXE_Full_Path is the exe generated for the WindowsService1 project. Let's say the full path of the exe is C:/WindowsService1/Bin/Debug/WindowsService1.exe then our command to install it would be like this.
  17. InstallUtil.exe C:/WindowsService1/Bin/Debug/WindowsService1.exe
  18. If the above command is successful then you will notice a new service named "Service1" is shown in Control Panel->Administrative Tools/Services
  19. To uninstall a service, InstallUtil.exe -u C:/WindowsService1/Bin/Debug/WindowsService1.exe
  20. To make the life easier to install/uninstall windows services we can create a setup project which will let people easily install/uninstall with a wizard Please read this link. http://cherupally.blogspot.com/2009/09/how-to-create-setup-project-to-install.html

kick it on DotNetKicks.com
Shout it

How to create a setup project to install windows services

This post assumes that you have knowledge on windows services and how to create a windows service using visual studio. People who don't know how to create windows service please learn here.

Please follow below steps to create a setup project
1. Create a visual studio solution with a project of type Windows Service as explained in http://cherupally.blogspot.com/2009/09/how-to-create-windows-service-in-dot.html

2. Add a new project of type "Setup Project" to the solution as shown below


2. Once you click on OK button in the above step, you will see the screen below. There you notice a new project named "Setup1" is added.


3. Now right click on Setup1 project in the solution and click "Add Project Output" as shown below.

4. In "Add Project Output Group" dialog box shown below, select the windows service project in the drop down and click OK.


5. The above 4 steps are only to copy all the assemblies to specifies installation folder. Setup will not install the services in the system. To tell the setup to install services we must add custom actions. To open the custom actions window right click "Setup1" project in solution explorer and click View->Custom Actions as shown below.


6. You will see the Custom Actions tab opened like this.


7. Right click on "Custom Actions" and click "Add Custom Action".

8. That will open a dialog box which lets you choose the items from "Application Folder". Select "Primary Output From WindowsService1" in "ApplicationFolder" and click OK.


9. The above step will add this custom action to all sub folders "Install", "Commit", "Rollback", "Uninstall". Finally you will see the screen like this.


10. Build the "Setup1" project. Now you are ready to use this setup project to install/uninstall windows services. Take the setup build from WindowsService1\Setup1\Debug and use it to install/uninstall when needed.
kick it on DotNetKicks.com
Shout it