Suchfunktion - funktioniert mit Einschränkungen

Achso. Mir fehlen jetzt noch drei Dinge um die Sache abzurunden:

1) Die Suche stoppen können. (Habe einen "Stop"-Button gesetzt.) Ich wollte erst den "Suspend()-Befehl verwenden, aber das wird grün unterstrichen und es gibt den Hinweis, dass der Befehl wohl veraltet ist. Daher dürfte Abort() der von mir gesuchte Befehl sein.

2) Ich muss noch den Ort anzeigen können, wo die Datei liegt. Nach der alten Methode ging das bereits, mir der neuen nicht mehr

3) Wenn ich eine gefundene Datei öffnen will muss ich unterscheiden können, welches Programm geöffnet werden soll. Das wollte ich mittels "file.Extension" machen, aber das "Extension" steht mir an der benötigten Stelle nicht mehr zur Verfügung.

Ich würde behaupten, dass alle drei Probleme an einem Punkt scheitern. Ich kann die benötigten Variablen nicht übergeben. (Für Punkt 2 beispielsweise muss also irgendwie das Verzeichnis in dem eine gefundene Datei liegt übertragen werden, also "DirectoryName". Ich habe wirklich einiges ausprobiert, aber die richtige Lösung war noch nicht dabei. Bitte poste erst einmal keinen Code, sondern gib mir nur einen kräftigen Stoß in die richtige Richtung oder mache ein Beispiel aus dem ich es übertragen können sollte. Es werden ja eigentlich schon Variablen übergeben, beispielsweise bei "private void Search(string path, string searchPattern)" Daran wollte ich mich orientieren, aber vergebens.

4-Optional) Ein Fortschrittsbalken mit dem man sieht, wie weit die Suche fortgeschritten ist. Der Balken ist drin und ich hatte es (nach dem ganz alten System) sogar geschafft, dass er sich ein bisschen füllt. Allerdings war die Suche fertig (Erkennbar daran, dass das Tool wieder freigegeben war), aber der Balken nur etwa 20% gefüllt. So ganz kann es also nicht gestimmt haben, was ich da gemacht hatte. (War irgendwas mit "progressBar1.Value += 1;"

Der Vollständigkeit wegen hie der bisherige Code:

C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;

namespace Suche
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cmbLaufwerk.Items.AddRange(Environment.GetLogicalDrives());
        }

        private void cmdSuchen_Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            string path = cmbLaufwerk.Text;
            string searchPattern = "*" + txtSuchbegriff.Text + "*";
 
            System.Threading.Thread t = new System.Threading.Thread(delegate() { Search(path, searchPattern); });
            t.Start();
        }
        
        private void Search(string path, string searchPattern)
        {
            try
            {
 
                DirectoryInfo di = new DirectoryInfo(path);
                FileInfo[] files = di.GetFiles(searchPattern);
                DirectoryInfo[] subDirectories = di.GetDirectories();
 
                foreach (FileInfo file in files)
                {
                    if ((file.Extension == ".doc") || (file.Extension == "docx") && (cbWord.Checked == true))
                    {
                        AddFile(file.Name);
                    }
                    if ((file.Extension == ".xls") && (cbExcel.Checked == true))
                    {
                        AddFile(file.Name);
                    }
                    if ((file.Extension == ".ppt") && (cbPowerPoint.Checked == true))
                    {
                        AddFile(file.Name);
                    }
                    if ((file.Extension == ".pdf") && (cbPDF.Checked == true))
                    {
                        AddFile(file.Name);
                    }
                }
 
                foreach (DirectoryInfo subDir in subDirectories)
                {
                    Search(subDir.FullName, searchPattern);
                }
            }
            catch (UnauthorizedAccessException) { }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
         }
        
        private void AddFile(string fileName)
        {
            if (this.listView1.InvokeRequired)
            {
                this.listView1.BeginInvoke(new MethodInvoker(delegate() { AddFile(fileName); }));
            }
            else
            {
                this.listView1.Items.Add(fileName);
            }
        }

        private void cmdStop_Click(object sender, EventArgs e)
        {

        }

        private void dateiToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void überToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form2 NeuesFenster = new Form2();
            NeuesFenster.ShowDialog();
        }

        private void öffnenToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            ListView.SelectedListViewItemCollection co = listView1.SelectedItems;

            if (co.Count > 0)
            {
                string strFile = co[0].SubItems[0].Text; // Datei
                string strPath = co[0].SubItems[1].Text; // Ort

                string strFilePath = Path.Combine(strPath, strFile);
                Process.Start("WINWORD.exe", "\"" +strFilePath + "\"");
            }
        }
    }
}
 
