Solved

Delete from ListBox broken shortcuts in C# WPF

Posted on 2014-01-08
13
614 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
Comment Utility
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
Comment Utility
Opps sorry, 2nd item means to display the record count in the list box into a textbox.
0
 

Author Comment

by:TeknikDev
Comment Utility
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
 
LVL 13

Expert Comment

by:Naman Goel
Comment Utility
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
Comment Utility
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
Comment Utility
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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:TeknikDev
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
I added before and it worked! thanks
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
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…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

771 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now