Home

Previous 20

Jan. 28th, 2008

My Daemon

Tags:

Dec. 7th, 2007

Create a setup project for a Windows Service in C#

This article describes how to create a setup project for a Windows Service application (formerly named an "NT service"). To do this, you must first create a solution that contains a simple Windows Service project that writes an entry to its application log. You then add a setup project to the solution to install the Window Service. Finally, you start the service from Microsoft Visual Studio .NET or Microsoft Visual Studio 2005 Server Explorer.

Requirements
The following list outlines the recommended hardware, software, network infrastructure, and service packs that you must have:

•    Microsoft Windows 2000 Professional, Microsoft Windows Server 2003, Microsoft Windows 2000 Server, Microsoft Windows XP Professional, or Microsoft Windows XP Server with Microsoft .NET Framework installed
•    Microsoft Visual Studio .NET Enterprise, Microsoft Visual Studio .NET Enterprise Architect, or Microsoft Visual Studio 2005

This article assumes that the user account that you use to install and to run this service has the permissions that you must have to install and to start services, and also has the permissions that you must have to access the event log.

Create a Setup Project for a Windows Service


This section describes how to create a Windows Service project, and how to use a compiled setup project to install the Windows Service.

Create a Windows Service Project
1.    Start Microsoft Visual Studio .NET or Microsoft Visual Studio 2005.
2.    On the File menu, point to New, and then click Project.
3.    Click Visual C# Projects under Project Types, and then click Windows Service under Templates.
Note In Visual Studio 2005, expand Visual C# under Project Types, click Windows, and then click Windows Service under Templates.
4.    Type LogWriterService in the Name text box, and then type C:\ in the Location text box. Click OK.
5.    In Solution Explorer, right-click Service1.cs, and then click View Code.
6.    In the OnStart event handler, replace the comments with the following code:
            EventLog.WriteEntry("My simple service started.");
7.    In Solution Explorer, double-click Service1.cs.
8.    In the Code Editor window, right-click Design View, and then click Properties
9.    In the Properties pane, click the Add Installer link.
10.    In the Properties pane for ServiceInstaller1, change the ServiceName property to Service1.
11.    In the Code Editor window in Design view, click ServiceProcessInstaller1.
12.    In the Properties pane, change the Account property to LocalSystem (The LocalService and NetworkService values are available only in Microsoft Windows XP).

Use a Compiled Setup Project to Install the Windows Service

After you complete the steps in the previous section to configure the Windows Service project, follow these steps to add a deployment project that packages the service application so that the service application can be installed:

1.    Add a new project to your LogWriterService project. To do this, follow these steps:
a.     In Solution Explorer, right-click Solution 'LogWriterService' (1 project), point to Add, and then click New Project.
b.     Click Setup and Deployment Projects under Project Types, and then click Setup Project under Templates.
c.     In the Name text box, type ServiceSetup.
d.     Type C:\ in the Location text box, and then click OK.

2.    Tell the deployment project what to package. To do this, follow these steps:
a.     In Solution Explorer, right-click ServiceSetup, point to Add, and then click Project Output
b.     In the Add Project Output Group dialog box, in the Project box, click LogWriterService
c.     Click Primary Output, and then click OK.

3.    For correct installation, add only primary output. To add the custom actions, follow these steps:
a.     In Solution Explorer, right-click ServiceSetup, point to View, and then click Custom Actions
b.     Right-click Custom Actions, and then click Add Custom Action.
c.     Click Application Folder, and then click OK.
d.     Click Primary output from LogWriterService (Active), and then click OK.
Notice that Primary output appears under Install, Commit, Rollback and Uninstall.

4.    By default, setup projects are not included in the build configuration. To build the solution, use one of the following methods:
•    Method 1
a.     Right-click LogWriterService, and then click Build.
b.     Right-click ServiceSetup, and then click Build.

•    Method 2
a.     On the Build menu, click Configuration Manager to build the whole solution.
b.     Click to select the Build check box for ServiceSetup.
c.     Press F7 to build the whole solution. When the solution is built, you have a complete installation package that is available for the service.

