This blog is moved to
http://amalhashim.wordpress.com
Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Wednesday, May 18, 2011

Serialize Multiobject ArrayList to XML

This is a code snippet which shows how to Serialize an ArrayList to XML. ArrayList contains objects of different types.

using System.Collections;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
class Program
{

static void Main(string[] args)
{
AListWrapper wrapper = new AListWrapper();

XmlSerializer mySerializer = new XmlSerializer(typeof(AListWrapper));

StreamWriter myWriter = new StreamWriter("c:\\myFileName.xml");

mySerializer.Serialize(myWriter, wrapper);
myWriter.Close();
}
}

public class Animal
{
public string Type { get; set; }
public int Age { get; set; }
}

public class Employee
{
public string Name { get; set; }
public double Salary { get; set; }
public string Address { get; set; }
}

[XmlRoot("ArrayList")]
public class AListWrapper
{
[XmlElement(Type = typeof(Employee)),
XmlElement(Type = typeof(Animal))]
public ArrayList list = new ArrayList();

public AListWrapper()
{
Animal animal = new Animal()
{
Age = 1,
Type = "Dog"
};

Employee emp = new Employee()
{
Address = "Address",
Name = "SomeName",
Salary = 2000.50
};

list.Add(animal);
list.Add(emp);
}
}
}

Monday, May 2, 2011

DataTable to GenericList | C# and LINQ

Programming Microsoft® LINQ in Microsoft .NET Framework 4 
using System;
using System.Data;

namespace ConsoleApplication1
{
class Program
{

static void Main(string[] args)
{
DataTable table = new DataTable
{
Columns = {
{"Id", typeof(int)},
{"Name", typeof(string)}
}
};

table.Rows.Add(1, "Amal");
table.Rows.Add(1, "Fousiya");
table.Rows.Add(1, "Munna");
table.Rows.Add(1, "Hussain");         

var listOfEmployees = from row in table.AsEnumerable()
select new Employee
{
Id = row.Field<int>("Id"),
Name = row.Field<String>("Name")
};

foreach (Employee emp in listOfEmployees)
{
Console.WriteLine("{0}   {1}", emp.Id, emp.Name);
}
}
}

class Employee
{
public int Id { get; set; }
public String Name { get; set; }
}
}

Thursday, October 21, 2010

MOSS | Using People Editor Control


People editor can be used whenever we want the user to select user, AD groups or SharePoint groups. For using the control, 1st we need to register the assembly as shown below
<%@ register tagprefix="SharePointWebControls" namespace="Microsoft.SharePoint.WebControls"
assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
Once this is done, we can use the following tag for placing the control
<SharePointWebControls:PeopleEditor ID="ppeUser" runat="server" Rows="1" 
CheckButtonImageName = "/_layouts/Images/user.png" 
BrowseButtonImageName = "/_layouts/Images/addressbook.png"                                   
PlaceButtonsUnderEntityEditor="false" MultiSelect="false" AutoPostBack="true"/>

In C#, the following code demonstrate the usage

this.ppeUser.CommaSeparatedAccounts;

Using the above code we can get information user has selected/entered in the people editor control.

public static void UpdatePeoplePicker(string login, PeopleEditor editor)
{
ArrayList list = new ArrayList();
PickerEntity entity = new PickerEntity();
entity.Key = login;
entity = editor.ValidateEntity(entity);
list.Add(entity);
editor.UpdateEntities(list);
}

The above code can be used to update the People Editor control using code.


We can restrict the selection of the People Editor using the SelectionSet property. It accepts the following values

User – In case the selection to be restricted only for users
AD – In case the selection to be restricted only for AD groups
SPGroup – In case the selection to be restricted only for SharePoint Groups

Hope this was helpful!!!

Friday, October 8, 2010

MOSS 2007 | Enumerate User Profile Properties

Below is the code to enumerate the User Profile Properties

using System;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using (SPSite site = new SPSite("http://server:port/"))
{
ServerContext context =
ServerContext.GetContext(site);
UserProfileManager profileManager = new UserProfileManager(context);
string sAccount = "domain\\user";
UserProfile u = profileManager.GetUserProfile(sAccount);
PropertyCollection props = profileManager.Properties;

foreach (Property prop in props)
{
Console.WriteLine(prop.DisplayName + ">>" + prop.Name );
}
}
}
}
}

Friday, September 24, 2010

C# | Automating Facebook Login using WebBrowser Control