Zuletzt bearbeitet:
1) Die Suche stoppen können. (Habe einen "Stop"-Button gesetzt.) Ich wollte erst den "Suspend()-Befehl verwenden, aber das wird grün unterstrichen und es gibt den Hinweis, dass der Befehl wohl veraltet ist. Daher dürfte Abort() der von mir gesuchte Befehl sein.
Abort() zu verwenden ist eigentlich nicht die feine englische.
Schau dir folgendes Beispiel an wie man es machen sollte :http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.80).aspx
Du kannst allerdings anstatt eines Threads auch einen Backgroundworker verwenden.
Backgroundworker haben den Vorteil das sie wesentlich leichter zu implementieren sind und genau die Funktionalitäten bieten die du gerne hättest.
2) Ich muss noch den Ort anzeigen können, wo die Datei liegt. Nach der alten Methode ging das bereits, mir der neuen nicht mehr
Dann änder die AddFile Methode einfach so ab das sie 2 Parameter anstatt nur einen akzeptiert und übergib den Pfad als zweiten Parameter.
Wenn ich eine gefundene Datei öffnen will muss ich unterscheiden können, welches Programm geöffnet werden soll. Das wollte ich mittels "file.Extension" machen, aber das "Extension" steht mir an der benötigten Stelle nicht mehr zur Verfügung.
Wieso steht dir die Extension nicht mehr zur Verfügung. Du übergibst der AddFile Methode doch File.Name welches sowohl den Dateinamen als auch die Extension enthält.
4-Optional) Ein Fortschrittsbalken mit dem man sieht, wie weit die Suche fortgeschritten ist. Der Balken ist drin und ich hatte es (nach dem ganz alten System) sogar geschafft, dass er sich ein bisschen füllt. Allerdings war die Suche fertig (Erkennbar daran, dass das Tool wieder freigegeben war), aber der Balken nur etwa 20% gefüllt. So ganz kann es also nicht gestimmt haben, was ich da gemacht hatte. (War irgendwas mit "progressBar1.Value += 1;"
Das Problem mit Fortschrittsbalken ist das man immer erst berechnen muss was 100% des Fortschrittsbalkens entspricht.
Das bedeutet bevor du anfängst zu suchen müsstest du z.B. erstmal berechnen wieviele Ordner es insgesamt gibt die durchsucht werden müssen.
Und sobald ein Ordner durchsucht wurde erhöhst du den Wert des Fortschrittsbalkens um 1.
Angenommen das ermitteln des maximal Wertes dauert 10 Sekunden dann verbrät dein Programm schonmal 10 Sekunden an Zeit die nicht für den eigentlich Suchvorgang drauf gehen sondern eben nur für diese Operation.
 
Danke. Punkt 2 ist erledigt. Punkt 4 bleibt dann außen vor, weil sinnlos. Man könnte ja stattdessen am ende eine Meldung ausgeben von wegen "Suche abgeschlossen" oder so.

Momentan versuche ich mich noch daran das richtige Programm für die richtige Datei zu öffnen. Das will mir nicht gelingen. Ich bin da:
C#:
        private void öffnenToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            ListView.SelectedListViewItemCollection co = listView1.SelectedItems;

            if (co.Count > 0)
            {
                string strFile = co[0].SubItems[0].Text; // Datei
                string strPath = co[0].SubItems[1].Text; // Ort

                string strFilePath = Path.Combine(strPath, strFile);
                if (strFile == "*.doc")
                    Process.Start("WINWORD.exe", "\"" + strFilePath + "\"");
                else
                    MessageBox.Show("Bla");
            }
        }

Der Code funktioniert natürlich nicht, gibt immer ein "Bla". Soweit eigentlich auch nicht verwunderlich, da ich ja nur die Extension brauche (Dachte mit dem Sternchen kann man etwas schummeln) Die Extension alleine steht mir aber nicht zur Verfügung und wie ich sie in diese Methode übernehmen kann, weis ich nicht. Bei der selbst erstellten Methode war das irgendwie kein Problem (Da wo es darum ging den Ort noch mit zu übertragen)
 
