Solved

Delete from ListBox broken shortcuts in C# WPF

Posted on 2014-01-08
13
637 Views
Last Modified: 2014-01-12
Hi, this code works and what it does is basically search in all folders for shortcuts based on the file extension of ".lnk" and then list the files found in the list box.

What I want now, is:

1.

delete the files found based on selections (multiple or singular).  

2.

display the item count in the list box

3.

  sorting so that the directories are listed alphabetically - currently its out of order  

I used to be able to do this in Windows form using the iwshruntimelibrary based on TargetPath not found based on the search files found. However, this library is nonexistent for WPF.

Any thoughts how I can achieve this? Here's the working code.
 // Holds a collection of all the found files
        ObservableCollection<String> lstFilesFound = new ObservableCollection<string>();

        // Property used by the list box to display the list of files
        public ObservableCollection<string> FilesFound { get { return lstFilesFound; } }

        private void Button3_Click(object sender, RoutedEventArgs e)
        {
            Splash sp = new Splash();
            sp.Show();
            DirSearch(@"C:\\");   
            MessageBox.Show("Search Completed");
            sp.Close();
             
        }

        void DirSearch(string sDir)
        {
             
            Stack<string> dirs = new Stack<string>(20);

            if (!System.IO.Directory.Exists(sDir))
            {
                throw new ArgumentException();
            }
            dirs.Push(sDir);

            while (dirs.Count > 0)
            {
                string currentDir = dirs.Pop();
                string[] subDirs = null;
                try
                {
                    subDirs = System.IO.Directory.GetDirectories(currentDir);
                }
                
                catch (UnauthorizedAccessException e)
                {
                    
                    continue;
                }
                catch (System.IO.PathTooLongException e)
                {

                    
                    continue;
                }
                catch (System.IO.DirectoryNotFoundException e)
                {
                   
                    continue;
                }

                string[] files = null;
                try
                {
                    files = System.IO.Directory.GetFiles(currentDir, "*.lnk");
                }
                catch (System.IO.PathTooLongException e)
                {
                    
                    continue;
                }
                catch (UnauthorizedAccessException e)
                {
                     
                    continue;
                }
                catch (System.IO.DirectoryNotFoundException e)
                {
                   
                    continue;
                }  
                foreach (string file in files)
                {
                    try
                    {
                       
                        System.IO.FileInfo fi = new System.IO.FileInfo(file);
                        lstFilesFound.Add(fi.FullName);
                    }
                    catch (System.IO.PathTooLongException e)
                    {
                        
                        continue;
                    }
                    catch (System.IO.FileNotFoundException e)
                    {
                        
                        continue;
                    }
                }

                
                foreach (string str in subDirs)
                    dirs.Push(str);

            }
        }

Open in new window

0
Comment
Question by:TeknikDev
  • 7
  • 6
13 Comments
 
LVL 13

Expert Comment