Create a new windows forms application project.

Add two button and place the web browser control as shown below. Rename the button as “btnShowPage” and “btnLogin”.

image

On form load event use the following code

private void Form1_Load(object sender, EventArgs e)
{
btnLogin.Enabled = false;
}



Now on button btnShowPage use the following code



private void btnShowPage_Click(object sender, EventArgs e)
{
webBrowser1.Navigate("https://login.facebook.com/login.php?login_attempt=1");
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
}


void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
string s = webBrowser1.DocumentText;
btnLogin.Enabled = true;
}



On btnLogin click event use the following code



private void btnLogin_Click(object sender, EventArgs e)
{
HtmlElement ele = webBrowser1.Document.GetElementById("email");
if (ele != null)
ele.InnerText = "amalhashim@gmail.com";

ele = webBrowser1.Document.GetElementById("pass");
if (ele != null)
ele.InnerText = "password";

ele = webBrowser1.Document.GetElementById("Login");
if (ele != null)
ele.InvokeMember("click");
}



That’s it :-)

Sunday, April 11, 2010

LINQ Performance Benchmark

Yesterday I was reading “LINQ To Objects Using C# 4.0” by Troy Magennis and find a good LINQ usage example. I got curious about how the LINQ implementation will perform and thought of writing this article.

The example is related to an entity having 3 fields State, LastName and FirstName. The aim is to Group the objects by state and sort by LastName. For calculating the execution time I am using Stopwatch class in System.Diagnosis namespace.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.IO;

namespace ConsoleApplication2
{
public class Customer
{
public string State { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}

class Program
{
static void Main(string[] args)
{
List<Customer> custList = FillListAndGetList();

Stopwatch sw = new Stopwatch();
sw.Start();
#region C# 2.0 Approach

///Sorting by LastName
custList.Sort(
delegate(Customer c1, Customer c2)
{
if (c1 != null && c2 != null)
return string.Compare(c1.LastName, c2.FirstName);
return 0;
});

///Sort and Groupby State [SortedDictionary]
SortedDictionary<string, List<Customer>>
sortedCust = new SortedDictionary<string, List<Customer>>();

foreach (Customer c in custList)
{
if (!sortedCust.ContainsKey(c.State))
sortedCust.Add(c.State, new List<Customer>());

sortedCust[c.State].Add(c);
}

foreach (KeyValuePair<string, List<Customer>>
pair in sortedCust)
{
Console.WriteLine("State : " + pair.Key);

foreach (Customer c in pair.Value)
Console.WriteLine("Last Name : {0}" +
"FirstName : {1} ", c.LastName,
c.FirstName);
}

#endregion

sw.Stop();
File.WriteAllLines("C20", new string[] { sw.ElapsedTicks.ToString() });

custList = FillListAndGetList();
sw.Reset();
sw.Start();

#region LINQ Approach

var query = from c in custList
orderby c.State, c.LastName
group c by c.State;

foreach (var group in query)
{
Console.WriteLine("State : " + group.Key);

foreach (Customer c in group)
Console.WriteLine("Last Name : {0}" +
"FirstName : {1} ", c.LastName,
c.FirstName);
}

#endregion

sw.Stop();
File.WriteAllLines("C20", new string[] { sw.ElapsedTicks.ToString() });
}

private static List<Customer> FillListAndGetList()
{
List<Customer> custList = new List<Customer>();
for (int i = 0; i < 1000000; i++)
{
Customer c = new Customer();
if (i % 2 == 0)
{
c.State = "State2";
c. FirstName = "FirstName2" + i.ToString();
c.LastName = "LastName2" + i.ToString();
}
else if (i % 3 == 0)
{
c.State = "State3";
c.FirstName = "FirstName3" + i.ToString();
c.LastName = "LastName3" + i.ToString();
}
else if(i % 7 == 0)
{
c.State = "State7";
c.FirstName = "FirstName7" + i.ToString();
c.LastName = "LastName7" + i.ToString();
}
else if (i % 11 == 0)
{
c.State = "State11";
c.FirstName = "FirstName11" + i.ToString();
c.LastName = "LastName11" + i.ToString();
}
else
{
c.State = "OtherState";
c.FirstName = "FirstName" + i.ToString();
c.LastName = "LastName" + i.ToString();
}

custList.Add(c);
}

return custList;
}
}
}

Once I ran the application, I got the following result.
C# 2.0 version : 627373008
LINQ version : 692116906
LINQ version has a slight performance problem, but compared to the chunk of code that has gone in 2.0 I think LINQ is far better.

Tuesday, April 6, 2010

C# – Read, Insert, Update, Delete From SQL Database

Code snippets for reading, inserting, updating and deleting from SQL database.

static void Read()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("SELECT * FROM EmployeeDetails", conn))
{
SqlDataReader reader = cmd.ExecuteReader();

if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("Id = ", reader["Id"]);
Console.WriteLine("Name = ", reader["Name"]);
Console.WriteLine("Address = ", reader["Address"]);
}
}

