Laden...

Variablen zu Beginn überprüfen - an welcher Stelle

Erstellt von Nierewa vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.414 Views
N
Nierewa Themenstarter:in
15 Beiträge seit 2019
vor 4 Jahren
Variablen zu Beginn überprüfen - an welcher Stelle

Ich habe ein Projekt, bei dem in allen Textdateien in einem Verzeichnis Zeichen ersetzt werden und die Datei dann in einem anderen Verzeichnis gespeichert wird. Das wird mittels Timer immer wieder ausgeführt.

Der Nutzer kann über ein Formular Quell- und Zielverzeichnis, das zu ersetzende und das neue Zeichen auswählen, sowie das Überprüfungsintervall einstellen. Das ganze wird in einer Konfigurationsdatei gespeichert. So weit so gut.

Ich habe jetzt den Quellcodse angepaßt, das die Variablen aus der Konfigurationsdatei verwendet werden. Jetzt bekomme ich für meinen Aufruf foreach (var fn in Directory.GetFiles(@sourcePath, "*.txt")) folgende Fehlermeldung

Fehlermeldung:
System.ArgumentException
HResult=0x80070057
Nachricht = Der Pfad hat ein ungültiges Format.
Quelle = mscorlib
Stapelüberwachung:
bei System.IO.Path.LegacyNormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
bei System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
bei System.IO.Path.GetFullPathInternal(String path)
bei System.IO.FileSystemEnumerableIterator1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler1 resultHandler, Boolean checkHost)
bei System.IO.Directory.GetFiles(String path, String searchPattern)
bei Zuarbeit.Program.MyNotifyIconApplication.t1_Tick(Object sender, EventArgs e) in z:\Nurtzer\Documents\Visual Studio 2017\Zuarbeit\Zuarbeit\Program.cs: Zeile58
bei System.Windows.Forms.Timer.OnTick(EventArgs e)
bei System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
bei System.Windows.Forms.Application.Run()
bei Zuarbeit.Program.MyNotifyIconApplication.Main(String[] astrArg) in z:\Nutzer\Documents\Visual Studio 2017\Zuarbeit\Zuarbeit\Program.cs: Zeile126

Ich denke mal das liegt daran, das die Variable sourcePath leer ist.

Ich müßte also prüfen ob die Variale leer ist und falls ja, zuerst das Formular mit den Einstellungen aufrufen und diese setzen lassen, bevor etwas anderes passiert.

Nur weiß ich nicht an welcher Stelle im quellcode ich das tun muß. Ich hab schon einiges probiert, bekomme aber nur noch mehr Fehlermeldungen. Kann mir jemand sagen wo ich die Prüfung einfügen muß? Oder den Quelltext für mich korrigieren und mir kurz erklären was und warum getan wurde?

Die Prüfung würde ich übrigens so machen:

 if (sourcePath == "") { MessageBox.Show("Bitte über das TRay-Icon die einstellungen aufrufen und die nötigen Eingaben setzen. "); }
                else if (targetPath == "") { MessageBox.Show("Bitte über das TRay-Icon die einstellungen aufrufen und die nötigen Eingaben setzen. "); }
                else if (selectedCharacter == "") { MessageBox.Show("Bitte über das TRay-Icon die einstellungen aufrufen und die nötigen Eingaben setzen."); }
                else if (replacementCharacter == "") { MessageBox.Show("Bitte über das TRay-Icon die einstellungen aufrufen und die nötigen Eingaben setzen."); }
                else if (testIntervall == "") { MessageBox.Show("Bitte über das TRay-Icon die einstellungen aufrufen und die nötigen Eingaben setzen."); }

Hier mal meine gesamte Program.cs:

using System;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using System.Collections.Specialized;
using System.Configuration;
using System.Text;




namespace Zuarbeit
{
    /// <summary>
    /// Class with program entry point.
    /// </summary>
    internal sealed class Program
    {
        /// <summary>
        /// Program entry point.
        /// </summary>  


        //*****************************************************************************

        static class MyNotifyIconApplication
{
            public static string fileName = "";
            public static string sourcePath = Properties.Settings.Default.quellpfad;
            public static string targetPath = Properties.Settings.Default.zielpfad;
            public static string selectedCharacter = Properties.Settings.Default.auswahlzeichen;
            public static string replacementCharacter = Properties.Settings.Default.ersatzzeichen;
            public static string testIntervall = Properties.Settings.Default.intervall;

            // Use Path class to manipulate file and directory paths.
            public static string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
            public static string destFile = System.IO.Path.Combine(targetPath, fileName);