by:Naman Goel
ID: 39767601
Here is code for the same:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            FileShortcutsListBox.SelectionMode = SelectionMode.Multiple;
            ManualResetEvent mr = new ManualResetEvent(false);
            new DirSearchDelegate(DirSearch).BeginInvoke(@"c:\temp", mr, null, null);
            mr.WaitOne();

            FileShortcutsListBox.ItemsSource = lstFilesFound;
            FileShortcutsListBox.Items.SortDescriptions.Add(
            new System.ComponentModel.SortDescription(String.Empty,
            System.ComponentModel.ListSortDirection.Ascending));
        }

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
           

           foreach (var item in FileShortcutsListBox.SelectedItems)
           {
               IWshRuntimeLibrary.IWshShell shell = new IWshRuntimeLibrary.WshShell();

               IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(item.ToString());

              FileInfo fi = new FileInfo(shortcut.TargetPath);
              fi.Delete();
               
           }
        }

        // Holds a collection of all the found files
        static ObservableCollection<String> lstFilesFound = new ObservableCollection<string>();

        // Property used by the list box to display the list of files
        public static ObservableCollection<string> FilesFound { get { return lstFilesFound; } }

        delegate void DirSearchDelegate(string sDir,ManualResetEvent mr);

        static void DirSearch(string sDir, ManualResetEvent mr)
        {
            try
            {
                Stack<string> dirs = new Stack<string>(20);
                if (!System.IO.Directory.Exists(sDir))
                {
                    throw new ArgumentException();
                }
                dirs.Push(sDir);

                while (dirs.Count > 0)
                {
                    string currentDir = dirs.Pop();
                    string[] subDirs = null;
                    try
                    {
                        subDirs = System.IO.Directory.GetDirectories(currentDir);
                    }

                    catch (UnauthorizedAccessException e)
                    {

                        continue;
                    }
                    catch (System.IO.PathTooLongException e)
                    {


                        continue;
                    }
                    catch (System.IO.DirectoryNotFoundException e)
                    {

                        continue;
                    }

                    string[] files = null;
                    try
                    {
                        files = System.IO.Directory.GetFiles(currentDir, "*.lnk");
                    }
                    catch (System.IO.PathTooLongException e)
                    {

                        continue;
                    }
                    catch (UnauthorizedAccessException e)
                    {

                        continue;
                    }
                    catch (System.IO.DirectoryNotFoundException e)
                    {

                        continue;
                    }
                    foreach (string file in files)
                    {
                        try
                        {

                            System.IO.FileInfo fi = new System.IO.FileInfo(file);
                            lstFilesFound.Add(fi.FullName);
                        }
                        catch (System.IO.PathTooLongException e)
                        {

                            continue;
                        }
                        catch (System.IO.FileNotFoundException e)
                        {

                            continue;
                        }
                    }


                    foreach (string str in subDirs)
                        dirs.Push(str);
                }
            }
            finally
            {
                mr.Set();
            }

        }
    }
}

Open in new window


Add reference to Windows Script Host Object Model in COM tab of Add Reference dialogue.

I don't know what do you mean in second point. If you want count of items you can use Items.Count property, do you want it to display in listbox? where in listbox? It is not making any sense for me to display items count in listbox itself. you can use label or some other control for same.
0
 

Author Comment

by:TeknikDev
ID: 39767804
Opps sorry, 2nd item means to display the record count in the list box into a textbox.
0
 

Author Comment

by:TeknikDev
ID: 39767926
Wow! This is a much cleaner and faster way to do the job! Thank you Naman!

Can you help me with a few update? The search is working, but i need only BROKEN shortcuts. Also, when i changed the code from c:\temp to just c:\ the delete function stopped working. I selected multiple items and single items and it wont delete anymore.

  new DirSearchDelegate(DirSearch).BeginInvoke(@"c:\", mr, null, null);

Open in new window


1.

Refresh the list box after shortcut is deleted

2.

Find only broken shortcut links

3.

Instead of hardcoding the c:\temp folder, give users the ability to define a drive via drive selection box or enter value into textbox whichever you think is easier to code for you. The search will be based off this selection otherwise default to the c:\ drive

4.

A checkbox to delete ALL broken shortcuts found
0
Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

 
LVL 13

Expert Comment

by:Naman Goel
ID: 39768863
if you give c:\\ then also it will work, it will just take more time for searching whole drive.

Please find the modified code:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            FileShortcutsListBox.SelectionMode = SelectionMode.Multiple;
            ManualResetEvent mr = new ManualResetEvent(false);
            new DirSearchDelegate(DirSearch).BeginInvoke(DirectoryTextBox.Text, mr, null, null);
            mr.WaitOne();

            FileShortcutsListBox.ItemsSource = lstFilesFound;
            CountTextBox.Text = lstFilesFound.Count.ToString();
            FileShortcutsListBox.Items.SortDescriptions.Add(
            new System.ComponentModel.SortDescription(String.Empty,
            System.ComponentModel.ListSortDirection.Ascending));
        }

    

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            List<string> deletedItems = new List<string>();
            if (chkDeleteAll.IsChecked.Value== true)
            {
                foreach (var item in FileShortcutsListBox.Items)
                {

                    FileInfo fi = new FileInfo(item.ToString());
                    fi.Delete();
                    deletedItems.Add(item.ToString());

                }
            }
            else
            {

                foreach (var item in FileShortcutsListBox.SelectedItems)
                {

                    FileInfo fi = new FileInfo(item.ToString());
                    fi.Delete();
                    deletedItems.Add(item.ToString());

                }
            }
           for (int i = 0; i < deletedItems.Count; i++)
           {
               lstFilesFound.Remove(deletedItems[i]);
           }
        }

        // Holds a collection of all the found files
        static ObservableCollection<String> lstFilesFound = new ObservableCollection<string>();

        // Property used by the list box to display the list of files
        public static ObservableCollection<string> FilesFound { get { return lstFilesFound; } }

        delegate void DirSearchDelegate(string sDir,ManualResetEvent mr);

        static void DirSearch(string sDir, ManualResetEvent mr)
        {
            try
            {
                Stack<string> dirs = new Stack<string>(20);
                if (!System.IO.Directory.Exists(sDir))
                {
                    throw new ArgumentException();
                }
                dirs.Push(sDir);

                while (dirs.Count > 0)
                {
                    string currentDir = dirs.Pop();
                    string[] subDirs = null;
                    try
                    {
                        subDirs = System.IO.Directory.GetDirectories(currentDir);
                    }

                    catch (UnauthorizedAccessException e)
                    {

                        continue;
                    }
                    catch (System.IO.PathTooLongException e)
                    {


                        continue;
                    }
                    catch (System.IO.DirectoryNotFoundException e)
                    {

                        continue;
                    }

                    string[] files = null;
                    try
                    {
                        files = System.IO.Directory.GetFiles(currentDir, "*.lnk");
                    }
                    catch (System.IO.PathTooLongException e)
                    {

                        continue;
                    }
                    catch (UnauthorizedAccessException e)
                    {

                        continue;
                    }
                    catch (System.IO.DirectoryNotFoundException e)
                    {

                        continue;
                    }
                    foreach (string file in files)
                    {
                        try
                        {

                            System.IO.FileInfo fi = new System.IO.FileInfo(file);
                            IWshRuntimeLibrary.IWshShell shell = new IWshRuntimeLibrary.WshShell();

                            IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(file.ToString());

                            FileInfo fiTemp = new FileInfo(shortcut.TargetPath);
                            if (fiTemp.Exists == false)
                            {
                                lstFilesFound.Add(fi.FullName);
                            }
                        }
                        catch (System.IO.PathTooLongException e)
                        {

                            continue;
                        }
                        catch (System.IO.FileNotFoundException e)
                        {

                            continue;
                        }
                    }


                    foreach (string str in subDirs)
                        dirs.Push(str);
                }
            }
            finally
            {
                mr.Set();
            }

        }
    }
}