reader.Close();
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Insert()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("INSERT INTO EmployeeDetails VALUES(" +
"@Id, @Name, @Address)", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);
cmd.Parameters.AddWithValue("@Name", "Amal Hashim");
cmd.Parameters.AddWithValue("@Address", "Bangalore");

int rows = cmd.ExecuteNonQuery();

//rows number of record got inserted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Update()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("UPDATE EmployeeDetails SET Name=@NewName, Address=@NewAddress" +
" WHERE Id=@Id", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);
cmd.Parameters.AddWithValue("@Name", "Munna Hussain");
cmd.Parameters.AddWithValue("@Address", "Kerala");

int rows = cmd.ExecuteNonQuery();

//rows number of record got updated
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

static void Delete()
{
try
{
string connectionString =
"server=.;" +
"initial catalog=employee;" +
"user id=sa;" +
"password=sa123";
using (SqlConnection conn =
new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd =
new SqlCommand("DELETE FROM EmployeeDetails " +
"WHERE Id=@Id", conn))
{
cmd.Parameters.AddWithValue("@Id", 1);

int rows = cmd.ExecuteNonQuery();

//rows number of record got deleted
}
}
}
catch (SqlException ex)
{
//Log exception
//Display Error message
}
}

Sunday, April 4, 2010

C# | 3 Tier Architecture

In this article I am going to explain how easily we can build up a 3 layered application using .net framework and c#. I have an Employee database. For demonstration I have cut the scope by talking only to one table, EmployeeDetails.

In 3 tier, we are dealing with

1. Data Access Layer

2. Business Layer

3. Presentation Layer

Here is the code of my Data Access Layer
static class DAL
{
const string ConnectionString = "server=.;initial catalog=Employee;user id=sa;password=sa123";

public static int ExecuteNonQuery(string commandText, SqlParameter[] parameters)
{
try
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
foreach (SqlParameter param in parameters)
cmd.Parameters.Add(param);

int rowsAffected = cmd.ExecuteNonQuery();

return rowsAffected;
}
}
}
catch
{
throw;
}
}

public static SqlDataReader GetReader(string commandText, SqlParameter[] parameters)
{
try
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
foreach (SqlParameter param in parameters)
cmd.Parameters.Add(param);

SqlDataReader reader = cmd.ExecuteReader();

return reader;
}
}
}
catch
{
throw;
}
}
}

To resemble the table EmployeeDetails I have created the following entity class
class EmployeeEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("Employee Name = ").Append(this.Name);
sb.Append(" Have Id = ").Append(this.Id);
sb.Append(" Lives In = ").Append(this.Address);

return sb.ToString();
}
}

Now comes the business layer


static class Employee
{
public static int AddEmployee(EmployeeEntity e)
{
SqlParameter[] param = new SqlParameter[3];
param[0] = new SqlParameter("@Id", e.Id);
param[1] = new SqlParameter("@Name", e.Name);
param[2] = new SqlParameter("@Address", e.Address);

return DAL.ExecuteNonQuery("INSERT INTO EmployeeDetails VALUES(@Id, @Name, @Address)", param);
}

public static EmployeeEntity GetEmployee(int id)
{
SqlParameter[] param = new SqlParameter[1];
param[0] = new SqlParameter("@Id", id);

SqlDataReader reader = DAL.GetReader("SELECT * FROM EmployeeDetails WHERE Id = @Id", param);

if (reader.HasRows)
{
EmployeeEntity emp = new EmployeeEntity();
while (reader.Read())
{
int temp = 0;
int.TryParse(reader["Id"].ToString(), out temp);
emp.Id = temp;
emp.Name = reader["Name"].ToString();
emp.Address = reader["Address"].ToString();

break;
}
return emp;

}
else
return null
;
}
}