5.    To install the newly built service, right-click ServiceSetup, and then click Install.
6.    In the ServiceSetup dialog box, click Next three times. Notice that a progress bar appears while the service installs.
7.    When the service is installed, click Close.

Complete Code Listing
Service1.cs

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
namespace LogWriterService
{
        public class Service1 : System.ServiceProcess.ServiceBase
        {
               /// <summary>
               /// Required designer variable.
               /// </summary>
               private System.ComponentModel.Container components = null;

               public Service1()
               {
                       // The Windows.Forms Component Designer must have this call.
                       InitializeComponent();
                      // TODO: Add any initialization after the InitComponent call
               }
 
               // The main entry point for the process
               static void Main()
               {
                       System.ServiceProcess.ServiceBase[] ServicesToRun;
       
                       // More than one user service may run in the same process. To add
                       // another service to this process, change the following line to
                       // create a second service object. For example,
                       //
                       //   ServicesToRun = New System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
                       //
                       ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
 
                       System.ServiceProcess.ServiceBase.Run(ServicesToRun);
               }
 
               /// <summary>
               /// Required method for Designer support - do not modify
               /// the contents of this method with the code editor.
               /// </summary>
               private void InitializeComponent()
               {
                       components = new System.ComponentModel.Container();
                       this.ServiceName = "Service1";
               }
 
               /// <summary>
               /// Clean up any resources that are being used.
               /// </summary>
               protected override void Dispose( bool disposing )
               {
                       if( disposing )
                       {
                              if (components != null)
                               {
                                      components.Dispose();
                               }
                       }
                       base.Dispose( disposing );
               }
 
               /// <summary>
               /// Set things in motion so your service can do its work.
               /// </summary>
               protected override void OnStart(string[] args)
               {
                       EventLog.WriteEntry("My simple service started.");
               }
 
               /// <summary>
               /// Stop this service.
               /// </summary>
               protected override void OnStop()
               {
                       // TODO: Add code here to perform any tear-down necessary to stop your service.
               }
        }
}

Verify That It Works

1.    In Control Panel, double-click Administrative Tools, and then double-click Services
2.    Right-click Service1, and then click Start
3.    Use one of the following methods to verify that an event is logged in the event log:
•    Method 1
a.     In Control Panel, double-click Administrative Tools, and then double-click Event Viewer.
b.     Click Application Log in the left pane, and then locate the event log for your service from the right pane.

•    Method 2
a.     In Server Explorer, expand Servers, expand ComputerName, expand Event Logs, expand Application, and then expand Service1. Recall that Service1 is the name of the class, not the service itself. Therefore, Service1 is used as the application name. (It is beyond the scope of this article to explain how to customize the names.)
b.     Move the cursor over the log entries. The second entry from the top should read "My simple service started".


 
Tags:

Avoid losing Session data when Deleting Directories!!!!

Add the following code in Application_Start() in you Global.asax file.

//FIX disable AppDomain restart when deleting subdirectory

//This code will turn off monitoring from the root website directory.

//Monitoring of Bin, App_Themes and other folders will still be operational, so updated DLLs will still auto deploy.

System.Reflection.PropertyInfo p = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);

object o = p.GetValue(null, null);

System.Reflection.FieldInfo f = o.GetType().GetField("_dirMonSubdirs", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.IgnoreCase);

object monitor = f.GetValue(o);

System.Reflection.MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); m.Invoke(monitor, new object[] { });

Tags:

Linq to Sql Surprise Performance Hit

Here is a link that discusses the performance issues associated with using LINQ to SQL. Its shows how to use compiled queries rather than normal ones to boost performance.
Tags:

Nov. 13th, 2007

Some Links

Creating a Vista-like Menu Bar Custom Control

Basic tutorial on IKVM and Java in .NET

Oct. 19th, 2007

LIMIT in SQL

This query gives you the same ability as a LIMIT clause does in MySQL for MS SQL Server.

SELECT * FROM employee LIMIT 10,10  (-- MySQL --)
will give 10 records from 11 upto 20

In SQL you can achieve the same result by running the following query