Open in new window

0
 

Author Comment

by:TeknikDev
ID: 39769352
Error when attempting to debug - might be easier to put a button for search and not auto-populate list?

dirs.Push(sDir);

Open in new window

Value does not fall within the expected range
0
 
LVL 13

Expert Comment

by:Naman Goel
ID: 39770122
here is code for same:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
        }

    

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            List<string> deletedItems = new List<string>();
            if (chkDeleteAll.IsChecked.Value== true)
            {
                foreach (var item in FileShortcutsListBox.Items)
                {

                    FileInfo fi = new FileInfo(item.ToString());
                    fi.Delete();
                    deletedItems.Add(item.ToString());

                }
            }
            else
            {

                foreach (var item in FileShortcutsListBox.SelectedItems)
                {

                    FileInfo fi = new FileInfo(item.ToString());
                    fi.Delete();
                    deletedItems.Add(item.ToString());

                }
            }
           for (int i = 0; i < deletedItems.Count; i++)
           {
               lstFilesFound.Remove(deletedItems[i]);
           }
        }

        // Holds a collection of all the found files
        static ObservableCollection<String> lstFilesFound = new ObservableCollection<string>();

        // Property used by the list box to display the list of files
        public static ObservableCollection<string> FilesFound { get { return lstFilesFound; } }

        delegate void DirSearchDelegate(string sDir,ManualResetEvent mr);
        static List<string> lstValues = new List<string>();
        static void DirSearch(string sDir, ManualResetEvent mr)
        {
            lstValues.Clear();
            try
            {
                Stack<string> dirs = new Stack<string>(20);
                if (!System.IO.Directory.Exists(sDir))
                {
                    throw new ArgumentException();
                }
                dirs.Push(sDir);

                while (dirs.Count > 0)
                {
                    string currentDir = dirs.Pop();
                    string[] subDirs = null;
                    try
                    {
                        subDirs = System.IO.Directory.GetDirectories(currentDir);
                    }

                    catch (UnauthorizedAccessException e)
                    {

                        continue;
                    }
                    catch (System.IO.PathTooLongException e)
                    {


                        continue;
                    }
                    catch (System.IO.DirectoryNotFoundException e)
                    {

                        continue;
                    }

                    string[] files = null;
                    try
                    {
                        files = System.IO.Directory.GetFiles(currentDir, "*.lnk");
                    }
                    catch (System.IO.PathTooLongException e)
                    {

                        continue;
                    }
                    catch (UnauthorizedAccessException e)
                    {

                        continue;
                    }
                    catch (System.IO.DirectoryNotFoundException e)
                    {

                        continue;
                    }
                    foreach (string file in files)
                    {
                        try
                        {

                            System.IO.FileInfo fi = new System.IO.FileInfo(file);
                            IWshRuntimeLibrary.IWshShell shell = new IWshRuntimeLibrary.WshShell();

                            IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(file.ToString());

                            FileInfo fiTemp = new FileInfo(shortcut.TargetPath);
                            if (fiTemp.Exists == false)
                            {
                                lstValues.Add(fi.FullName);
                            }
                        }
                        catch (System.IO.PathTooLongException e)
                        {

                            continue;
                        }
                        catch (System.IO.FileNotFoundException e)
                        {

                            continue;
                        }
                    }


                    foreach (string str in subDirs)
                        dirs.Push(str);
                }
            }
            finally
            {
                mr.Set();
            }
            
        }

        private void FillButton_Copy_Click_1(object sender, RoutedEventArgs e)
        {
            FileShortcutsListBox.ItemsSource = null;
            FileShortcutsListBox.SelectionMode = SelectionMode.Multiple;
            ManualResetEvent mr = new ManualResetEvent(false);
            new DirSearchDelegate(DirSearch).BeginInvoke(DirectoryTextBox.Text, mr, null, null);
            mr.WaitOne();
            lstFilesFound.Clear();
            
            foreach (var item in lstValues)
            {
                lstFilesFound.Add(item);
            }

            FileShortcutsListBox.ItemsSource = lstFilesFound;
            CountTextBox.Text = lstFilesFound.Count.ToString();
            FileShortcutsListBox.Items.SortDescriptions.Add(
            new System.ComponentModel.SortDescription(String.Empty,
            System.ComponentModel.ListSortDirection.Ascending));
        }
    }
}