Finally my presentation
class Program
{
static void Main(string[] args)
{
Employee.AddEmployee(new EmployeeEntity() { Id = 1, Name = "Amal", Address = "MyAddress" });
Employee.AddEmployee(new EmployeeEntity() { Id = 2, Name = "Hashim", Address = "Hashim Address" });
Employee.AddEmployee(new EmployeeEntity() { Id = 3, Name = "Rooney", Address = "Manchester" });

EmployeeEntity emp = Employee.GetEmployee(1);

Console.WriteLine(emp);
}
}

For better demonstration, you can think the presentation layer as a windows form application. With a 3 textboxes and one button. You can enter Id, Name and Address and use the button event for adding the data.

.Net Framework | Value Types

Value type holds data in the variable. They are stored in “Stack”. Because of this the performance is good and causes minimal overhead. Mainly there are three value types

1. In built

2. User defined(structs)

3. Enums

All the above are derived from System.Value

Type Bytes Occupied Range
System.SByte 1 -128 to 127
System.Byte 1 0 to 255
System.Int16 2 -32768 to 32767
System.Int32 4 -2147483648 to 2147483647
System.UInt32 4 0 to 4294967295
System.Int64 8 -9223372036854775808 to 9223372036854775807
System.Single 4 –3.402823E+38 to 3.402823E+38
System.Double 8 -1.79769319486232E+308 to 1.79769319486232E+308
System.Decimal 16 -79228162514264337593543950335 to 79228162514264337593543950335
System.Char 2  
System.Boolean 4  
System.DateTime 8 1/1/0001 12:00:00 AM to 12/31/9999 11:59:59 PM
System.Boolean 4 True/False
System.IntPtr Platform Dependent  

Nullable Types

In some scenarios we might need to store the value null in the basic types. For doing that we can make the type nullable as shown below

bool? isValid = null;
//or
Nullable<bool> isSelected = null;


Structures or User Defined Types


Struct as mentioned is also a value type and is stored on the stack. Struct resembles class, but have several differences. Structures are composite types. They form a meaningful  data. The most common example give for structures is the Point type available in System.Drawing namespace. Each point can be represented using x and y coordinate and hence a structure can be formed as


struct Point
{
public UInt32 X;
public UInt32 Y;
}



I have enhanced the Point structure as shown below



using System;
using System.Text;

namespace ConsoleApplication2
{
struct Point
{
public UInt32 X;
public UInt32 Y;

public Point(uint x, uint y)
{
this.X = x;
this.Y = y;
}

public static Point operator +(Point p1, Point p2)
{
Point newPoint = new Point(p1.X + p2.X, p1.Y + p2.Y);

return newPoint;
}

public static Point operator -(Point p1, Point p2)
{
Point newPoint = new Point(p1.X + p2.X, p1.Y + p2.Y);

return newPoint;
}

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("The current point has X = ").Append(this.X.ToString())
.Append(" and Y = ").Append(this.Y.ToString());
return sb.ToString();
}
}

class Program
{
static void Main(string[] args)
{
Point p1 = new Point(10, 20);
Point p2 = new Point(20, 30);

p1 += p2;

Console.WriteLine(p1);

}

}
}

As you can see the structure has a parameterized constructor and can have methods. It also has overloaded operators.


Note: We can’t use default constructors in Structure. Default constructor is used by the framework to initialize the fields in structure.


Note: Always make use of a structure only if the entire data in it constitute less than 16 bytes.


Enumerations or Enum


Enums are grouped constants. They are introduced mainly to make the code readable.


Lets extend the above application by adding an Enum Direction. Based on the direction the point will be moved.


using System;
using System.Text;

namespace ConsoleApplication2
{
struct Point
{
public UInt32 X;
public UInt32 Y;

public Point(uint x, uint y)
{
this.X = x;
this.Y = y;
}

public static Point operator +(Point p1, Point p2)
{
Point newPoint = new Point(p1.X + p2.X, p1.Y + p2.Y);

return newPoint;
}

public static Point operator -(Point p1, Point p2)
{
Point newPoint = new Point(p1.X + p2.X, p1.Y + p2.Y);

return newPoint;
}

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("The current point has X = ").Append(this.X.ToString())
.Append(" and Y = ").Append(this.Y.ToString());
return sb.ToString();
}

public void Move(Direction d)
{
switch (d)
{
case Direction.Up:
if (this.X > 0)
this.X--;
break;
case Direction.Down:
if (this.X < 1000)
this.X++;
break;
case Direction.Left:
if (this.Y > 0)
this.Y--;
break;
case Direction.Right:
if (this.Y < 1000)
this.Y++;
break;
default:
break;
}
}
}

