Friday, January 30, 2009

Getting MAC address using .Net

What is MAC address

Media Access Control address (MAC address) is a unique address assigned to all network adapters or network cards.It is normally expressed as group of 6 two digit hex numbers.ie MAC address is of length 48bits or 6 bytes.

Eg:00-0B-CD-95-CA-8F

You can see your network card's MAC address by typing the command

ipconfig -all

More details here

Retrieving MAC address using C#.Net

We can retrieve MAC address using .Net only through Management namespace.You can get a basic idea about classes in Management namespace by referring below links.

http://msdn.microsoft.com/en-us/library/system.management.aspx

System.Management.ManagementObjectSearcher Class [Articles]

Before going to work with System.Management namespace add a reference to the assembly System.Management which contains the said namespace.

There are 2 methods to find out the MAC address using Management classes.

1.Using the class ManagementClass

This is the simplest method which creates an object of ManagementClass by passing the string parameter "Win32_NetworkAdapterConfiguration" through it's constructor.Then get the ManagementObjectCollection using the method GetInstances().Once we get the collection we can iterate through it and find the MAC address which is IP enabled.

private string GetMACUsingManagementClass()
{
ManagementClass mgmtClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection CollectionOfResults = mgmtClass.GetInstances();
foreach (ManagementObject obj in CollectionOfResults)
{
if ((bool)obj.Properties["IPEnabled"].Value)
{
string mac = obj.Properties["MACAddress"].Value.ToString();
return mac;
}
}
return string.Empty;
}


2.Using Query



This method employs an query to find out correct ManagementObject.The query is similar as any sql query.We need to create object of ManagementObjectSearcher class by passing the query through it's constructor.Then call it's Get method which gives ManagementObjectCollection.This collection can be iterated to get the MAC address.



private string GetMACUsingQuery()
{
ManagementObjectSearcher Searcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=TRUE");
ManagementObjectCollection CollectionOfResults = theSearcher.Get();
foreach (ManagementObject CurrentObject in CollectionOfResults)
{
string macAdd = CurrentObject.Properties["MACAddress"].Value.ToString();
return macAdd;
}
return string.Empty;
}


VB.Net Code to find out MAC address



Method 1 : Management class



Private Function GetMACUsingManagementClass() As String
Dim
mgmtClass As ManagementClass = New ManagementClass("Win32_NetworkAdapterConfiguration")
Dim CollectionOfResults As ManagementObjectCollection = mgmtClass.GetInstances()
For Each objec In CollectionOfResults
If CType(objec.Properties("IPEnabled").Value, Boolean) Then
Dim
mac As String = objec.Properties("MACAddress").Value.ToString()
Return mac
End If
Next
objec
Return String.Empty
End Function


Method 2: Using query



Private Function GetMACUsingQuery() As String

Dim
Searcher As New ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
Dim CollectionOfResults As ManagementObjectCollection = Searcher.Get()
For Each CurrentObject In CollectionOfResults
Dim macAdd As String = CurrentObject.Properties("MACAddress").Value.ToString()
Return macAdd
Next CurrentObject
Return String.Empty
End Function



A WIME(Works In My Environment ie P4 32Bit+Vista+VS2008) Sample can be downloaded from here.



NB: This retrieves MAC address of local system under local privileges.If you need to retrieve MAC address of a remote system you can try following links.



Get MAC address of client machine using C#