Open in new window

0
 

Author Comment

by:TeknikDev
ID: 39771519
I'm still getting this error message. It looks like it's trying to get a value for the sDir variable which is currently just " ".

{"Value does not fall within the expected range."}
dirs.Push(sDir);

Open in new window


So I went ahead and added a default text of C:\ in the DirectoryTextBox textbox. When I click Search, nothing happens.

I debugged and found the following.
dirs.Count is 0 and sDir does show that its passing the c:\temp path. I noticed that the stack is not defined, so its passing in null?

Stack<string> dirs = new Stack<string>(20);

Open in new window

0
 
LVL 13

Expert Comment

by:Naman Goel
ID: 39771890
ok, that can be debugged on your environment. let me know if you face any other issue with logic. Retrieval of files  is fine and can be debugged and modified accordingly.
0
 

Author Comment

by:TeknikDev
ID: 39772231
yes, but I'm not how to fix it. Could you tell me based on the information provided thus far?
0
 
LVL 13

Expert Comment

by:Naman Goel
ID: 39772920
This error can be caused when there are two elements being added with the same name. That is rarely possible in your case. Please debug and check and if possible please check using Contains method if the string is already added in your stack. I am not getting much idea beyond this as this is working fine in my env.
0
 

Author Comment

by:TeknikDev
ID: 39774093
Ok I realized that I had to put a value into the textbox. It was telling me that the exception handler for no files found was not found. So I created shortcuts that were broken and it got close to the end of the code and got this error in this function.

FillButton_Copy_Click_1(object sender, RoutedEventArgs e)


{"Items collection must be empty before using ItemsSource."} Invalid Operation Exception was unhandled by user code.

  FileShortcutsListBox.ItemsSource = lstFilesFound;

Open in new window

0
 
LVL 13

Accepted Solution

by:
Naman Goel earned 500 total points
ID: 39774291
Add FileShortcutsListBox.Items.Clear() at start of event. or create a new List out of lstFilesFound and attach it with ItemSource.
0
 

Author Closing Comment

by:TeknikDev
ID: 39774665
I added before and it worked! thanks
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

856 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