?
Solved

Delete from ListBox broken shortcuts in C# WPF

Posted on 2014-01-08
13
Medium Priority
?
676 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 
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 2000 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

Is Your Team Achieving Their Full Potential?

74% of employees feel they are not achieving their full potential. With Linux Academy, not only will you strengthen your team's core competencies but also their knowledge of of the newest IT topics.

With new material every week, we'll make sure that you stay ahead of the game.

Question has a verified solution.

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

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
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…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…

752 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