select * from (
 select top 10 * from (
    select top 20 *
    from TABLE
   order by name asc
 ) as newtbl order by name desc
) as newtbl2 order by name asc


In this example - 20, since you start at 10 and want 10 rows (10+10=20).
Tags:

Oct. 18th, 2007

Retrieving HTTP content in .NET

Here is a good article to use the WebRequest and WebResponse object from .NET

Link : Retrieving HTTP content in .NET
Tags:

Remove duplicate values from an arraylist

I had a situation where in i had to remove duplicate values from an arraylist. I was trying a few thing with this and came up with this code which according to me if quite efficient.

public static ArrayList RemoveDuplicates(ArrayList list)
{
ArrayList ret=new ArrayList();
foreach (object obj in list) {
if (!ret.Contains(obj)) ret.Add(obj);
}
return ret;
}
Tags:

Oct. 16th, 2007

Open Source projects in ASP.NET

You can get some good open source projects from "Community Projects" from the ASP.NET website.

Link : Community Projects
Tags:

Optional Parameters in C#

I have seen Optional parameters being used in VB.net, but there is no provision to do the same in C#. We can achieve this functionality by using the Params keyword.
Params allows you to send any number of parameters to a function. But we have to be careful while using this because anything that follow s the Params keyword is taken as an argument, so we have to use the Params keyword as the last item.
We can achieve the optional feature by not sending any value to the Params.

EG:
    protected void Page_Load(object sender, EventArgs e)
    {
        PrintName("ASP.NET");
    }

    public void PrintName(params string[] values)
    {
        if (values.Length > 0)
        {
            Response.Write(values[0]);
        }
        else
        {
            Response.Write("Empty");
        }
    }
Tags:

Oct. 15th, 2007

Close browser window without confirmation using JS


To close a browser window without the confirmation dialog, just put  window.opener=self; before the window.close();
Tags:

Display Please Wait While the Page Refreshes

This can easily be achieved by using the ClientScript.GetPostBackEventReference method.

this.Btn_Upload.Attributes.Add("onclick", "this.value='Please wait..'; this.disabled=true;" + ClientScript.GetPostBackEventReference(this.Btn_Upload,""));

The GetPostBackEventReference injects the __doPostBack method and also the hidden fields that hold the event target and event arguments.

This is a useful technique when uploading large files and during the process disabling the button control. 
Tags:

Oct. 12th, 2007

"I"

The evening sun was gorgeous, I watched the splendidly perfect golden sphere slowly descending on the western horizon, behind the translucent patches of clouds.

Exactly at the same time, on the eastern horizon the glorious moon ascended, not in the crescent, but in full size and splendor. It changed its size and color as it ascended, appearing smaller with a silvery white gloss on the clear blue sky.

Why dose the moon appear running faster as it rises ans then slowing down? Maybe an illusion, just as it seems to go faster under the clouds. And why does it look so big first and then small, why change its color? What kind of illusion is this? Optical illusion? Color illusion? But the moon was so beautiful, cool and peaceful.

One can keep looking at it for hours and keep wondering about the world, the stars, the cosmos and ones own self. The 'I' is so small, so insignificant, one in a million, one individual in several billion humans on earth, a dust particle in this vast earth. And compare this earth with the size of sun, with all the suns, stars and galaxies, distant stars, millions and billions of light years away and million times bigger and brighter than our own sun. Its beyond imagination. And this 'I' is infinitesimal, really nothing. Yet, it asserts 'I', wants name, fame, wealth, power, to impress and to subjugate a handful of fellow humans for a few years, a fraction of his life span. Then this of his life span, hundred years? a trifle, compared to the age of these rocks, earth and of the universe, not even a droplet in the limitless ocean of time.

Text taken from the book "Scientists search for truth"
Tags:

Oct. 11th, 2007

Reading and Writing Excel Spreadsheets Using ADO.NET C# DbProviderFactory

