Click here to Skip to main content
15,881,882 members
Articles / Desktop Programming / Windows Forms
Article

Search Engine for Local Area Network ( LAN )

Rate me:
Please Sign up or sign in to vote.
4.84/5 (16 votes)
25 Jan 2007CPOL3 min read 175.5K   6K   118   66
Searches for files and folders shared over a Local Area Network ( LAN )

Sample Image - lanscan.gif

Introduction

LanScan is a tool designed for the purpose of searching for files and folders which are shared over a Local Area Network. It is particularly useful in organizations where a lot of folders are shared on individual systems.

At the outset, I would like to declare that I have used a library designed by Robert Deeming. Robert Deeming has explained the library in this article : http://www.codeproject.com/cs/internet/networkshares.asp. I would like to thank him for sharing such a wonderful piece of work.

Background

This article assumes that you have a reasonable understanding of C#, basic understanding of threads and general knowledge of local area networks.

Using the code

Here's how the application works. You specify an IP range. The tool searches for live hosts. It then determines the list of folders shared by each system and looks for files (according to a keyword that you specify).

The first point of interest would be - how to determine whether a system with a particular IP address is active. This can be achieved using the Ping class defined in the namespace System.Net.NetworkingInformation. The Ping class offers both synchronous and asynchronous methods to detect whether a remote host is reachable. I would be using the asynchronous method because I don't want the system to halt whenever I ping a remote host. Here's the code for it.

C#
Ping pingSender = new Ping();
// When the PingCompleted event is raised,
// the PingCompletedCallback method is called.
pingSender.PingCompleted += new PingCompletedEventHandler(AddHost);

// Wait 1000 milliseconds for a reply.
int timeout = 1000 ;

// Create a buffer of 32 bytes of data to be transmitted.
byte[] buffer = new byte[] { 100 };

// Set options for transmission:
// The data can go through 64 gateways or routers
// before it is destroyed, and the data packet
// cannot be fragmented.
PingOptions options = new PingOptions(64, true);

pingSender.SendAsync("192.168.209.178", timeout, buffer, options, null);

AddHost is called when a Ping operation is complete. Here's how to check the result of the Ping operation.

C#
private void AddHost(object sender, PingCompletedEventArgs e)
{
        PingReply reply = e.Reply;
        if (reply == null)
            return;
        if (reply.Status == IPStatus.Success)
        {
            // Code to be execute if a remote host
            // is found to be active.
            // reply.Address returns the address.
        }
}

Now the second point of interest would be how to list the shared folders for an active remote host. Here's where Robert Deeming's library comes into the picture. Two classes defined in this library are ShareCollection and Share. ShareCollection is a class capable of determining the shared folders for a given IP Address and storing the information in objects of type Share. Given below is the code to explain the working.

C#
ShareCollection sc = new ShareCollection(reply.Address.ToString());
foreach (Share s in sc)
{
    // Do what you want with each individual Share object.
    // s.NetName returns the name of the shared folder.
    // s.ShareType return the type of share.
}

Lastly, to search for files in a particular share, you have to use recursion. The basic logic is to begin in a shared folder. Process the names of each file in that folder. Once this is done, recursively apply the same logic to each sub-directory until no files or folders remain. A problem with this approach arises if the directory structure is too deep. In this case, the tool would waste a lot of time looking for files in a particular share. To prevent this, we employ the feature of search depth. Search depth is an integer variable which is incremented by one everytime the search moves to a folder a level deeper in the directory tree. Whenever the variable exceeds a particular value (generally a small integer like 2 or 3) the recursion stops and the function returns. Here's the code to explain the point.

C#
ShareCollection sc = new ShareCollection(reply.Address.ToString());
foreach (Share share in sc)
{
    RecursiveSearch(share.ToString(), 0);
}

Then we declare the recursive function:

C#
private void RecursiveSearch(string path,int depth)
{
    DirectoryInfo di = new DirectoryInfo(path);
    if (!di.Exists)
        return;
    depth++;
    // searchDepth is a static variable defined in a static class Settings
    // Used like a global variable. Typical value is 2
    if(depth>Settings.searchDepth)
        return;

    // Keyword to look for
    string keyword=Settings.keyword;
    if (di.Name.ToLower().Contains(keyword.ToLower()))
    {
        AddRow(name,parent, "Folder");
    }
    foreach (FileInfo file in di.GetFiles())
    {
        if (file.Name.ToLower().Contains(keyword.ToLower()))
        {
            AddRow(file.Name, di.FullName,size);
        }
    }
    foreach (DirectoryInfo subdir in di.GetDirectories())
    {
        RecursiveSearch(subdir.FullName, depth);
    }
}

Well...that's all there is to it. Of course, there are a lot of interface design issues which I am not discussing here because explaining GUI is not the objective behind this article. In addition, there is a lot of exception handling and other minor details which I choose not discuss. After all, something should be left to imagination. Nevertheless you can find it all in the source code(see the link at the top of the page).

Points of Interest