enum Direction
{
Up,
Down,
Left,
Right
}

class Program
{
static void Main(string[] args)
{
Point p1 = new Point(0, 0);
Console.WriteLine(p1);
p1.Move(Direction.Left);
Console.WriteLine(p1);
p1.Move(Direction.Down);
Console.WriteLine(p1);
p1.Move(Direction.Left);
Console.WriteLine(p1);
p1.Move(Direction.Right);
Console.WriteLine(p1);
}

}
}

Tuesday, March 9, 2010

ASP.Net Password Input Width Issue

I came across a strange issue with Password input and IE browser. I have set the width property as same as that of the other controls. But while rendering it in IE, the width of Password field was coming as around 10 pixel less than the other control. The best way to get rid of this issue was using CSS.

Before applying CSS I was using the below code

<html xmlns="http://www.w3.org/1999/xhtml" >
<
body>
<
form id="form1" runat="server">
<
table width="25%">
<
tr>
<
td style="width:100%; text-align:left">UserName: </td>
<
td style="width:100%; text-align:left"><asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></td>
</
tr>
<
tr>
<
td style="width:100%; text-align:left">Password: </td>
<
td style="width:100%; text-align:left"><asp:TextBox ID="txtPassword" TextMode="Password" runat="server"></asp:TextBox></td>
</
tr>
</
table>
</
form>
</
body>
</
html>
And in IE it’s coming as

image

Resolution, I have defined the following style
<style type="text/css" >
.TextBox
{
font-family: Arial, Tahoma, Verdana, Calibri;
font-size: 12px;
color: Black;
height: auto;
width: auto;
}
</style>

And modified the HTML as

<html xmlns="http://www.w3.org/1999/xhtml" >
<
body>
<
form id="form1" runat="server">
<
table width="25%">
<
tr>
<
td style="width:100%; text-align:left">UserName: </td>
<
td style="width:100%; text-align:left"><asp:TextBox CssClass="TextBox" ID="txtUserName" runat="server"></asp:TextBox></td>
</
tr>
<
tr>
<
td style="width:100%; text-align:left">Password: </td>
<
td style="width:100%; text-align:left"><asp:TextBox CssClass="TextBox" ID="txtPassword" TextMode="Password" runat="server"></asp:TextBox></td>
</
tr>
</
table>
</
form>
</
body>
</
html>

Now in IE it’s coming as

image

Viola!!!!! issue resolved. Hope this helps.

Monday, March 8, 2010

Disabling Network using C#

In C# there are several ways to interact with network interfaces. Which include WMI, NetworkInformation Namespace, Win32 API’s etc. In this article I am going to explain, how easily we can query network information's and play with it.
///Check whether network is available or not
bool isNwUp = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

///Get all network cards and display status
System.Net.NetworkInformation.NetworkInterface[] networkCards = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();

foreach (System.Net.NetworkInformation.NetworkInterface ni in networkCards)
{
Console.WriteLine(ni.Name + ": " + ni.OperationalStatus.ToString());
}


Now let’s see how we can enable/disable a network connection. I have written a generic class wrapping all required methods.