After reading David Hayden`s blog today I found a very interesting tutorial on reading and writing Excel Spreadsheets and Worksheets using C# and ADO.NET.

Apparently you can insert, update, and delete data from an Excel spreadsheet as if it were a database using OleDbManaged Data Provider and C#.

Tags:

Use System.Reflection For Comparing Custom Objects


Account first = new Account("email", "007", "name");
Account second = new Account("email", "000007", "name");

For strings, integers, DateTime's, etc... using object.Equals works just fine for comparing two objects.  I can't tell you how many times I have seen someone do the following to compare two custom objects (such as the Account objects above).

public static bool IsEqualTo(Account one, Account two)
{
   bool isEqual = true;

   if (!one.EmailAddress.Equals(two.EmailAddress))
      isEqual = false;
   else if (!one.Password.Equals(two.Password))
      isEqual = false;
   else if (!one.Username.Equals(two.Username))
      isEqual = false;

   return isEqual;
}

There is a much more graceful way. Enter System.Reflection.

public static bool IsEqualTo(object one, object two)
{
   bool isEqual = true;

   foreach (PropertyInfo p in one.GetType().GetProperties())
      if (!p.GetValue(one, null).Equals(p.GetValue(two, null)))
      {
         isEqual = false;
         
         break;
      }
  
   return isEqual;
}  
Tags:

Code Snippets - Public domain source code repository

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Here is the link :
Code Snippets: Store, sort and share source code, with tag goodness
Tags:

Merging Different DataSources

Database dbSandbox = DatabaseFactory.CreateDatabase(“Sandbox”);

string sqlSandbox = “SELECT COUNT(r.RecordId) as Count, r.DepartmentId “ +
                 “FROM ExceptionRecords r “ +
                  “WHERE Year = @Year “ +
                  “GROUP BY r.DepartmentId “ +
                  “ORDER BY r.DepartmentId”;

DbCommand cmdSandbox = dbSandbox.GetSqlStringCommand(sqlSandbox);
db.AddInParameter(cmdSandbox, “Year”, DbType.Int32, 2006);

DataTable dtSandbox = dbSandbox.ExecuteDataSet(cmd).Tables[0];

Now we have a DataTable object that contains our information.  However, while we have the DepartmentId, we need the Department Name for our report.  That information is not located anywhere within the SQL Server database because the application is using our standard framework to get that information at runtime.

So, let’s add a new string column to our DataTable to hold the Department name.

dtSandbox.Columns.Add(new DataColumn(“DepartmentName”, typeof (string)));

Now, we’re ready to loop through and populate that new column.

foreach (DataRow row in dtSandbox.Rows)
{
row[“DepartmentName”] = Depts.GetDept(Convert.ToInt32(row[“DepartmentId”])).Name;
}
Tags:

Creating a Scrollable GridView Custom Control

A custom gridview control to create a scrollable gridview in asp.net 2.0. You can find the post here
Tags:

Tips for Nested Master Pages and VS 2005 Design-Time

One of the cool advanced features of the new Master Pages feature in ASP.NET 2.0 is the ability to nest them.  For example, you could define a top-level master-page called “MainMaster.master” that defines a common logo header and footer, and defines a content-placeholder for the page called “content”.  You could then define two sub-masters beneath it – one that provides a two-column layout model for the content (“TwoColumnMaster.master”), and one that provides a three-column layout model (“ThreeColumnMaster.master”).  These two nested-master pages could then use the MainMaster.master file as the root master, and only adjust the layout within its content section (each would fill in the "content" placeholder and in turn add their own content-placeholders for sub-pages within it).  The benefit of this approach is that if a designer ever changed the logo or top-level design of the site, they only have to update one file (MainMaster.master) and then have every page on the site automatically pick it up regardless of what master file they were based on.

This nested model is pretty cool and powerful, and allows arbitrary levels of nesting.  The only downside is that VS 2005 only supports nested master page editing in source-view, and doesn’t support it in the WYWSIWYG designer (note: obviously it does support editing them when the master-pages are not nested).

There is a cool tip/trick, though, that will allow you to load a design-surface for a page that uses nested master-pages.  This will allow you to use all of the control-designers and smart-tasks in design-view for the page (for example: to perform data-binding, auto-format things, and use any of the control wizards), and not have to change any-code to test it at runtime.

The tip/trick works by adding a base-page class to your project or solution that defines a new property called “RuntimeMasterPageFile” of type string.  The base-class then overrides the page’s “OnPreInit” method and uses this property to set the Page object’s MasterPageFile at runtime:

public class BasePage : System.Web.UI.Page
{
    private string runtimeMasterPageFile;
    public string RuntimeMasterPageFile
    {
        get
        {
            return runtimeMasterPageFile;
        }
        set
        {
            runtimeMasterPageFile = value;
        }
    }
 
    protected override void OnPreInit(EventArgs e)
    {
        if (runtimeMasterPageFile != null)
        {
            this.MasterPageFile = runtimeMasterPageFile;
        }
        base.OnPreInit(e);
    }
}

Once a code-behind class derives from this base class, it becomes possible for a developer to set this “RuntimeMasterPageFile” property in the .aspx file’s <%@ Page %> directive (note: the CodeFileBaseClass also needs to be set to the base class to enable this):

<%@ Page Language="C#"
MasterPageFile="~/Test.master" RuntimeMasterPageFile="SubMaster.master" CodeFileBaseClass="BasePage"
AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="_Default"
Title="My Page Title" %>

You’ll notice that the above page now has two master-page file directives – the usual “MasterPageFile” directive that VS will use at design-time, and then the custom RuntimeMasterPageFile directive that will override this at runtime.  What this allows you to do is point the page at a “test.master” file at design-time that is a single-nested page with contentplaceholder controls that match the names in your nested master.  You can then switch to design-view and edit the content and all controls on your page.  When you run the page, though, it will use the nested “submaster.master” (or any other master page you specify) to run.

Update: Brian also pointed out to me that you can leave the MasterPageFile attribute value as "" and the designer will then automatically render a test master page that just lists all of the content-placeholder controls in editable regions.  This might allow you to avoid having to define a test master page for your site.

Here is a simple sample that shows all this working (you can switch the default.aspx page to use either the submaster.master or submaster2.master page that is based on mainmaster.master).
 

Hope this helps and is useful,
Scott
Tags:

Basic C# Predicate Generic Delegate Example

Predicate Generic Delegates are very useful in the 2.0 Framework.  I first came across Predicate Generic Delegates a couple of months ago when creating a sequencing algorithm for a large project.  Part of the sequencing involved enumerating List<T>'s and removing / replacing items that met / failed to meet certain criteria.  First I tried simply enumerating the collection, analyzing the data, and removing / replacing said item.  It looked sort of like the following basic "Hello World" example.

List<string> list = new List<string>();
list.Add("one");
list.Add("two");
list.Add("three");
list.Add("four");
list.Add("fivehundredandfiftyfive");

foreach (string s in list)
   if (string.Compare(s, "three") == 0)
      list.Remove(s); // InvalidOperationException

The InvalidOperationException is caused (in this case) when the call to IEnumerator.MoveNext is made. The reason the exception is thrown is because the collection objects were modified after the enumerator was created.

Collection was modified; enumeration operation may not execute

There is a way around this that is much safer and, in my opinion, much more elegant.  In using the same string collection above, let's say that you want to remove any items that are "three".  The Predicate delegate returns a bool reflecting if certain criteria was met. Here is an example of a Predicate using an anonymous delegate.

list.RemoveAll(delegate(string s)
                   {
                      return string.Compare(s, "three") == 0;
                   });

You can also create named methods instead of anonymous delegates. I created 2 simple ones for use with the original collection of strings.

static bool RemoveThree(string s)
{
   return string.Compare(s, "three") == 0;
}

static bool RemoveLongLength(string s)
{
   return s.Length > 4;
}

To use these methods is as simple as:

list.RemoveAll(RemoveThree);
list.RemoveAll(RemoveLongLength);

Predicates can get more useful once you understand the basic premise. These examples are very "Hello World"-ey but definitely convey the usefulness.
Tags:

Previous 20

January 2008

S M T W T F S
  12345
6789101112
13141516171819
20212223242526
2728293031  

Advertisement

Syndicate

RSS Atom
Powered by LiveJournal.com