Developersdex.com - Get the MAC Address of your Network Card (C# Code)



win32 programmer wmi How can I obtain the MAC address of a remote

Thursday, January 22, 2009

Designing and developing an Image gallery with thumbnails in ASP.net - Part 1

I have seen frequently, people asking about image gallery implementation.In most cases they are confused in handling the thumbnails.They are not sure whether they need to store a separate small image for thumbnail or use the original one in MBs.Even if they decide to use single image for thumbnail as well as original display they do the resizing at the client side which didn't reduce bandwidth usage.ie the image of size 1 or 2MB is downloaded to the client to show thumbnail of size 100x100.

Solution.

Here comes the importance of .net image libraries and the ability to directly write bitmap images into output stream as if the request is an ordinary image.

My last post describes how we can directly write images into asp.net stream.We can use the same technique here with some changes.In the earlier post the image was just writing directly into the stream.Here we will be getting the thumbnail of that image which is being returned.This uses the method GetThumbnailImage available in the Image class.

Architecture

The ImageGallery contains 3 modules.

  1. Uploading:This uploads the given image file into server and saves in the server folder named ImageStore.The metadata such as Name,Description etc are stored in an xml file called Files.xml
  2. Thumbnails display: Thumbnails are displayed in a DataList control.The thumb image url will be like '../Thumb.aspx?name=' to achieve the desired goal.
  3. Selected image display : On clicking thumbnail, it will display the corresponding image in full size with all details.

Thumbnails display

The first and third modules are very easy.There is nothing special to do.But the thumbnail display needs special attention.As we discussed earlier we have to reduce the bandwidth.For that we are resizing the image using C# code.So we can't directly access the image like '../ImageStore/test.jpg'.The Thumbnail.aspx does this using the technique mentioned above.It doesn't have any aspx tags except page directive.It just writes the image requested through query string to output stream after reducing it's size.

public partial class Thumbnail : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["name"] != null)
{
string name = Request.QueryString["name"];
Bitmap bitmap = new Bitmap(Server.MapPath("ImageStore/"+name));
System.Drawing.Image image= bitmap.GetThumbnailImage(100,100,new System.Drawing.Image.GetThumbnailImageAbort(thumb) ,IntPtr.Zero);
image.Save(Response.OutputStream,ImageFormat.Jpeg);
}
}
bool thumb()
{
return true;
}
}



Now in the thumbnail list, check the size of each thumbnail.It will be some KBs...



Sample can be downloaded from here which is done using VS2008 and .Net2.0



This works fine for an experimental purpose.But won't in a production environment.Every one can access the Files.xml using it's URL(can be fixed using Database).Anybody can use the images hosted here, in their sites using the image URL.They can download images and upload into their sites without any overhead because these images doesn't have any protection methods such as watermark or signs.



The second part will be dealing with these concerns.

Thursday, January 15, 2009

Writing images directly into ASP.Net response stream

This is for all who wish to use as follows

<img src="image.aspx?text=yourtext"/>

in order to display your text beautifully as an image.

Implementation

This makes use of the concept of managed gdi drawing and direct stream handling.Here are the steps

  1. Create a new Page named Image.aspx.
  2. Remove its contens except the page directive.
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Image.aspx.cs" Inherits="TextImageGenerator.Image" %>



  3. In the Page_Load handler do the following



    1. Create object of Bitmap


    2. Get Graphics object from the bitmap.


    3. Draw strings into the graphics object


    4. Save the bitmap into the output stream




Code



protected void Page_Load(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap(100, 100);
Graphics g = Graphics.FromImage(bitmap);
g.DrawString(Request.QueryString["text"] == null ? "joymon@gmail.com" : Request.QueryString["text"], SystemFonts.DefaultFont, Brushes.Red, new PointF(0, 0));
bitmap.Save(Response.OutputStream, ImageFormat.Jpeg);
}


Future enhancements




  • Changing size of the bitmap according to the length of the text and font styles using MeasureString.


  • Adding support for font styles and other parameters.



Sample can be downloaded here.

Storing and retrieving data in web.config

I came to the concept of using web.config as storage when I did a small application which deals with small amount of data.

The database is very costly compared to the size of the application.I was in need of some KBs for data storage.

The other option was to store data in text file.But there is one security issue.Anybody can download the file using it's URL.This can be fixed by writing some more code like HttpHandlers.But that will make the application more complex.

So decided to go with web.config as Data source.

Here is the code to store data into web.config.

//Opens the web.config at root level. 
Configuration cfg = WebConfigurationManager.OpenWebConfiguration("~");
//Change value
cfg.AppSettings.Settings["options"].Value = "hello";
//Save the configuration
cfg.Save();


Using web.config as data source is applicable only if the size of the data is very small (Some KBs).

Tuesday, January 13, 2009

Setting Text into ASP.Net Password TextBox

In the normal case if you set any value to Text property of TextBox which is in Password mode it won't get displayed.

textBoxPass.TextMode = TextBoxMode.Password;
textBoxPass.Text = "mypassword"; //This won't work

Here is one method to assign text into TextBox in password mode.

This make use of the attributes collection to set the value.

textBoxPass.TextMode = TextBoxMode.Password;
textBoxPass.Attributes.Add("value", "mypassword");
 

Reading Image from Excel file using C# .Net

Office Primary Interop Assemblies

These assemblies/dlls contain classes which help us to work or interact with the Office files through our .Net programs.They maintain clean object model which represents the structure of office files like .xls,.doc etc...To work with these different office file formats we have to use separate office interop assemblies.