/// <summary>
/// This is a generic class for disconnecting TCP connections.
/// This class can be used to
/// 1. Get a list of all connections.
/// 2. Cloas a connection
/// </summary>
public static class DisconnectWrapper
{
/// <summary>
/// Enumeration of connection states
/// </summary>
public enum ConnectionState
{
All = 0,
Closed = 1,
Listen = 2,
Syn_Sent = 3,
Syn_Rcvd = 4,
Established = 5,
Fin_Wait1 = 6,
Fin_Wait2 = 7,
Close_Wait = 8,
Closing = 9,
Last_Ack = 10,
Time_Wait = 11,
Delete_TCB = 12
}

/// <summary>
/// Connection information
/// </summary>
private struct ConnectionInfo
{
public int dwState;
public int dwLocalAddr;
public int dwLocalPort;
public int dwRemoteAddr;
public int dwRemotePort;
}

/// <summary>
/// Win 32 API for get all connection
/// </summary>
/// <param name="pTcpTable">Pointer to TCP table</param>
/// <param name="pdwSize">Size</param>
/// <param name="bOrder">Order</param>
/// <returns>Number</returns>
[DllImport("iphlpapi.dll")]
private static extern int GetTcpTable(IntPtr pTcpTable, ref int pdwSize, bool bOrder);

/// <summary>
/// Set the connection state
/// </summary>
/// <param name="pTcprow">Pointer to TCP table row</param>
/// <returns>Status</returns>
[DllImport("iphlpapi.dll")]
private static extern int SetTcpEntry(IntPtr pTcprow);

/// <summary>
/// Convert 16-bit value from network to host byte order
/// </summary>
/// <param name="netshort">network host</param>
/// <returns>host byte order</returns>
[DllImport("wsock32.dll")]
private static extern int ntohs(int netshort);

/// <summary>
/// //Convert 16-bit value back again
/// </summary>
/// <param name="netshort"></param>
/// <returns></returns>
[DllImport("wsock32.dll")]
private static extern int htons(int netshort);

/// <summary>
/// Close all connection to the remote IP
/// </summary>
/// <param name="IP">IP to close</param>
public static void CloseRemoteIP(string IP)
{
ConnectionInfo[] rows = getTcpTable();
for (int i = 0; i < rows.Length; i++)
{
if (rows[i].dwRemoteAddr == IPStringToInt(IP))
{
rows[i].dwState = (int)ConnectionState.Delete_TCB;
IntPtr ptr = GetPtrToNewObject(rows[i]);
int ret = SetTcpEntry(ptr);
}
}
}

/// <summary>
/// Close all connections at current local IP
/// </summary>
/// <param name="IP">IP to close</param>
public static void CloseLocalIP(string IP)
{
ConnectionInfo[] rows = getTcpTable();
for (int i = 0; i < rows.Length; i++)
{
if (rows[i].dwLocalAddr == IPStringToInt(IP))
{
rows[i].dwState = (int)ConnectionState.Delete_TCB;
IntPtr ptr = GetPtrToNewObject(rows[i]);
int ret = SetTcpEntry(ptr);
}
}
}

/// <summary>
/// //Closes all connections to the remote port
/// </summary>
/// <param name="port">Port to close</param>
public static void CloseRemotePort(int port)
{
ConnectionInfo[] rows = getTcpTable();
for (int i = 0; i < rows.Length; i++)
{
if (port == ntohs(rows[i].dwRemotePort))
{
rows[i].dwState = (int)ConnectionState.Delete_TCB;
IntPtr ptr = GetPtrToNewObject(rows[i]);
int ret = SetTcpEntry(ptr);
}
}
}

/// <summary>
/// //Closes all connections to the local port
/// </summary>
/// <param name="port">Local port</param>
public static void CloseLocalPort(int port)
{
ConnectionInfo[] rows = getTcpTable();
for (int i = 0; i < rows.Length; i++)
{
if (port == ntohs(rows[i].dwLocalPort))
{
rows[i].dwState = (int)ConnectionState.Delete_TCB;
IntPtr ptr = GetPtrToNewObject(rows[i]);
int ret = SetTcpEntry(ptr);
}
}
}

/// <summary>
/// Close a connection by returning the connectionstring
/// </summary>
/// <param name="connectionstring">Connection to close</param>
public static void CloseConnection(string connectionstring)
{
try
{
//Split the string to its subparts
string[] parts = connectionstring.Split('-');
if (parts.Length != 4) throw new Exception("Invalid connectionstring - use the one provided by Connections.");
string[] loc = parts[0].Split(':');
string[] rem = parts[1].Split(':');
string[] locaddr = loc[0].Split('.');
string[] remaddr = rem[0].Split('.');
//Fill structure with data
ConnectionInfo row = new ConnectionInfo();
row.dwState = 12;
byte[] bLocAddr = new byte[] { byte.Parse(locaddr[0]), byte.Parse(locaddr[1]), byte.Parse(locaddr[2]), byte.Parse(locaddr[3]) };
byte[] bRemAddr = new byte[] { byte.Parse(remaddr[0]), byte.Parse(remaddr[1]), byte.Parse(remaddr[2]), byte.Parse(remaddr[3]) };
row.dwLocalAddr = BitConverter.ToInt32(bLocAddr, 0);
row.dwRemoteAddr = BitConverter.ToInt32(bRemAddr, 0);
row.dwLocalPort = htons(int.Parse(loc[1]));
row.dwRemotePort = htons(int.Parse(rem[1]));
//Make copy of the structure into memory and use the pointer to call SetTcpEntry
IntPtr ptr = GetPtrToNewObject(row);
int ret = SetTcpEntry(ptr);
if (ret == -1) throw new Exception("Unsuccessful");
if (ret == 65) throw new Exception("User has no sufficient privilege to execute this API successfully");
if (ret == 87) throw new Exception("Specified port is not in state to be closed down");
if (ret != 0) throw new Exception("Unknown error (" + ret + ")");
}
catch (Exception ex)
{
throw new Exception("CloseConnection failed (" + connectionstring + ")! [" + ex.GetType().ToString() + "," + ex.Message + "]");
}
}

/// <summary>
/// Get all connection
/// </summary>
/// <returns>Array of connection string</returns>
public static string[] Connections()
{
return Connections(ConnectionState.All);
}

/// <summary>
/// Get connections based on the state
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
public static string[] Connections(ConnectionState state)
{
ConnectionInfo[] rows = getTcpTable();

ArrayList arr = new ArrayList();

foreach (ConnectionInfo row in rows)
{
if (state == ConnectionState.All || state == (ConnectionState)row.dwState)
{
string localaddress = IPIntToString(row.dwLocalAddr) + ":" + ntohs(row.dwLocalPort);
string remoteaddress = IPIntToString(row.dwRemoteAddr) + ":" + ntohs(row.dwRemotePort);
arr.Add(localaddress + "-" + remoteaddress + "-" + ((ConnectionState)row.dwState).ToString() + "-" + row.dwState);
}
}

return (string[])arr.ToArray(typeof(System.String));
}

/// <summary>
/// The function that fills the ConnectionInfo array with connectioninfos
/// </summary>
/// <returns>ConnectionInfo</returns>
private static ConnectionInfo[] getTcpTable()
{
IntPtr buffer = IntPtr.Zero; bool allocated = false;
try
{
int iBytes = 0;
GetTcpTable(IntPtr.Zero, ref iBytes, false); //Getting size of return data
buffer = Marshal.AllocCoTaskMem(iBytes); //allocating the datasize

allocated = true;
GetTcpTable(buffer, ref iBytes, false); //Run it again to fill the memory with the data
int structCount = Marshal.ReadInt32(buffer); // Get the number of structures
IntPtr buffSubPointer = buffer; //Making a pointer that will point into the buffer
buffSubPointer = (IntPtr)((int)buffer + 4); //Move to the first data (ignoring dwNumEntries from the original MIB_TCPTABLE struct)
ConnectionInfo[] tcpRows = new ConnectionInfo[structCount]; //Declaring the array
//Get the struct size
ConnectionInfo tmp = new ConnectionInfo();
int sizeOfTCPROW = Marshal.SizeOf(tmp);
//Fill the array 1 by 1
for (int i = 0; i < structCount; i++)
{
tcpRows[i] = (ConnectionInfo)Marshal.PtrToStructure(buffSubPointer, typeof(ConnectionInfo)); //copy struct data
buffSubPointer = (IntPtr)((int)buffSubPointer + sizeOfTCPROW); //move to next structdata
}

return tcpRows;
}
catch (Exception ex)
{
throw new Exception("getTcpTable failed! [" + ex.GetType().ToString() + "," + ex.Message + "]");
}
finally
{
if (allocated) Marshal.FreeCoTaskMem(buffer); //Free the allocated memory
}
}

/// <summary>
/// Object pointer
/// </summary>
/// <param name="obj"></param>
/// <returns>Pointer</returns>
private static IntPtr GetPtrToNewObject(object obj)
{
IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(obj));
Marshal.StructureToPtr(obj, ptr, false);
return ptr;
}

