?
Solved

Using progress bar while scanning folders

Posted on 2006-03-30
14
Medium Priority
?
1,741 Views
Last Modified: 2008-01-09
I have simple application which is scanning specific folder for all of the files which contains in it and subfolders. Also it takes the ouput and add it to the list box. I have a question... How can I implement using progressbar so I can actually see how far my application is from beeing done. Thank you...

HERE IS THE CODE OF THAT APPLICATION
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
using System;
using System.IO;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace ListFiles
{
      public class Form1 : System.Windows.Forms.Form
      {
            public System.Windows.Forms.Button btnScan;
            public System.Windows.Forms.ListBox lstFiles;
            private System.ComponentModel.IContainer components;

            public Form1()
            {
                  InitializeComponent();
            }

            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if (components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            private void InitializeComponent()
            {
                  this.btnScan = new System.Windows.Forms.Button();
                  this.lstFiles = new System.Windows.Forms.ListBox();
                  this.SuspendLayout();
                  this.btnScan.Location = new System.Drawing.Point(536, 368);
                  this.btnScan.Name = "btnScan";
                  this.btnScan.TabIndex = 0;
                  this.btnScan.Text = "&Scan";
                  this.btnScan.Click += new System.EventHandler(this.btnScan_Click);
                  this.lstFiles.HorizontalScrollbar = true;
                  this.lstFiles.Location = new System.Drawing.Point(8, 8);
                  this.lstFiles.Name = "lstFiles";
                  this.lstFiles.ScrollAlwaysVisible = true;
                  this.lstFiles.Size = new System.Drawing.Size(600, 355);
                  this.lstFiles.TabIndex = 1;
                  this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
                  this.ClientSize = new System.Drawing.Size(616, 395);
                  this.Controls.Add(this.lstFiles);
                  this.Controls.Add(this.btnScan);
                  this.Name = "Form1";
                  this.Text = "Form1";
                  this.ResumeLayout(false);
            }
            #endregion
            [STAThread]
            static void Main()
            {
                  Application.Run(new Form1());
            }

            private void btnScan_Click(object sender, System.EventArgs e)
            {
                  DirectoryInfo dir = new DirectoryInfo(@"C:\Program Files\Adobe\");
                  //Pass the Directory for displaying the contents
                  getDirsFiles(dir);
            }

            //this is the recursive function
            public void getDirsFiles(DirectoryInfo d)
            {
                  //create an array of files using FileInfo object
                  FileInfo [] files;
                  //get all files for the current directory
                  files = d.GetFiles("*.*");

                  //iterate through the directory and print the files
                  foreach (FileInfo file in files)
                  {
                        //get details of each file using file object
                        String fileName = file.FullName;
                        String fileSize = file.Length.ToString();
                        String fileExtension =file.Extension;
                        String fileCreated = file.LastWriteTime.ToString();

                        lstFiles.Items.Add(fileName + " " + fileSize +
                              " " + fileExtension + " " + fileCreated);
                  }            
                  
                  DirectoryInfo [] dirs = d.GetDirectories("*.*");
 
                  foreach (DirectoryInfo dir in dirs)
                  {
                        lstFiles.Items.Add("--------->> " + dir.Name.ToString());
                        getDirsFiles(dir);
                  }
            }


      }
}

-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------
END OF SOURCE CODE!!!
0
Comment
Question by:g00r00
  • 5
  • 5
  • 2
  • +2
14 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 16340649
0
 
LVL 13

Expert Comment

by:devsolns
ID: 16341947
Since you dont know ahead of time how many files there are or how long access to each would take its not really possible to implement an accurate progress bar.  To show progress you need to know how long the end result will take and that cant be known.

The best approach would be to implemnt a progress bar with style "continuous" just like windows file search does.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 16342584
Like devsolns said, you can't have a proper progress bar since you don't know how many items a recursive search will find.  If you don't want a "continous" progress bar then you would need to use a two pass system.  The first pass would simply do a recursive search and only COUNT the files.  Then you can use that information in the second pass to update a progress bar.  Of course, there isn't any way to proper way display progress while counting so you could use a "continous" progress bar for that portion...
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 96

Expert Comment

by:Bob Learned
ID: 16343174
I had this VB.NET class lying around, and until recently I had forgotten that I had it.  It uses Micro$oft Log Parser 2.2 to do a file query, and you will be quite amazed at the speed vs. doing a file scan.   It was easily convertible to C#.

WindowsFileQuery class
===============

/* You must download and install Logparser from Microsoft:
  http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&displaylang=en

 Read about Logparser here:
  http://www.microsoft.com/technet/community/columns/scripts/sg0105.mspx

 Add a COM reference to 'MS Utility 1.0 Type Library – LogParser Interfaces collection'.
 
*/

using System;
using System.Collections;
using System.IO;
using MSUtil;

public class WindowsFileQuery
{

  public static FileInfo[] FindFiles(string folderPath, string searchPattern, bool isRecursive)
  {
    // Create a parser object.
    LogQueryClass parser = new LogQueryClass();

    // Configure the input format for a recursive search.
    COMFileSystemInputContextClass inputFormat = new COMFileSystemInputContextClass();
    inputFormat.recurse = Convert.ToInt32(isRecursive);

    // Configure the output format.
    COMNativeOutputContextClass outputFormat = new COMNativeOutputContextClass();
    outputFormat.rtp = -1;

    // Perform a file system query.
    string query = string.Format("Select Name, Path FROM '{0}\\{1}'", folderPath, searchPattern);

    // Get the recordset for the query
    ILogRecordset searchData = parser.Execute(query, inputFormat);

    // Collect the file info instances for each file.
    ArrayList listFiles = new ArrayList();

    while (!searchData.atEnd())
    {

      // Get each file entry record.
      ILogRecord record = searchData.getRecord();

      // Get the file path from the record.
      string fileName = (string)record.getValue("Path");

      // Skip '.' and '..' entries.
      if (!fileName.StartsWith("."))
      {
        listFiles.Add(new FileInfo(fileName));
      }

      // Go to the next record.
      searchData.moveNext();
    }

    return (FileInfo[])listFiles.ToArray(typeof(FileInfo));
  }

}

Test Code
=======
    System.Text.StringBuilder builder = new System.Text.StringBuilder();

    foreach (System.IO.FileInfo file in WindowsFileQuery.FindFiles(@"C:\", "*.xml", true))
      builder.Append(file.FullName + "\r\n");

    return builder.ToString();

Bob
0
 

Author Comment

by:g00r00
ID: 16343807
Hey devsolns and Idle_Mind,

 Yeah continous bar will work for me. Can you guys explain me how I can create same countinues bar as microsoft have in its search???  Thank you,
0
 

Author Comment

by:g00r00
ID: 16343820
TheLearnedOne,

Utility that I am creating is not searching for specific file or file type. It needs to scan though every single file in directory and subdirectorys. Thanks
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16343827
Microsoft does it with an AVI file.  You could do it with an animated GIF, but with tight loops animated GIFs doesn't get updated correctly.

Bob
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16343842
Yep, like *.*, recursive = yes.  It doesn't have to be a specific file, it can be all files.  It is fast, that's the point, so you wouldn't need progress bars.

Bob
0
 

Author Comment

by:g00r00
ID: 16343869
AlexFM,

Thanks for respond, But the article that you give is about ways to implement multithreading programs and there is nothing about showing progress bar. Especially when its not possible unless u know how many files there are in the folder.
0
 

Author Comment

by:g00r00
ID: 16343916
TheLearnedOne,

Will it require user to install any additional software in order to use my utility??? I need to scan all harddrive so probably I still will need some kind of progress bar.

>>>Microsoft does it with an AVI file
How can I do something like that?

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16343930
Yes, it is a COM component (LogParser):

 /* You must download and install Logparser from Microsoft:
  http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&displaylang=en

 Read about Logparser here:
  http://www.microsoft.com/technet/community/columns/scripts/sg0105.mspx

 Add a COM reference to 'MS Utility 1.0 Type Library – LogParser Interfaces collection'.
 
*/

Bob
0
 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 500 total points
ID: 16344614
I think Bob has a great tool there if you wish to implement it.  The proper way to "fix" your current problem would be to multithread it which is the direction AlexFM was pointing you.

Without making things overly complicated though...  

You can speed up the process by calling BeginUpdate and EndUpdate on your ListBox:

          private void btnScan_Click(object sender, System.EventArgs e)
          {
               DirectoryInfo dir = new DirectoryInfo(@"C:\Program Files\Adobe\");
               //Pass the Directory for displaying the contents

               lstfiles.BeginUpdate();
               getDirsFiles(dir);
               lstfiles.EndUpdate();
          }

For simplicity, you can simply make a progressbar go up to 100% and then reset and repeat.

Add Application.DoEvents() inside your getDirsFiles() sub and then add a Timer control to your form.  In the Timer event code, simply increment the Value of the progressbar.  If it has reached its maximum then put it back at its minimum.  The DoEvents() call will allow the Timer code to fire and be processed.

Again, this is if you are going to "fix" your current approach.  If you're going to use threads or Bobs approach then don't bother with these suggestions...
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 16344702
I haven't had much occasion to use it, since it requires a COM reference, but it soooo fast that I tried to make it fit this situation.  If it doesn't work, then hey, it's cool ;)

Bob
0
 

Author Comment

by:g00r00
ID: 16367919
Thank you everybody for participation..



>>>>>I haven't had much occasion to use it, since it requires a COM reference

same problem here.... so i'll just do it regularly
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Screencast - Getting to Know the Pipeline
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question