These assemblies are different for different office versions.OfficeXP uses 10.0.0.0, Office2003 uses the interop version of 11.0.0.0 and Office 2007 uses the version of 12.0.0.0 etc...

More details here.

Microsoft Excel interop assembly.

This assembly gives access to excel files.We can interact with the excel workbooks,worksheets,cells etc.We can do a bunch of operations such as creating a work book , referring the cells inside a sheet and lot more using this.The main interop dll of excel is Microsoft.Office.Interop.Excel.dll .It contains the excel object model.The main classes which we need to interact are ApplicationClass,Workbook & Worksheet

Application flow

If you want to use the excel interop you have to refer the concerned assembly in your application.Then create instance of ApplicationClass.Using the ApplicationClass object you can create excel Workbook which is equivalent to the actual .xls or .xlsx file.Workbook contains a collection of Worksheets which again contains cells,rows and columns.We can set or get the values from these cells as per the requirement.

Some links to create and read Excel files using office interop.

Creation

Reading

Full list

The normal reading of cells will go smoothly with these things.But when we come to reading of images we can not do that very easily because the images are not bound to the cells.More specifically ,they are bound to the sheet.Here is one method to read images from worksheet

 

Basic idea of Reading Image

Let us first check the object model.These is no property collection in the Worksheet interface to get images directly.We have to use the method

workSheet.Pictures("pictureName")

Thus this method need the name of the image.We have to iterate through the WorkSheet.Shapes collection, if you don't know the image name in advance.


Once we execute the Pictures method we gets the image as object Picture interface.This again don't have any direct method which returns the image as useful.


We have to copy the image into clipboard using the method

pict.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
 

Yes we now have the image in clipboard.Get the image from there and show or save as per the requirement.

if (Clipboard.ContainsImage())
{
Image img=Clipboard.GetImage();
pictureBox.Image = img;
}

Sample


Here is a small sample which reads first image from a .xls file and shows in a picture box.I have used Office 2003 interop assemblies (11.0.0.0)


ExcelImageRead.zip

Monday, January 5, 2009

CodeDom and Picture to exe converter

CodeDom

If you have ever though of creating an exe or assembly from .net program, CodeDom is your answer.In simple words CodeDom is the memory representation of .Net code which can be saved or compiled afterwards.

CodeDom contains classes which represent each and every element of .Net code.for example CodeNamespace class represents a namespace declaration and CodeConstructor represents a constructor.More details here.

We can build the code model using these classes.Once we complete building the CodeDom model we can either get the source code or compile that code to get executable.

The CodeDom can be compiled or generated using any .net compiler which implements CLR specifications.For that we have to create a code provider first which can be of C Sharp or VB.net.Provider will give a generator object for code generation and compiler object to compile the CodeDom.

Code to create CodeDom

CodeNamespace myNamespace = new CodeNamespace();
CodeTypeDeclaration myclass = new CodeTypeDeclaration();
myNamespace.Types.Add(myclass);



//Add more classes here



Code to Generate Source Code in C#



CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeGenerator codeGen=provider.CreateGenerator("mypgm.cs");
codeGen.GenerateCodeFromNamespace(myNamespace, textWriter, options);



Code to compile CodeDom using C# compiler



CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
CodeCompileUnit myCodeunit = new CodeCompileUnit();
myCodeunit.Namespaces.Add(myNamespace);
CompilerParameters parameters = new CompilerParameters();


parameters.OutputAssembly="mypgm.exe";
compiler.CompileAssemblyFromDom(parameters, myCodeunit);


Picture to exe converter



Now the things are clear.We can create an exe using code dom which have the given picture embedded in it and a windows form in that application can display the same from resource.Its simple and standalone.The flow is as follows




  1. Code a 'Form' derived class named 'Pic2Exe' which shows have a piturebox and gets picture from resource stream.This should also contain Main method to start execution.


  2. Get the path to the picture which need to be converted as exe


  3. Create object of class Compilerparameters and set appropriate paramaeters.(For details see sample)


  4. Embedd the input picture through the CompilerParameters object.


  5. Create object of CSharpCodeProvider class and get the compiler object.


  6. Compile the Pic2Exe class using the compiler object.



If you are confused about the settings and flow please see the sample here.



Future enhancements




  • Modify the Pic2Exe (Which is responsible for showing the image from resource) to have Zooming and Panning.


  • It can be modified as a slide show application.


  • Can be used to protect your video files if your target audience don't know about reflector.