The New LinkedList Class and Iterator Class in C#

we need a header field and a constructor method to instantiate the list.

public class LinkedList()
{
private Node header;
public LinkedList()
{

header = new Node("header");
}
public bool IsEmpty() {
return (header.Link == null);
}
public Node GetFirst() {
return header;
}
public void ShowList() {
Node current = header.Link;
while (!(current == null)) {
Console.WriteLine(current.Element);
current = current.Link;
}
}
}


Demonstrating the Iterator Class

Using the Iterator class, it’s easy to write an interactive program to move through a linked list. This also gives us a chance to put all the code for both the Iterator class and the LinkedList class in one place.

using System;
public class Node
{
public Object Element;
public Node Link;
public Node()
{
Element = null;
Link = null;
}
public Node(Object theElement)
{
Element = theElement;
Link = null;
}
}
public class InsertBeforeHeaderException : System.
ApplicationException
{
public InsertBeforeHeaderException(string message) :
base(message)
{
}
}
public class LinkedList
{
private Node header;
public LinkedList()
{
header = new Node("header");
}
public bool IsEmpty()
{
return (header.Link == null);
}
public Node GetFirst()
{
return header;
}
public void ShowList()
{
Node current = header.Link;
while (!(current == null))
{
Console.WriteLine(current.Element);
current = current.Link;
}
}
}
public class ListIter
{
private Node current;
private Node previous;
LinkedList theList;
public ListIter(LinkedList list)
{
theList = list;
current = theList.GetFirst();
previous = null;
}
public void NextLink()
{
previous = current;
current = current.Link;
}
public Node GetCurrent()
{
return current;
}
public void InsertBefore(Object theElement)
{
Node newNode = new Node(theElement);
if (previous.Link == null)
throw new InsertBeforeHeaderException
("Can't insert here.");
else {
newNode.Link = previous.Link;
previous.Link = newNode;
current = newNode;
}
}
public void InsertAfter(Object theElement)
{
Node newNode = new Node(theElement);
newNode.Link = current.Link;
current.Link = newNode;
NextLink();
}
public void Remove()
{
previous.Link = current.Link;
}
public void Reset()
{

current = theList.GetFirst();
previous = null;
}
public bool AtEnd() {
return (current.Link == null);
}
}
class chapter
{
static void Main()
{
LinkedList MyList = new LinkedList();
ListIter iter = new ListIter(MyList);
string choice, value;
try
{
iter.InsertAfter("David");
iter.InsertAfter("Mike");
iter.InsertAfter("Raymond");
iter.InsertAfter("Bernica");
iter.InsertAfter("Jennifer");
iter.InsertBefore("Donnie");
iter.InsertAfter("Michael");
iter.InsertBefore("Terrill");
iter.InsertBefore("Mayo");
iter.InsertBefore("Clayton");
while (true)
{
Console.WriteLine("(n) Move to next node");
Console.WriteLine("(g)Get value in current node");
Console.WriteLine("(r) Reset iterator");
Console.WriteLine("(s) Show complete list");
Console.WriteLine("(a) Insert after");
Console.WriteLine("(b) Insert before");
Console.WriteLine("(c) Clear the screen");
Console.WriteLine("(x) Exit");
Console.WriteLine();
Console.Write("Enter your choice: ");
choice = Console.ReadLine();
choice = choice.ToLower();
char[] onechar = choice.ToCharArray();
switch(onechar[0])
{
case 'n' :
if (!(MyList.IsEmpty()) &&
(!(iter.AtEnd())))
iter.NextLink();
else
Console.WriteLine("Can' move to
next link.");
break;
case 'g' :
if (!(MyList.IsEmpty()))
Console.WriteLine("Element: " +
iter.GetCurrent().Element);
else
Console.WriteLine ("List is empty.");
break;
case 'r' :
iter.Reset();
break;
case 's' :
if (!(MyList.IsEmpty()))
MyList.ShowList();
else
Console.WriteLine("List is empty.");
break;
case 'a' :
Console.WriteLine();
Console.Write("Enter value to insert:");
value = Console.ReadLine();
iter.InsertAfter(value);
break;
case 'b' :
Console.WriteLine();
Console.Write("Enter value to insert:");
value = Console.ReadLine();
iter.InsertBefore(value);
break;
case 'c' :
// clear the screen
break;
case 'x' :
// end of program
break;
}
}
}
catch (InsertBeforeHeaderException e)
{
Console.WriteLine(e.Message);
}
}
}

GENERIC LINKED LIST CLASS AND THE GENERIC NODE CLASS
The System.Collections.Generic namespace provides two generic classes for building linked lists: the LinkedList class and the LinkedListNode class. The Node class provides two data fields for storing a value and a link, whereas the LinkedList class implements a doubly linked list with methods for inserting before a node as well as inserting after a node. The class also provides method for removing nodes, finding the first and last nodes in the linked list, as well as other useful methods.

Generic Linked List Example

LinkedListNode node1 = new LinkedListNode_(“Raymond");
LinkedList names = new LinkedList();

From here, it’s just a matter of using the classes to build and use a linked list. A simple example demonstrates how easy it is to use these classes:

using System;
using System.Collections.Generic;
using System.Text;
class Program
{
static void Main(string[] args)
{
LinkedListNode node = new
LinkedListNode("Mike");
LinkedList names = new LinkedList();
names.AddFirst(node);
LinkedListNode node1 = new
LinkedListNode ("David");
names.AddAfter(node, node1);
LinkedListNode node2 = new
LinkedListNode ("Raymond");
names.AddAfter(node1, node2);
LinkedListNode node3 = new LinkedListNode (null);
LinkedListNode aNode = names.First;
while(aNode != null)
{
Console.WriteLine(aNode.Value);
aNode = aNode.Next;
}
aNode = names.Find("David");
if (aNode != null) aNode = names.First;
while (aNode != null)
{
Console.WriteLine(aNode.Value);
aNode = aNode.Next;
}
Console.Read()
}
}

The linked list in this example does not use a header node because
we can easily find the first node in the linked list with the First property.
Although it wasn’t used in this example, there is also a Last property
that could be used in the previous While loop to check for the end of the
list:
while (aNode != names.Last) {
Console.WriteLine(aNode.Value);
aNode = aNode.Next;
}
There are two other methods, not shown here, that could prove useful in a linked list implementation: AddFirst and AddLast. These methods can help you implement a linked list without having to provide header and tail nodes in your list.

USING AN ITERATOR CLASS in C#

One problem the LinkedList class has is that you can’t refer to two positions in the linked list at the same time. We can refer to any one position in the list (the current node, the previous node, etc.), but if we want to specify two or more positions, such as if we want to remove a range of nodes from the list, we’ll need some other mechanism. This mechanism is an iterator class.
The iterator class consists of three data fields: a field that stores the linked list, a field that stores the current node, and a field that stores the current node. The constructor method is passed a linked list object, and the method sets the current field to the header node of the list passed into the method. Let’s look at our definition of the class so far:

public class ListIter
{
private Node current;
private Node previous;
LinkedList theList;
public ListIter(LinkedList list)
{
theList = list;
current = theList.getFirst();
previous = null;
}

The first thing we want an Iterator class to do is allow us to move from node to node through the list. The method nextLink does this:

public void NextLink()
{
previous = current;
current = current.link;
}

Notice that in addition to establishing a new current position, the previous node is also set to the node that is current before the method has finished executing. Keeping track of the previous node in addition to the current node makes insertion and removal easier to perform.
The getCurrent method returns the node pointed to by the iterator:
public Node GetCurrent()
{
return current;
}

Two insertion methods are built in the Iterator class: InsertBefore and InsertAfter. InsertBefore inserts a new node before the current node; InsertAfter inserts a new node after the current node. Let’s look at the Insert-Before method first.

The first thing we have to do when inserting a new node before the current object is check to see if we are at the beginning of the list. If we are, then we can’t insert a node before the header node, so we throw an exception. This exception is defined below. Otherwise, we set the new node’s Link field to the Link field of the previous node, set the previous node’s Link field to the new node, and reset the current position to the new node. Here’s the code:

public void InsertBefore(Object theElement)
{
Node newNode = new Node(theElement);
if (current == header)
throw new InsertBeforeHeaderException();
else
{
newNode.Link = previous.Link;
previous.Link = newNode;
current = newNode;
}
}

The InsertBeforeHeader Exception class definition is:

public class InsertBeforeHeaderException
{
public InsertBeforeHeaderException()
{
base("Can't insert before the header node.");
}
}

The InsertAfter method in the Iterator class is much simpler than the method we wrote in the LinkedList class. Since we already know the position of the current node, the method just needs to set the proper links and set the current node to the next node.

public void InsertAfter(Object theElement)
{
Node newnode = new Node(theElement);
newNode.Link = current.Link;
current.Link = newnode;
NextLink();
}

Removing a node from a linked list is extremely easy using an Iterator class. The method simply sets the Link field of the previous node to the node pointed to by the current node’s Link field:

public void Remove()
{
prevous.Link = current.Link;
}

Other methods we need in an Iterator class include methods to reset the iterator to the header node (and the previous node to null) and a method to test if we’re at the end of the list. These methods are shown as follows.

public void Reset()
current = theList.getFirst();
previous = null;
}
public bool AtEnd()
{
return (current.Link == null);
}

Circular Link List Implementation in C#

Circularly Linked List
A circularly linked list is a list where the last node points back to the first node (which may be a header node).

public class Node
{
public Object Element;
public Node Flink;
public Node Blink;
public Node()
{
Element = null;
Flink = null;
Blink = null;
}
public Node(Object theElement)
{
Element = theElement;
Flink = null;
Blink = null;
}
}
public class LinkedList
{
protected Node current;

protected Node header;
private int count;
public LinkedList() {
count = 0;
header = new Node("header");
header.Link = header;
}
public bool IsEmpty() {
return (header.Link == null);
}
public void MakeEmpty() {
header.Link = null;
}
public void PrintList() {
Node current = new Node();
current = header;
while (!(current.Link.Element = "header")) {
Console.WriteLine(current.Link.Element);
current = current.Link;
}
}
private Node FindPrevious(Object n)
{
Node current = header;
while (!(current.Link == null) && current.Link.
Element != n)
current = current.Link;
return current;
}
private Node Find(Object n)
{
Node current = new Node();
current = header.Link;
while (current.Element != n)
current = current.Link;
return current;
}

public void Remove(Object n)
{
Node p = FindPrevious(n);
if (!(p.Link == null)
p.Link = p.Link.Link;
count--;
}
public void Insert(Object n1, n2)
{
Node current = new Node();
Node newnode = new Node(n1);
current = Find(n2);
newnode.Link = current.Link;
current.Link = newnode;
count++;
}
public void InsertFirst(Object n)
{
Node current = new Node(n);
current.Link = header;
header.Link = current;
count++;
}
public Node Move(int n)
{
Node current = header.Link;
Node temp;
for(int i = 0, i <= n; i++)
current = current.Link;
if (current.Element = "header")
current = current.Link;
temp = current;
return temp;
}
}
In the .NET Framework Library, the ArrayList data structure is implemented using a circularly linked list. There are also many problems that can be solved using a circularly linked list.

Doubly Link List Implementation in C#

We first need to modify the Node class to add an extra link to the class. To distinguish between the two links, we’ll call the link to the next node the FLink, and the link to the previous node the BLink. These fields are set to Nothing when a Node is instantiated. Here’s the code:
public class Node
{
public Object Element;
public Node Flink;
public Node Blink;
public Node()
{
Element = null;
Flink = null;
Blink = null;
}
public Node(Object theElement)
{
Element = theElement;
Flink = null;
Blink = null;
}
}

Insertion method


public void Insert(Object newItem, Object after)
{
Node current = new Node();
Node newNode = new Node(newItem);
current = Find(after);
newNode.Flink = current.Link;
newNode.Blink = current;
current.Flink = newNode;
}
Remove method
We first need to find the node in the list; then we set the node’s back link property to point to the node pointed to in the deleted node’s forward link. Then we need to redirect the back link of the link the deleted node points to and point it to the node before the deleted node.

public void Remove(Object n)

{
Node p = Find(n);
if (!(p.Flink == null))

{
p.Blink.Flink = p.Flink;
p.Flink.Blink = p.Blink;
p.Flink = null;
p.Blink = null;
}
}


Printing the elements of a linked list in reverse order

First, we need a method that finds the last node in the list. This is just a matter of following each node’s forward link until we reach a link that points to null. This method, called FindLast, is defined as follows:
private Node FindLast()

{
Node current = new Node();
current = header;
while(!(current.Flink == null))
current = current.Flink;
return current;
}

Once we find the last node in the list, to print the list in reverse order we just follow the backward link until we get to a link that points to null, which indicates we’re at the header node. Here’s the code:
public void PrintReverse()

{
Node current = new Node();
current = FindLast();
while (!(current.Blink == null))

{
Console.WriteLine(current.Element);
current = current.Blink;
}
}

How to write to an event log by using Visual C#

Requirements

The following list describes the recommended hardware, software, network infrastructure, and service packs that you will need:
  • Microsoft Windows 2000 Professional, Windows 2000 Server, Windows 2000 Advanced Server, or Windows NT 4.0 Server
  • Microsoft Visual Studio C#

Write to an event log

Event logging provides a standard, centralized way for your applications to record important software and hardware events. Windows supplies a standard user interface for viewing the logs, the Event Viewer. By using the common language's run-time EventLog component, you can connect to existing event logs easily, on both local and remote computers, and write entries to these logs. You can also read entries from existing logs and create your own custom event logs. In its simplest form, writing to an event log involves only a few steps to create a sample application. To do this, follow these steps:
  1. Open Visual Studio C#.
  2. Create a new Console application in Visual C#. The Console application creates a public class and an empty Main method for you.
  3. Verify that the project references at least the System.dll file.
  4. Use the using directive on the System and System.Diagnostics namespaces so that you do not have to qualify declarations from these namespaces later in your code. You must use these statements before any other declarations.
    using System;
    using System.Diagnostics;
  5. To write to an event log, you must have several pieces of information: Your
    message, the name of the log you to which you want to write (which will be
    created if it does not already exist), and a string that represents the source
    of the event. You can register a particular source with only a single event log;
    if you want to write messages to more than one log, you must define multiple
    sources.
    string sSource;
    string sLog;
    string sEvent;

    sSource = "dotNET Sample App";
    sLog = "Application";
    sEvent = "Sample Event";
  6. Use two static methods of the EventLog class to check whether your source
    exists, and then, if the source does not exist, to create this source that is
    associated with a particular event log. If the log name that you specify does
    not exist, the name is created automatically when you write your first entry to
    the log. By default, if you do not supply a log name to the
    CreateEventSource method, the log file is named "Application Log."
    if (!EventLog.SourceExists(sSource))
    EventLog.CreateEventSource(sSource,sLog);
    1. To write a message to an event log, you can use the EventLog.WriteEntry static method. This method has several different overloaded versions. The following sample code shows the simplest method, which takes a source string and your message, and one of the more complex methods, which supports specifying the event ID and event type:
      EventLog.WriteEntry(sSource,sEvent);
      EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning, 234);
    2. Save your application. Run your application, and then check the Application log in the Event Viewer to see your new events.
    Complete code listing
  7. using System;
    using System.Diagnostics;

    namespace WriteToAnEventLog_csharp
    {
    /// Summary description for Class1.
    class Class1
    {
    static void Main(string[] args)
    {
    string sSource;
    string sLog;
    string sEvent;

    sSource = "dotNET Sample App";
    sLog = "Application";
    sEvent = "Sample Event";

    if (!EventLog.SourceExists(sSource))
    EventLog.CreateEventSource(sSource,sLog);

    EventLog.WriteEntry(sSource,sEvent);
    EventLog.WriteEntry(sSource, sEvent,
    EventLogEntryType.Warning, 234);
    }
    }
    }



Web Farming with the Network Load Balancing Service in Windows Server 2003

Goto this link

http://www.west-wind.com/presentations/loadbalancing/networkloadbalancingwindows2003.asp

How to turn on remote debugging for Visual Studio 2005 in Windows XP with Service Pack 2

The Windows Firewall feature in Windows XP SP2 includes significant enhancements over the earlier the Internet Connection Firewall (ICF) feature. These enhancements help protect the computer from attack by malicious users or by malicious software such as viruses. By default, Windows Firewall is turned on for all network connections including connections to the Internet.

Turn on remote debugging

To turn on remote debugging in Windows XP with SP2, you must configure Windows Firewall as follows:
  • If Windows Firewall is in "shielded" mode, you must perform the appropriate actions so that Windows Firewall is no longer in "shielded" mode.
  • If Windows Firewall is on, you must open some ports. You must also grant some permissions to Microsoft Visual Studio 2005 and to other executable programs that are used in remote debugging.
  • If Windows Firewall is off, you may not have to configure a firewall.
  • Additionally, if the user who runs Microsoft Visual Studio 2005 does not have Administrator user rights on the remote computer, you must configure the DCOM settings on the computer that is running Visual Studio 2005.
To turn on remote debugging, you must have Administrator user rights on the computer that is running Visual Studio 2005. These instructions are only for Internet Protocol version 4 (IPV4) based network settings.

Configure DCOM on the computer that is running Visual Studio 2005

Note After you make changes by using the DCOM Configuration tool (Dcomcnfg.exe), you must restart the computer for the changes to take effect.
  1. At a command prompt, type dcomcnfg, and then press ENTER. Component Services opens.
  2. In Component Services, expand Component Services, expand Computers, and then expand My Computer.
  3. On the toolbar, click Configure My Computer. The My Computer dialog box appears.

    Note If you cannot click Configure My Computer, go to the "Remove and then re-install the MSDTC service" section.
  4. In the My Computer dialog box, click the COM Security tab.
  5. Under Access Permission, click Edit Limits. The Access Permission dialog box appears.
  6. Under Group or user names, click ANONYMOUS LOGON.
  7. Under Permissions for ANONYMOUS LOGON, click to select the Remote Access check box, and then click OK.

Remove and then re-install the MSDTC service

If you cannot click Configure My Computer that is described in step 3 in the "Configure DCOM on the computer that is running Visual Studio 2005" section, follow these steps.

Important This section, method, or task contains steps that tell you how to modify the registry. However, serious problems might occur if you modify the registry incorrectly. Therefore, make sure that you follow these steps carefully. For added protection, back up the registry before you modify it. Then, you can restore the registry if a problem occurs. For more information about how to back up and restore the registry, click the following article number to view the article in the Microsoft Knowledge Base:
322756 (http://support.microsoft.com/kb/322756/ ) How to back up and restore the registry in Windows
  1. Remove the Microsoft Distributed Transaction Service (MSDTC):
    1. Click Start, click Run, type cmd, and then click OK.
    2. At the command prompt, run the following command to stop the MSDTC service:
      Net stop msdtc
    3. At the command prompt, run the following command to remove the MSDTC service:
      Msdtc –uninstall
      The command prompt will return without a message.
  2. In Registry Editor, delete the HKEY_LOCAL_MACHINE\Software\Microsoft\MSDTC subkey.
  3. Re-install and then start the MSDTC service:
    1. At the command prompt, run the following command to re-install the MSDTC service:
      Msdtc –install
    2. At the command prompt, run the following command to start the MSDTC service:
      Net start msdtc
  4. Go to step 4 in the "Configure DCOM on the computer that is running Visual Studio 2005" section.

Configure the computer that is running Visual Studio 2005

Open Windows Firewall

To open Windows Firewall, click Start, click Run, type firewall.cpl, and then click OK.

Open TCP port 135

DCOM remote procedure call (RPC) uses Transfer Control Protocol (TCP) port 135. If the application uses DCOM to communicate with remote computers, port 135 must be open.

To open TCP port 135, follow these steps:
  1. In Windows Firewall, click Add Port on the Exceptions tab. The Add a Port dialog box appears.
  2. In the Name box, type TCP port 135.
  3. In the Port Number box, type 135.
  4. In the Protocol area, click TCP.
  5. Click Change scope to open Change Scope dialog box, click My network (subnet) only, and then click OK. (This step is optional.)
  6. In the Add a Port dialog box, click OK.

Open UDP port 4500

User Datagram Protocol (UDP) port 4500 is used for Internet Protocol security (IPsec). If your domain policy requires that all network communication be completed through IPsec, this port must be open for any network operation. If your domain policy does not require IPsec, go to the "Turn on file and print sharing" section.

To open UDP port 4500, follow these steps:
  1. In Windows Firewall, click Add Port on the Exceptions tab. The Add a Port dialog box appears.
  2. In the Name box, type UDP port 4500.
  3. In the Port Number box, type 4500.
  4. In the Protocol area, click UDP.
  5. Click Change scope. The Change Scope dialog box appears. Click My network (subnet) only, and then click OK. (This step is optional.)
  6. In the Add a Port dialog box, click OK.

Open UDP port 500

UDP port 500 is used for IPsec. If your domain policy requires that all network communication be completed through IPsec, this port must be open for any network operation. If your domain policy does not require IPsec, go to the "Turn on file and print sharing" section.

To open UDP port 500, follow these steps:
  1. In Windows Firewall, click Add Port on the Exceptions tab. The Add a Port dialog box appears.
  2. In the Name box, type UDP port 500.
  3. In the Port Number box, type 500.
  4. In the Protocol area, click UDP.
  5. Click Change scope. The Change Scope dialog box appears. Click My network (subnet) only, and then click OK. (This step is optional.)
  6. In the Add a Port dialog box, click OK.

Turn on file and print sharing

  1. In the Programs and Services area of the Exceptions tab, click File and Print Sharing, and then click Edit. The Edit a Service dialog box appears.
  2. In the Edit a Service dialog box, click to select the following check boxes:
    • TCP 139
    • TCP 445
    • UDP 137
    • UDP 138
  3. Click Change scope. The Change Scope dialog box appears. Click My network (subnet) only, and then click OK. (This step is optional.)
  4. In the Change Scope dialog box, click OK to save your settings.
  5. Click OK to close the Edit a Service dialog box.

Add Devenv.exe to the application exceptions list

To enable applications that cannot run correctly unless the required ports are opened dynamically at runtime, you must add the applications to the application exceptions list.

To add the Visual Studio 2005 Development Environment (Devenv.exe) to the application exceptions list, follow these steps:
  1. In Windows Firewall, click Add Program on the Exceptions tab. The Add a Program dialog box appears.
  2. In the Add a Program dialog box, click Browse. Locate Devenv.exe, and then click OK.

    Note The Devenv.exe file is typically located in the following folder:
    C:\Program Files\Microsoft Visual Studio 8\Common7\IDE
    Microsoft Visual Studio 2005 appears in the Add a Program dialog box.
  3. Click Change scope. The Change Scope dialog box appears. Click My network (subnet) only, and then click OK. (This step is optional.)
  4. In the Add a Program dialog box, click OK.
  5. In Windows Firewall, click OK to save your settings.

Configure the remote computer

All the ports that you have opened on the debugger computer must also be open on the remote computer. To open the TCP 135 port, the UDP 4500 port, and the UDP 500 port, and to turn on file and print sharing, follow the steps in the "" section.

You must also add the Msvsmon.exe file to the application exceptions list.

Add MSVSMon.exe to the application exceptions list

  1. In Windows Firewall, click Add Program on the Exceptions tab. The Add a Program dialog box appears.
  2. In the Add a Program dialog box, click Browse. Locate Msvsmon.exe, and then click OK.

    Note Depending on the computer architecture, the Msvsmon.exe file may be located in any one of the following folders:
    • Drive:\Program Files\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\x86
    • Drive:\Program Files\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\x64
    • Drive:\Program Files\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\ia64
    Visual Studio 2005 Remote Debugger appears in the Add a Program dialog box.
  3. Click Change scope. The Change Scope dialog box appears. Click My network (subnet) only, and then click OK. (This step is optional.)
  4. In the Add a Program dialog box, click OK.
  5. In Windows Firewall, click OK to save your settings.

Enable Web server debugging

HTTP uses TCP port 80. To do Web-based debugging, you must open TCP port 80. This is true for Microsoft ASP.NET debugging, for classic ASP debugging, and for ATL Server debugging.

To open TCP port 80, follow these steps:
  1. In Windows Firewall, click Add Port on the Exceptions tab. The Add a Port dialog box appears.
  2. In the Name box, type TCP port 80.
  3. In the Port Number box, type 80.
  4. In the Protocol area, click TCP.
  5. Click Change scope. The Change Scope dialog box appears. Click My network (subnet) only, and then click OK. (This step is optional.)
  6. In the Add a Port dialog box, click OK.
  7. In Windows Firewall, click OK to save your settings.

Enable script debugging

To debug script code that runs on a remote computer, you must add the process that hosts the script code to the application exceptions list. Typically, in classic ASP debugging, the Dllhost.exe process or the Inetinfo.exe process hosts the script code. However, for a script that runs in Microsoft Internet Explorer, the Iexplore.exe process or in the Explorer.exe process generally hosts the script code.

To add the process that hosts the script code to the application exceptions list, follow these steps:
  1. Click Start, click Run, type firewall.cpl, and then click OK.
  2. In Windows Firewall, click Add Program on the Exceptions tab. The Add a Program dialog box appears.
  3. In the Add a Program dialog box, click Browse. Locate the process that hosts the script code, and then click OK. The application of the process that hosts the script code appears in the Add a Program dialog box.

    For example, if you locate the iexplore.exe process in this step, Internet Explorer appears in the Add a Program dialog box.
  4. In the Scope area, click My network (subnet) only. (This step is optional.)
  5. In the Add a Program dialog box, click OK.
  6. In Windows Firewall, click OK to save your settings.

Run the debugger as a typical user

If you want to run the debugger as a typical user, you must have full user rights to the folder where the executable files are located. Additionally, if you do not have Administrator user rights on the remote computer, you must have access permissions and start permissions to run the debugger as a typical user.

Note A typical user is a user who does not have Administrator user rights.

Note After you make changes by using the DCOM Configuration tool (Dcomcnfg.exe), you must restart the computer for the changes to take effect.

To grant access permissions and start permissions, you must have Administrator user rights. First, obtain Administrator user rights. Then, follow these steps:
  1. At a command prompt, type dcomcnfg, and then press ENTER. Component Services opens.
  2. In Component Services, expand Component Services, expand Computers, and then expand My Computer.
  3. On the toolbar, click Configure My Computer. The My Computer dialog box appears.

    Note If you cannot click Configure My Computer, go to the "Remove and then re-install the MSDTC service" section.
  4. In the My Computer dialog box, click the COM Security tab.
  5. Under Launch and Activate Permissions, click Edit Limits.
  6. If your group or user name does not appear in the Groups or user names list in the Launch Permission dialog box, follow these steps:
    1. In the Launch Permission dialog box, click Add.
    2. In the Select Users or Groups dialog box, enter your user name and your group in the Enter the object names to select box, and then click OK.
  7. In the Launch Permission dialog box, select your user name and your group in the Group or user names box.
  8. In the Allow column under Permissions for User, select Remote Activation, and then click OK.

    Note User is a placeholder for the user name or the group that is selected in the Group or user names box. Repeat steps 7 and 8 for all the users and groups for which you want to grant permissions.

Remove and then re-install the MSDTC service

If you cannot click Configure My Computer that is described in step 3 in the "Run the debugger as a typical user" section, follow these steps.

Important This section, method, or task contains steps that tell you how to modify the registry. However, serious problems might occur if you modify the registry incorrectly. Therefore, make sure that you follow these steps carefully. For added protection, back up the registry before you modify it. Then, you can restore the registry if a problem occurs. For more information about how to back up and restore the registry, click the following article number to view the article in the Microsoft Knowledge Base:
322756 (http://support.microsoft.com/kb/322756/ ) How to back up and restore the registry in Windows
  1. Remove the MSDTC service:
    1. Click Start, click Run, type cmd, and then click OK.
    2. At the command prompt, run the following command to stop the MSDTC service:
      Net stop msdtc
    3. At the command prompt, run the following command to remove the MSDTC service:
      Msdtc –uninstall
      The command prompt will return without a message.
  2. In Registry Editor, delete the HKEY_LOCAL_MACHINE\Software\Microsoft\MSDTC subkey.
  3. Re-install and then start the MSDTC service:
    1. At the command prompt, run the following command to re-install the MSDTC service:
      Msdtc –install
    2. At the command prompt, run the following command to start the MSDTC service:
      Net start msdtc
  4. Go to step 4 in the "Run the debugger as a typical user" section.

MORE INFORMATION

For more information about Windows Firewall, click the following article number to view the article in the Microsoft Knowledge Base:
843090 (http://support.microsoft.com/kb/843090/ ) Description of the Windows Firewall feature in Windows XP Service Pack 2
For more information about Windows XP SP2, visit the following Microsoft Developer Network (MSDN) Web site:
http://msdn2.microsoft.com/en-us/security/aa570371.aspx (http://msdn2.microsoft.com/en-us/security/aa570371.aspx)
For more information about remote debugging, click the following article number to view the article in the Microsoft Knowledge Base:
833977 (http://support.microsoft.com/kb/833977/ ) How to turn on remote debugging in Windows XP with Service Pack 2

How To Create an ASP.NET HTTP Handler by Using Visual C# .NET

Implement the Handler

  1. Open Microsoft Visual Studio .NET. In Visual C# .NET, create a new Class Library project named MyHandler.
  2. Set a reference to the System.Web.dll assembly.
  3. Add the following directive to the class.
using System.Web;

4. Rename the class SyncHandler.cs, and then change the class definition to reflect this.
5.Implement the IHttpHandler interface. Your class definition should appear as follows:

public class SyncHandler : IHttpHandler

6. Implement the IsReusable property and the ProcessRequest method of the IHttpHandler interface. Because this is a synchronous handler, return False for the IsReusable property so that the handler is not pooled.

public bool IsReusable
{
get
{
return false;
}
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("Hello from custom handler.");
}

7. Compile the project.

Deploy the Handler


  1. Create a new directory named Handler under the C:\Inetpub\Wwwroot directory.
  2. Create a subdirectory named Bin in the newly created Handler directory. The resultant path is C:\Inetpub\Wwwroot\Handler\Bin.
  3. Copy MyHandler.dll from your project's Bin\Debug directory to the C:\Inetpub\Wwwroot\Handler\Bin directory.
  4. Follow these steps to mark the new Handler directory as a Web application:
    1. Open Internet Services Manager.
    2. Right-click the Handler directory, and then click Properties.
    3. On the Directory tab, click Create.
  5. Follow these steps to create an application mapping for the handler. For this handler, create a mapping to the Aspnet_isapi.dll file for the *.sync extension. Whenever a .sync file is requested, the request is routed to ASP.NET, and ASP.NET executes the code in the handler.
    1. Right-click on the Handler Web application, and then click Properties.
    2. On the Directory tab, click Configuration.
    3. Click Add to add a new mapping.
    4. In the Executable text box, type the following path: Microsoft Windows 2000:
      C:\WINNT\Microsoft.NET\Framework\\Aspnet_isapi.dll
      Microsoft Windows XP:
      C:\WINDOWS\Microsoft.NET\Framework\\Aspnet_isapi.dll
    5. In the Extension text box, type .sync.
    6. Make sure that the Check that file exists check box is cleared, and then click OK to close the Add/Edit Application Extension Mapping dialog box.
    7. Click OK to close the Application Configuration and the Handler Properties dialog boxes.
  6. Close Internet Services Manager.

Configure the System

  1. In the C:\Inetpub\Wwwroot\Handler directory, create a new file named Web.config.
  2. Add the following code to Web.config:


In the verb="*" attribute, we instruct the handler to process a request that uses any verb (for example, POST, HEAD, GET, and so on). If you want this handler to process only the POST request, change this to verb="POST".

In the path="*.sync" attribute, we instruct the handler to process any incoming requests for files with the .sync extension.

In the type="MyHandler.SyncHandler, MyHandler" attribute, we instruct the handler that processes the request to implement in the MyHandler.SyncHandler namespace, and this class resides in the MyHandler assembly.

Test the Module

To test a handler, a page does not need to exist in the file system. For example, request the Default.sync file in the Handler Web application (http:///Handler/Default.sync). You should receive the following results:

Hello from custom handler.

How to use the Debug and the Trace classes

This article describes how to use the Debug and the Trace classes. These classes are available in the Microsoft .NET Framework. You can use these classes to provide information about the performance of an application either during application development, or after deployment to production. These classes are only one part of the instrumentation features that are available in the .NET Framework.

Requirements

The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
  • Microsoft Windows 2000 or Microsoft Windows XP or Microsoft Windows Server 2003
  • Microsoft Visual C#
This article also assumes that you are familiar with program debugging.

Description Of Technique


The steps in the Create a Sample with the Debug Class section demonstrate how to create a console application that uses the Debug class to provide information about the program execution.

When the program is run, you can use methods of the Debug class to produce messages that help you to monitor the program execution sequence, to detect malfunctions, or to provide performance measurement information. By default, the messages that the Debug class produces appear in the Output window of the Visual Studio Integrated Development Environment (IDE).

The sample code uses the WriteLine method to produce a message that is followed by a line terminator. When you use this method to produce a message, each message appears on a separate line in the Output window.

When you use the Assert method of the Debug class, the Output window displays a message only if a specified condition evaluates to false. The message also appears in a modal dialog box to the user. The dialog box includes the message, the project name, and the Debug.Assert statement number. The dialog box also includes the following three command buttons:
  • Abort: The application stops running.
  • Retry: The application enters debug mode.
  • Ignore: The application proceeds.
The user must click one of these buttons before the application can continue.

You can also direct output from the Debug class to destinations other than the Output window. The Debug class has a collection named Listeners that includes Listener objects.

Each Listener object monitors Debug output and directs the output to a specified target.

Each Listener in the Listener collection receives any output that the Debug class generates. Use the TextWriterTraceListener class to define Listener objects. You can specify the target for a TextWriterTraceListener class through its constructor.

Some possible output targets include the following:
  • The Console window by using the System.Console.Out property.
  • A text (.txt) file by using the System.IO.File.CreateText("FileName.txt") statement.
After you create a TextWriterTraceListener object, you must add the object to the Debug.Listeners collection to receive Debug output

Create a Sample with the Debug Class

  1. Start Visual Studio or Visual C# Express Edition.
  2. Create a new Visual C# Console Application project named conInfo. Class1 is created in Visual Studio .NET. Program.cs is created in Visual Studio 2005.
  3. Add the following namespace at top in Class1 or Program.cs.
using System.Diagnostics;

4.To initialize variables to contain information about a product, add the following declaration statements to Main method:
string sProdName = "Widget";
int iUnitQty = 100;
double dUnitCost = 1.03;

5.Specify the message that the class produces as the first input parameter of the
WriteLine method. Press the CTRL+ALT+O key combination to make sure that
the Output window is visible.

Debug.WriteLine("Debug Information-Product Starting ");

6.For readability, use the Indent method to indent subsequent messages in
the Output window:
Debug.Indent();

7.To display the content of selected variables, use the WriteLine method as
follows:
Debug.WriteLine("The product name is " + sProdName);
Debug.WriteLine("The available units on hand are" + iUnitQty.ToString());

8.You can also use the WriteLine method to display the namespace and the
class name for an existent object. For example, the following code displays the
System.Xml.XmlDocument namespace in the Output window:
System.Xml.XmlDocument oxml = new System.Xml.XmlDocument();

9.To organize the output, you can include a category as an optional, second input
parameter of the WriteLine method. If you specify a category, the format
of the Output window message is "category: message." For example, the first line
of the following code displays "Field: The product name is Widget" in the Output
window:
Debug.WriteLine("The product name is " + sProdName,"Field");
Debug.WriteLine("The units on hand are" + iUnitQty,"Field");
Debug.WriteLine("The per unit cost is" + dUnitCost.ToString(),"Field");
Debug.WriteLine("Total Cost is " + (iUnitQty * dUnitCost),"Calc");

Debug.WriteLine(oxml);

Debug.WriteLine("The per unit cost is " + dUnitCost.ToString());
10.The Output window can display messages only if a designated condition evaluates
to true by using the WriteLineIf method of the Debug class. The
condition to be evaluated is the first input parameter of the WriteLineIf
method. The second parameter of WriteLineIf is the message that appears
only if the condition in the first parameter evaluates to true.
Debug.WriteLineIf(iUnitQty > 50, "This message WILL appear");

11.
  1. Use the Assert method of the Debug class so that the Output window displays the message only if a specified condition evaluates to false:
    Debug.Assert(dUnitCost > 1, "Message will NOT appear");
    Debug.Assert(dUnitCost < 1, "Message will appear since dUnitcost < 1 is false");
Debug.WriteLineIf(iUnitQty < 50, "This message will NOT appear");
12. Create the TextWriterTraceListener objects for the Console window (tr1) and for a text file named Output.txt (tr2), and then add each object to the Debug Listeners collection:
TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out);
Debug.Listeners.Add(tr1);

TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText("Output.txt"));

13.For readability, use the Unindent method to remove the indentation for
subsequent messages that the Debug class generates. When you use the
Indent and the Unindent methods together, the reader can
distinguish the output as group.
Debug.Unindent();
Debug.WriteLine("Debug Information-Product Ending");

Debug.Listeners.Add(tr2);
14. To make sure that each Listener object receives all its output, call the Flush method for the Debug class buffers:
Debug.Flush();

Using the Trace Class

You can also use the Trace class to produce messages that monitor the execution of an application. The Trace and Debug classes share most of the same methods to produce output, including the following:
  • WriteLine
  • WriteLineIf
  • Indent
  • Unindent
  • Assert
  • Flush
You can use the Trace and the Debug classes separately or together in the same application. In a Debug Solution Configuration project, both Trace and Debug output are active. The project generates output from both of these classes to all Listener objects. However, a Release Solution Configuration project only generates output from a Trace class. The Release Solution Configuration project ignores any Debug class method invocations.
Trace.WriteLine("Trace Information-Product Starting ");
Trace.Indent();

Trace.WriteLine("The product name is "+sProdName);
Trace.WriteLine("The product name is"+sProdName,"Field" );
Trace.WriteLineIf(iUnitQty > 50, "This message WILL appear");
Trace.Assert(dUnitCost > 1, "Message will NOT appear");

Trace.Unindent();
Trace.WriteLine("Trace Information-Product Ending");

Trace.Flush();

Console.ReadLine();


Verify That It Works

  1. Make sure that Debug is the current solution configuration.
  2. If the Solution Explorer window is not visible, press the CTRL+ALT+L key combination to display this window.
  3. Right-click conInfo, and then click Properties.
  4. In the left pane of the conInfo property page, under the Configuration folder, make sure that the arrow points to Debugging.

    Note In Visual C# 2005 and in Visual C# 2005 Express Edition, click Debug in the conInfo page.
  5. Above the Configuration folder, in the Configuration drop-down list box, click Active (Debug) or Debug, and then click OK. In Visual C# 2005 and in Visual C# 2005 Express Edition, click Active (Debug) or Debug in the Configuration drop-down list box in the Debug page, and then click Save on the File menu.
  6. Press CTRL+ALT+O to display the Output window.
  7. Press the F5 key to run the code. When the Assertion Failed dialog box appears, click Ignore.
  8. In the Console window, press ENTER. The program should finish, and the Output window should display the output that resembles the following
        Debug Information-Product Starting
    The product name is Widget
    The available units on hand are100
    The per unit cost is 1.03
    System.Xml.XmlDocument
    Field: The product name is Widget
    Field: The units on hand are100
    Field: The per unit cost is1.03
    Calc: Total Cost is 103
    This message WILL appear
    ---- DEBUG ASSERTION FAILED ----
    ---- Assert Short Message ----
    Message will appear since dUnitcost < 1 is false
    ---- Assert Long Message ----


    at Class1.Main(String[] args) <%Path%>\class1.cs(34)

    The product name is Widget
    The available units on hand are100
    The per unit cost is 1.03
    Debug Information-Product Ending
    Trace Information-Product Starting
    The product name is Widget
    Field: The product name isWidget
    This message WILL appear
    Trace Information-Product Ending

  9. The Console window and the Output.txt file should display the following output:
    The product name is Widget
    The available units on hand are 100
    The per unit cost is 1.03
    Debug Information-Product Ending
    Trace Information-Product Starting
    The product name is Widget
    Field: The product name is Widget
    This message WILL appear
    Trace Information-Product Ending
Note The Output.txt file is located in the same directory as the conInfo executable (conInfo.exe). Typically, this is the \bin folder where the project source is stored. By default, this is C:\Documents and Settings\User login\My Documents\Visual Studio Projects\conInfo\bin. In Visual C# 2005 and in Visual C# 2005 Express Edition, the Output.txt file is located in the following folder:
C:\Documents and Settings\User login\My Documents\Visual Studio 2005\Projects\conInfo\conInfo\bin\Debug

Complete Code Listing
using System;
using System.Diagnostics;

class Class1
{
[STAThread]
static void Main(string[] args)
{
string sProdName = "Widget";
int iUnitQty = 100;
double dUnitCost = 1.03;
Debug.WriteLine("Debug Information-Product Starting ");
Debug.Indent();
Debug.WriteLine("The product name is "+sProdName);
Debug.WriteLine("The available units on hand are"+iUnitQty.ToString()); Debug.WriteLine("The per unit cost is "+ dUnitCost.ToString());

System.Xml.XmlDocument oxml = new System.Xml.XmlDocument();
Debug.WriteLine(oxml);
Debug.WriteLine("The product name is "+sProdName,"Field");
Debug.WriteLine("The units on hand are"+iUnitQty,"Field");
Debug.WriteLine("The per unit cost is"+dUnitCost.ToString(),"Field");
Debug.WriteLine("Total Cost is "+(iUnitQty * dUnitCost),"Calc");
Debug.WriteLineIf(iUnitQty > 50, "This message WILL appear");
Debug.WriteLineIf(iUnitQty < 50, "This message will NOT appear");
Debug.Assert(dUnitCost > 1, "Message will NOT appear");
Debug.Assert(dUnitCost < 1, "Message will appear since dUnitcost < 1 is false");


TextWriterTraceListener tr1 = new TextWriterTraceListener(System.Console.Out); Debug.Listeners.Add(tr1);
TextWriterTraceListener tr2 = new TextWriterTraceListener(System.IO.File.CreateText("Output.txt")); Debug.Listeners.Add(tr2);
Debug.WriteLine("The product name is "+sProdName);
Debug.WriteLine("The available units on hand are"+iUnitQty);
Debug.WriteLine("The per unit cost is "+dUnitCost);
Debug.Unindent();
Debug.WriteLine("Debug Information-Product Ending");
Debug.Flush();
Trace.WriteLine("Trace Information-Product Starting ");
Trace.Indent();
Trace.WriteLine("The product name is "+sProdName);

Trace.WriteLine("The product name is"+sProdName,"Field" );
Trace.WriteLineIf(iUnitQty > 50, "This message WILL appear");
Trace.Assert(dUnitCost > 1, "Message will NOT appear");
Trace.Unindent();
Trace.WriteLine("Trace Information-Product Ending");
Trace.Flush(); Console.ReadLine();
}
}