Link to home
Start Free TrialLog in
Avatar of g00r00
g00r00

asked on

Using progress bar while scanning folders

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!!!
Avatar of AlexFM
AlexFM

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.
Avatar of Mike Tomlinson
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...
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
Avatar of g00r00

ASKER

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,
Avatar of g00r00

ASKER

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
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
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
Avatar of g00r00

ASKER

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.
Avatar of g00r00

ASKER

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?

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
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
Avatar of g00r00

ASKER

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