            private static void t1_Tick(object sender, EventArgs e)  
{
              

    foreach (var fn in Directory.GetFiles(@sourcePath, "*.txt")) {

               // Eine Backupdatei von der Quelldatei anlegen
               fileName = System.IO.Path.GetFileNameWithoutExtension(fn);
               destFile = System.IO.Path.Combine(sourcePath, fileName+".bak");
               System.IO.File.Copy(fn, destFile, true);

               // in der Textdatei alle # mit | ersetzen.
               string text = File.ReadAllText(fn);
               text = text.Replace(selectedCharacter, replacementCharacter);
               File.WriteAllText(fn, text);



               // die Datei in den Zielordner kopieren und danach löschen
               fileName = System.IO.Path.GetFileName(fn);
               destFile = System.IO.Path.Combine(targetPath, fileName);
               System.IO.File.Copy(fn, destFile, true);
               System.IO.File.Delete(fn);
              }
              }
   private static NotifyIcon  notico;


            [STAThread]
            //==========================================================================
            public static void Main (string [] astrArg)
   {
                new MainForm().Show();
                

                   Timer t1 = new Timer(); // Timer anlegen
                   t1.Interval = Int32.Parse(testIntervall+1); // Intervall festlegen, hier 100 ms
                   t1.Tick+=new EventHandler(t1_Tick); // Eventhandler ezeugen der beim Timerablauf aufgerufen wird
                   t1.Start(); // Timer starten  

   

                      ContextMenu cm;
                      MenuItem    miCurr;
                      int         iIndex = 0;

                      // Kontextmenü erzeugen
                      cm = new ContextMenu ();

                      // Kontextmenüeinträge erzeugen
                      miCurr = new MenuItem ();
                      miCurr.Index = iIndex++;
                      miCurr.Text = "&Einstellungen";           // Eigenen Text einsetzen
                      miCurr.Click += new System.EventHandler (Action1Click);
                      cm.MenuItems.Add (miCurr);

                      // Kontextmenüeinträge erzeugen
                      miCurr = new MenuItem ();
                      miCurr.Index = iIndex++;
                      miCurr.Text = "&Beenden";
                      miCurr.Click += new System.EventHandler (ExitClick);
                      cm.MenuItems.Add (miCurr);

                      // NotifyIcon selbst erzeugen
                      notico = new NotifyIcon ();
                      notico.Icon = new Icon("smile.ico"); // Eigenes Icon einsetzen
                      notico.Text = "Doppelklick mich!";   // Eigenen Text einsetzen
                      notico.Visible = true;
                      notico.ContextMenu = cm;
                      notico.DoubleClick += new EventHandler (NotifyIconDoubleClick);

                // Ohne Appplication.Run geht es nicht
                Application.Run ();
                    
                
            }

   //==========================================================================
   private static void ExitClick (Object sender, EventArgs e)
   {
      notico.Dispose ();
      Application.Exit ();
   }

   //==========================================================================
   private static void Action1Click (Object sender, EventArgs e)
   {
      // nur als Beispiel:
      new MainForm().Show();
   }

   //==========================================================================
   private static void NotifyIconDoubleClick (Object sender, EventArgs e)
   {
      // Was immer du willst
      new MainForm().Show();
   }


}
    }
}
16.806 Beiträge seit 2008
vor 4 Jahren

Kann mir jemand sagen wo ich die Prüfung einfügen muß? Oder den Quelltext für mich korrigieren und mir kurz erklären was und warum getan wurde?

Das Forum ist kein kostenloser Quellcode-Korrektur-Generator.
[Hinweis] Wie poste ich richtig?

4.2. Wälzt nicht eure Aufgaben auf uns ab

Wundert euch nicht, wenn es zum Teil sehr heftige Gegenreaktionen gibt, falls ihr doch nach fertigen Lösungen fragt oder anderweitig der Eindruck entsteht, dass ihr uns kostenlos für eure Aufgaben einspannen wollt.

Aber als Hinweis:

Du musst natürlich vorher prüfen, ob der Pfad (sourcePath Variable) gültig ist.
Google-Suche nach c# path validation

N
Nierewa Themenstarter:in
15 Beiträge seit 2019
vor 4 Jahren

Hallo
Danke erst mal für die schnelle Antwort.

Du musst natürlich vorher prüfen, ob der Pfad (sourcePath Variable) gültig ist.

Das weiß ich. Müßte ja nur nachschauen ob der Pfad leer ist und wenn ja, das Formular mir den Einstellungen öffnen. Aber ich weiß nicht wo, also an welcher stelle im Code.
Egal wo ich das mache, der weitere Quellcode wird abgearbeitet und es kommt der Fehler.

Ich habe probiert eine Do-While Schleife zu nutzen, aber der Quellcode wird weiter ausgeführt und ich bekomme diese Fehlermeldung das der Pfad ungültig ist.

Wundert euch nicht, wenn es zum Teil sehr heftige Gegenreaktionen gibt, falls ihr doch nach fertigen Lösungen fragt oder anderweitig der Eindruck entsteht, dass ihr uns kostenlos für eure Aufgaben einspannen wollt.

Das verstehe ich, aber das möchte ich ja auch gar nicht. Deshalb hab ich geschrieben oder 😁

Ich schau mir den Link natürlich an.

H
523 Beiträge seit 2008
vor 4 Jahren

Ich müßte also prüfen ob die Variale leer ist und falls ja, zuerst das Formular mit den Einstellungen aufrufen und diese setzen lassen, bevor etwas anderes passiert.