In every little project which I have done, I find that there is a bit of weird coding that you can't understand (rather you don't want to), you don't want to use it, but you have to and you do. It seems that Windows Form Controls are not very thread friendly, so whenever you try to update a Form Control from a thread other that the thread you created, you get unexpected results. So here's how to get away with it. This code shows how to add rows to a table in a dataGridView(dgvResult irrespective of the thread. This method can be modified to handle any other Windows Form Control.

C#
delegate void SetCallback(params object[] objects);
private void AddRow(params object[] objects)
{
    if (this.dgvResult.InvokeRequired)
    {
        SetCallback d = new SetCallback(AddRow);
        this.Invoke(d, new object[] {objects});
    }
    else
    {
        (dgvResult.DataSource as DataTable).Rows.Add(objects);
    }
}

More information about this problem can be found in this article by Rüdiger Klaehn http://www.codeproject.com/csharp/threadsafeforms.asp

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
I am a Software Developer from Hyderabad, India

My MSDN Blog

My Windows Phone Apps

Comments and Discussions

 
GeneralRe: what kind of ping? Pin
AmitDey5-Jun-07 5:04
AmitDey5-Jun-07 5:04 
GeneralRe: what kind of ping? Pin
samentu5-Jun-07 6:41
samentu5-Jun-07 6:41 
GeneralRe: what kind of ping? Pin
AmitDey5-Jun-07 7:06
AmitDey5-Jun-07 7:06 
GeneralRe: what kind of ping? Pin
samentu5-Jun-07 22:39
samentu5-Jun-07 22:39 
QuestionUpdated.. 24-nov ?? Pin
Sixcode25-Nov-06 7:20
Sixcode25-Nov-06 7:20 
AnswerRe: Updated.. 24-nov ?? Pin
AmitDey25-Nov-06 15:29
AmitDey25-Nov-06 15:29 
GeneralRe: Updated.. 24-nov ?? Pin
Sixcode25-Nov-06 23:55
Sixcode25-Nov-06 23:55 
GeneralRe: Updated.. 24-nov ?? Pin
AmitDey26-Nov-06 0:31
AmitDey26-Nov-06 0:31 
I must admit that there are some issues with the thread handling.
I couldnot get them right. Even after calling the abort function for a thread the thread continues execution.

I believe that this is the source of the bug. Try this before starting a new search go to main menu LanScan>Kill Threads.

I hope it helps.

Regards
Amit Dey.
GeneralRe: Updated.. 24-nov ?? Pin
Sixcode26-Nov-06 5:16
Sixcode26-Nov-06 5:16 
Questionaccess to linux ? Pin
codecover14-Nov-06 5:54
codecover14-Nov-06 5:54 
AnswerRe: access to linux ? Pin
AmitDey14-Nov-06 7:34
AmitDey14-Nov-06 7:34 
GeneralSilly question ... Pin
Martin081514-Nov-06 4:27
professionalMartin081514-Nov-06 4:27 
GeneralRe: Silly question ... Pin
AmitDey14-Nov-06 5:03
AmitDey14-Nov-06 5:03 
GeneralNo network activity, no additional threads (WAS: Re: Silly question ...) Pin
Martin081514-Nov-06 5:17
professionalMartin081514-Nov-06 5:17 
GeneralRe: No network activity, no additional threads (WAS: Re: Silly question ...) Pin
AmitDey14-Nov-06 5:32
AmitDey14-Nov-06 5:32 
GeneralRe: No network activity, no additional threads (WAS: Re: Silly question ...) Pin
Martin081514-Nov-06 6:03
professionalMartin081514-Nov-06 6:03 
GeneralRe: No network activity, no additional threads (WAS: Re: Silly question ...) Pin
AmitDey14-Nov-06 7:32
AmitDey14-Nov-06 7:32 
GeneralRe: No network activity, no additional threads (WAS: Re: Silly question ...) Pin
Martin081514-Nov-06 8:57
professionalMartin081514-Nov-06 8:57 
GeneralRe: No network activity, no additional threads (WAS: Re: Silly question ...) Pin
AmitDey15-Nov-06 21:51
AmitDey15-Nov-06 21:51 
GeneralRe: No network activity, no additional threads (WAS: Re: Silly question ...) Pin
AmitDey18-Nov-06 6:38
AmitDey18-Nov-06 6:38 
GeneralNice job Pin
Niiiissssshhhhhuuuuu12-Nov-06 16:59
Niiiissssshhhhhuuuuu12-Nov-06 16:59 
GeneralRe: Nice job Pin
AmitDey13-Nov-06 5:36
AmitDey13-Nov-06 5:36 
GeneralRe: Nice job Pin
AmitDey13-Nov-06 5:39
AmitDey13-Nov-06 5:39 
GeneralMasked Text Box error Pin
Andreas Botsikas11-Nov-06 3:37
Andreas Botsikas11-Nov-06 3:37 
GeneralRe: Masked Text Box error Pin
AmitDey11-Nov-06 4:18
AmitDey11-Nov-06 4:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.