Also eigentlich kannst du dir die Angabe des Programms auch sparen es sei denn du willst erzwingen das z.B. doc/docx in Word geöffnet wird.
Ansonsten ist es nämlich so das wenn man Process.Start nur einen Dateinamen übergibt automatisch das StandardProgramm für den jeweiligen Dateityp gestartet wird.
C#:
private void öffnenToolStripMenuItem_Click(object sender, EventArgs e)
        {   
            if (this.listView1.SelectedItems.Count == 1)
            {
                ListViewItem item = this.listView1.SelectedItems[0];
                if (item.SubItems.Count >= 2)
                {
                    string fullPath = item.SubItems[1].Text + Path.DirectorySeparatorChar + item.SubItems[0].Text;
                    FileInfo fi = new FileInfo(fullPath);
                    
                    System.Diagnostics.Process.Start(fi.FullName);
                }
            }
        }
 
Hallo
Ich habe da mal eine ganz blöde Frage. Und zwar mache ich quasi etwas ähnliches. Aber ich mag diese Zeilen nicht.
Code:
DirectoryInfo di = new DirectoryInfo(path);
                FileInfo[] files = di.GetFiles(searchPattern);
                DirectoryInfo[] subDirectories = di.GetDirectories();
Ich selbst mache es immer so und habe keine Performance Probleme
Code:
public List<DirectoryInfo> readDirectorys(string node)
        {
            List<DirectoryInfo> temp = new List<DirectoryInfo>();
            DirectoryInfo infoDirectorys = new DirectoryInfo(node);
            temp.AddRange(infoDirectorys.GetDirectories());
            return temp;
        }

        public List<FileInfo> readFiles(string node)
        {
            List<FileInfo> temp = new List<FileInfo>();
            DirectoryInfo infoFiles = new DirectoryInfo(node);
            try
            {
                temp.AddRange(infoFiles.GetFiles());
            }
            catch (Exception e)
            {
                System.Windows.MessageBox.Show(e.Message.ToString());
                
            }
            return temp;
        }
Es ähnelt sich aber was ist der große Unterschied kann mir wer das erklären
MfG
 
Es ähnelt sich aber was ist der große Unterschied kann mir wer das erklären
Das du 23 Zeilen brauchst und ich/wir 3?!

Es gibt keinen wirklich Nennenswerten Unterschied aber es ist eigentlich völlig unnötig das 1. auszulagern und 2. in eine List<T> zu kapseln.

//edit
Bevor das falsch verstanden wird:
Mit "keine Nennenswerten Unterschiede" meine ich natürlich das es funktional keinen großen Unterschied macht.

Performance technisch sollte klar sein das deine Methode definitiv langsamer ist.
 
Zuletzt bearbeitet:
Hallo
also das auslagern finde ich in einem 3 Schichten Programm nicht unnötig.
Was die Performance angeht, ist es eben bei mir wesentlich fixer. Habe es mit Zeitausgaben getestet auf Life Systemen. Wieso weiß ich nicht. Und ich brauche auch nur 5Zeilen wenn man mal try und das Gedöns weglässt ;-)
MfG
oli

p.s ich dachte auch es sei langsamer
 
Zuletzt bearbeitet:
Was die Performance angeht, ist es eben bei mir wesentlich fixer. Habe es mit Zeitausgaben getestet auf Life Systemen
Das ist jetzt aber nicht dein ernst oder?
Wenn man das alles mal runter reduziert dann macht "deine" Version exakt das gleiche wie "meine" Version.
Der einzige Unterschied besteht daran das du das Ergebnis (was mein Endergebnis darstellt) dann noch nimmst und in eine Liste packst was laut Doku eine O(n + m) Operation ist.
Und deine Version ist schneller.
Ehrlich jetzt?!

Versteh mich nicht falsch. Mir ist das im Prinzip völlig Wurst welche Version schneller ist.
Aber vielleicht solltest du nochmal ein wenig Performance messen üben.
 
Zuletzt bearbeitet:
Also ich weiß wie man Performance mist und wenn der Zeitstamp es auf einem RL Server mehrfach so wieder gibt denke ich stimmt das schon
 
Zurück