Nur weiß ich nicht an welcher Stelle im quellcode ich das tun muß. Ich hab schon einiges probiert, bekomme aber nur noch mehr Fehlermeldungen. Kann mir jemand sagen wo ich die Prüfung einfügen muß? Oder den Quelltext für mich korrigieren und mir kurz erklären was und warum getan wurde?

Ich würde zwei Prüfungen einbauen:

1.) Wenn der Benutzer die Einstellung im Formular gemacht hat und auf Speichern/OK/Übernehmen/whatever klickt. An dieser Stelle einfach prüfen, ob der eingegebene Pfad existiert und wenn nicht, dann Fehlermeldung ausgeben und Speichern der Einstellungen unterbinden.

2.) Bevor

Directory.GetFiles(@sourcePath, "*.txt")

aufgerufen wird abfragen ob das Verzeichnis existiert und falls nicht, dann gar nicht in die Schleife laufen.

Es kann ja auch passieren, dass das Verzeichnis richtig eingestellt aber später umbenannt wurde.

4.931 Beiträge seit 2008
vor 4 Jahren

Die Fehlermeldung deutet auch nicht auf einen leeren Pfad hin, sondern auf einen fehlerhaften (z.B. mit Sonderzeichen o.ä.)?
Debugge einfach deine Anwendung und schau dir den Variableninhalt von sourcePath an, s. [Artikel] Debugger: Wie verwende ich den von Visual Studio?

PS: Mit if (sourcePath == "") testest du auch nur auf einen leeren Pfad, aber z.B. nicht auch auf null: if (String.IsNullOrEmpty(sourcePath)).

N
Nierewa Themenstarter:in
15 Beiträge seit 2019
vor 4 Jahren

Zuerst mal danke an alle.

ich habe das so geändert

public static void Main (string [] astrArg){

                      if (String.IsNullOrEmpty(sourcePath)) { new MainForm().Show(); }
                      else
                      {

                          Timer t1 = new Timer(); // Timer anlegen
                          t1.Interval = Int32.Parse(testIntervall + 1); // Intervall festlegen, hier 100 ms
                          t1.Tick += new EventHandler(t1_Tick); // Eventhandler ezeugen der beim Timerablauf aufgerufen wird
                          t1.Start(); // Timer starten 
                      }

Und es erscheint das Formular, wo ich die EIngaben machen kann.

Hier prüfe ich beim Speichern ob die erforderlichen Angaben gemacht wurden.Natürlich wird die if-else Anweisung dann nicht mehr abgefragt und es passiert nix mehr. Deshalb starte ich die Anwenung einfach über Application.Restart(); neu.

private void btn_save_Click(object sender, EventArgs e)
        {
            
                if (textBox1.Text =="") { MessageBox.Show("Bitte überprüfen Sie Ihre Eingaben für das Quellverzeichnis. ");  }
                else if (textBox2.Text =="") { MessageBox.Show("Bitte überprüfen Sie Ihre Eingaben für das Zielverzeichnis. "); }
                else if (textBox3.Text =="") { MessageBox.Show("Bitte überprüfen Sie Ihre Eingaben für das zu ersetzende Zeichen."); }
                else if (textBox4.Text == "") { MessageBox.Show("Bitte überprüfen Sie Ihre Eingaben für das zu schreibende Zeichen."); }
                else {
                    Properties.Settings.Default.quellpfad = textBox1.Text;
                    Properties.Settings.Default.zielpfad = textBox2.Text;
                    Properties.Settings.Default.auswahlzeichen = textBox3.Text;
                    Properties.Settings.Default.ersatzzeichen = textBox4.Text;
                    Properties.Settings.Default.Save();
                    Application.Restart();
                }
            
        }

Würde es auch besser gehen? Also das nach dem Speichern die If-Else Abfrage nochmal ausgeführt wird ohne neu zu starten? Und wenn ja, wie?

Hinzugefügt um 17:50Uhr:
Ich habe gemerkt das nach dem Application.Restart() das Formular aufgeht und ich nochmal alle Angaben machen muß. Nach dem errneuten Speichern funktioniert es wie gewünscht. Kann mir jemand sagen woran das liegt? Ich finde den Fehler nicht.

H
523 Beiträge seit 2008
vor 4 Jahren

ich habe das so geändert

public static void Main (string [] astrArg){  
  
                      if (String.IsNullOrEmpty(sourcePath)) { new MainForm().Show(); }  
                      else  
                      {  
  
                          Timer t1 = new Timer(); // Timer anlegen  
                          t1.Interval = Int32.Parse(testIntervall + 1); // Intervall festlegen, hier 100 ms  
                          t1.Tick += new EventHandler(t1_Tick); // Eventhandler ezeugen der beim Timerablauf aufgerufen wird  
                          t1.Start(); // Timer starten   
                      }  

Was passiert, wenn vor dem Start oder während die Anwendung läuft das Verzeichnis umbenannt oder verschoben wird? Ich würde immer Directory.Exists anstatt String.IsNullOrEmpty verwenden.