/// <summary>
/// IP to Int
/// </summary>
/// <param name="IP">IP Address</param>
/// <returns>Integer</returns>
private static int IPStringToInt(string IP)
{
if (IP.IndexOf(".") < 0) throw new Exception("Invalid IP address");
string[] addr = IP.Split('.');
if (addr.Length != 4) throw new Exception("Invalid IP address");
byte[] bytes = new byte[] { byte.Parse(addr[0]), byte.Parse(addr[1]), byte.Parse(addr[2]), byte.Parse(addr[3]) };
return BitConverter.ToInt32(bytes, 0);
}

/// <summary>
/// IP int to String
/// </summary>
/// <param name="IP">IP</param>
/// <returns>String</returns>
private static string IPIntToString(int IP)
{
byte[] addr = System.BitConverter.GetBytes(IP);
return addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3];
}
}

Add the class. For getting all connections use the following code

string[] connections = DisconnectWrapper.Connections();

Once you get the connection, you can disconnect it as follows
DisconnectWrapper.CloseConnection(connection[0]);

You can get connection based on the state

string openConnections[] = DisconnectWrapper.Connections(DisconnectWrapper.ConnectionState.Established);

Hope this helps you.

Wednesday, February 24, 2010

Creating a Timer job in MOSS

First we need to have a class derived from SPJobDefinition

Below is the skeleton of that class.
namespace TimerNameSpace
{
#region Using
using System;
using System.Collections.Generic;  
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;  
using Microsoft.SharePoint.Utilities;
#endregion Using

/// <summary>
/// Timer service
/// </summary>
public class MyTimerService : SPJobDefinition
{
#region Constructor

/// <summary>
/// Initializes a new instance of the TimerService class
/// </summary>
public MyTimerService()
: base()
{
}

/// <summary>
/// Initializes a new instance of the MyTimerService class
/// </summary>
/// <param name="jobName">Job Title for the timer service</param>
/// <param name="webApp">Web appication for which this service will run</param>
public MyTimerService(string jobName, SPWebApplication webApp)
: base(jobName, webApp, null, SPJobLockType.ContentDatabase)
{
this.Title = "My Timer";
}
#endregion Constructor

#region Execute

/// <summary>
/// Overriden Execute method
/// </summary>
/// <param name="targetInstanceId">guid of the target object</param>
public override void Execute(Guid targetInstanceId)
{
try
{
/// Here the timer logic goes
}
catch (Exception ex)
{
//Log exception
}
}

#endregion Execute      
}
}
One this class is ready. Next thing we need to look into is creating a Feature. This feature will internally schedule the timer as a Job and runs it. Below is the snapshot of this class.

namespace TimerNameSpace
{
#region Namespace Inclusions
using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;  
#endregion Namespace Inclusions

/// <summary>
/// Class is feature receiver for feature to install approval timer service
/// </summary>
public class MyTimerFeature : SPFeatureReceiver
{
/// <summary>
/// Notifications job name
/// </summary>
public string MyTimerFeatureName = "MyTimerServiceFeature";

/// <summary>
/// Occurs after a Feature is installed.
/// </summary>
/// <param name="properties">An  object that represents the properties of the event.</param>
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}

/// <summary>
/// Occurs when a Feature is uninstalled.
/// </summary>
/// <param name="properties">An object that represents the properties of the event.</param>
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}

/// <summary>
/// Occurs after a Feature is activated.
/// </summary>
/// <param name="properties">An object that represents the properties of the event.</param>
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
// register the the current web
SPWeb web = (SPWeb)properties.Feature.Parent;

SPSite site = web.Site;

// make sure the job isn't already registered
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == this.MyTimerFeatureName)
{
job.Delete();
break;
}
}

MyTimerService myJob = new MyTimerService(this.MyTimerFeatureName, site.WebApplication);

SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 5;
schedule.Interval = 2;

myJob.Schedule = schedule;
myJob.Update();
}

/// <summary>
/// Occurs when a Feature is deactivated.
/// </summary>
/// <param name="properties">An object that represents the properties of the event.</param>
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
// current web
SPWeb web = (SPWeb)properties.Feature.Parent;

SPSite site = web.Site;

// delete the job
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == this.MyTimerFeatureName)
{
job.Delete();
break;
}
}
}
}
}
Similar to SPMinuteSchedule, there is Hourl Schedule also. Use the one as per your requirement.
Once this much is done, we need to create Feature.xml file for the feature we have built and paste it under the Features Folder (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES). Create a folder named MyTimerFeature and under this folder create Feature.xml with the following content.


<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
Creator="Amal Hashim"
Id="{76D2F200-5CA0-4882-B64F-9FC6208C1234}"
Title="MyTimerFeature"
Description="My Timer."
Scope="Web"
Hidden="FALSE"
Version="1.0.0.0"
ReceiverAssembly="MyTimer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=12344ab009fa4028"
ReceiverClass="TimerNameSpace.MyTimerFeature">
</Feature>
You can activate the feature using the Stsadm command as shown below.
stsadm -o installfeature -name MyTimerFeature

For checking whether the timer has activated successfully or not, you can go to the central admin page
Central Administration –> Operations –> Timer Job Status