Bei Fehler Kopiervorgang sofort beenden

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von siycah.

    Bei Fehler Kopiervorgang sofort beenden

    Moin moin

    Mein Code hier bereitet mir einige Probleme. Das kopieren als solches funktioniert super. Das Problem ist das Abfangen von Fehlern.
    Kopiere ich z.B. auf einen USB-Stick und ziehe den Stick während des kopieren ab, verlässt der Code nicht sofort die entsprechende Methode.

    Siehe dazu den Auszug aus dem LogFile. Habe bis Bild Nummer 0011 kopieren lassen und dann den USB-Stick abgezogen.

    Irgendwie komme ich leider nicht weiter. :(

    Mein Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class FileCopier
    2. Public Event CopyProgressChanged As EventHandler(Of CopyProgressEventArgs)
    3. Public Event CopyCompleted As EventHandler(Of CopyCompletedEventArgs)
    4. Public Event CopyFailed As EventHandler(Of CopyFailedEventArgs)
    5. Private Property Copysuccess As Boolean = False ' Flag für den Kopierforgang
    6. Public Async Function CopyDirectoryAsync(sourceDir As String, targetDir As String) As Task
    7. Await Task.Run(Sub() CopyDirectory(sourceDir, targetDir))
    8. End Function
    9. Private Sub IsCopySuccess()
    10. If Copysuccess Then
    11. Dim message As String = $"Kopieren erfolgreich abgeschlossen."
    12. RaiseEvent CopyCompleted(Me, New CopyCompletedEventArgs(message))
    13. GlobalEventLogger.ExceptionToFile(message, ExStatus.Success)
    14. End If
    15. End Sub
    16. Private Sub CopyDirectory(sourceDir As String, targetDir As String)
    17. Try
    18. ' Zuerst das Quellverzeichnis überprüfen
    19. If Not CheckSourceDirectory(sourceDir) Then Return
    20. ' Dann das Zielverzeichnis erstellen oder überprüfen
    21. If Not CreateTargetDirectory(targetDir) Then Return
    22. ' Schließlich die Dateien und Unterverzeichnisse kopieren
    23. CopyFilesAndSubDirectories(sourceDir, targetDir)
    24. ' Wenn alles erfolgreich war
    25. Copysuccess = True
    26. Catch ex As Exception
    27. Copysuccess = False
    28. Dim message As String = $"Ein Fehler ist aufgetreten."
    29. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs(message))
    30. GlobalEventLogger.ExceptionToFile($"{message}{Environment.NewLine}{ex.Message}", ExStatus.Failure)
    31. End Try
    32. End Sub
    33. Private Function CheckSourceDirectory(sourceDir As String) As Boolean
    34. Dim sourceDirectoryInfo As New DirectoryInfo(sourceDir)
    35. If Not sourceDirectoryInfo.Exists Then
    36. Dim message As String = $"Quellverzeichnis existiert nicht!"
    37. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs(Message))
    38. GlobalEventLogger.ExceptionToFile(Message, ExStatus.Failure)
    39. Return False
    40. End If
    41. Return True
    42. End Function
    43. Private Function CreateTargetDirectory(targetDir As String) As Boolean
    44. Try
    45. Dim targetDirectoryInfo As DirectoryInfo = Directory.CreateDirectory(targetDir)
    46. Return True
    47. Catch ex As Exception
    48. Copysuccess = False
    49. Dim message As String = $"Fehler beim Erstellen des Zielverzeichnisses."
    50. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs(Message))
    51. GlobalEventLogger.ExceptionToFile($"{Message}{Environment.NewLine}{ex.Message}", ExStatus.Failure)
    52. Return False
    53. End Try
    54. End Function
    55. Private Sub CopyFilesAndSubDirectories(sourceDir As String, targetDir As String)
    56. Dim sourceDirectoryInfo As New DirectoryInfo(sourceDir)
    57. For Each sourceFileOrDir As FileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos()
    58. If (sourceFileOrDir.Attributes And FileAttributes.Hidden) <> FileAttributes.Hidden Then ' Überprüfung auf versteckte Dateien oder Ordner
    59. Dim formattedPath As String
    60. If TypeOf sourceFileOrDir Is FileInfo Then ' Wenn es sich um eine Datei handelt
    61. Dim sourceFile As FileInfo = DirectCast(sourceFileOrDir, FileInfo)
    62. formattedPath = Path.Combine(targetDir, sourceFile.Name)
    63. Dim directoryStructure As String() = formattedPath.Split("\"c)
    64. If directoryStructure.Length > 3 Then
    65. formattedPath = Path.Combine(directoryStructure(0), directoryStructure(1), "...", directoryStructure(directoryStructure.Length - 1))
    66. End If
    67. Dim targetFile As String = Path.Combine(targetDir, sourceFile.Name)
    68. Try
    69. sourceFile.CopyTo(targetFile, True)
    70. RaiseEvent CopyProgressChanged(Me, New CopyProgressEventArgs(formattedPath))
    71. Catch ex As Exception
    72. Copysuccess = False
    73. Dim message As String = $"Fehler beim Kopieren der Datei"
    74. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs($"{message} {sourceFile.Name}{Environment.NewLine}{ex.Message}"))
    75. GlobalEventLogger.ExceptionToFile($"{message} {sourceFile.Name}{Environment.NewLine}{ex.Message}", ExStatus.Failure)
    76. Return ' Sofort verlassen, wenn ein Fehler auftritt
    77. End Try
    78. ElseIf TypeOf sourceFileOrDir Is DirectoryInfo Then ' Wenn es sich um ein Verzeichnis handelt
    79. Dim sourceSubDir As DirectoryInfo = DirectCast(sourceFileOrDir, DirectoryInfo)
    80. Dim targetSubDir As String = Path.Combine(targetDir, sourceSubDir.Name)
    81. CopyDirectory(sourceSubDir.FullName, targetSubDir)
    82. End If
    83. End If
    84. Next
    85. End Sub
    86. End Class
    87. Public Class CopyProgressEventArgs
    88. Inherits EventArgs
    89. Public Property FileName As String
    90. Public Sub New(fileName As String)
    91. Me.FileName = fileName
    92. End Sub
    93. End Class
    94. Public Class CopyCompletedEventArgs
    95. Inherits EventArgs
    96. Public Property Message As String
    97. Public Sub New(message As String)
    98. Me.Message = message
    99. End Sub
    100. End Class
    101. Public Class CopyFailedEventArgs
    102. Inherits EventArgs
    103. Public Property ErrorMessage As String
    104. Public Sub New(errorMessage As String)
    105. Me.ErrorMessage = errorMessage
    106. End Sub
    107. End Class




    Auszug aus dem LogFile:
    Spoiler anzeigen

    XML-Quellcode

    1. [ 03.05.2024 | 08:40:44 ] Erfolgreich
    2. Das Laden der Programm-Konfiguration aus der XML-Datei B:\Debug\Settings.xml war erfolgreich.
    3. [ 03.05.2024 | 08:40:46 ] Hinweis
    4. Der Backup-Prozess wurde gestartet.
    5. [ 03.05.2024 | 08:40:48 ] Fehler
    6. Fehler beim Kopieren der Datei NewAI_A_0012.png
    7. Die Datei "F:\_LibraryBackUp\testverzeichnisse\Bilder\NewAI_A_0012.png" konnte nicht gefunden werden.
    8. [ 03.05.2024 | 08:41:00 ] Fehler
    9. Fehler beim Erstellen des Zielverzeichnisses.
    10. Ein Teil des Pfades "F:\_LibraryBackUp\testverzeichnisse\Bilder_I" konnte nicht gefunden werden.
    11. [ 03.05.2024 | 08:41:01 ] Fehler
    12. Fehler beim Erstellen des Zielverzeichnisses.
    13. Ein Teil des Pfades "F:\_LibraryBackUp\testverzeichnisse\Bilder_II" konnte nicht gefunden werden.
    14. [ 03.05.2024 | 08:41:01 ] Fehler
    15. Fehler beim Erstellen des Zielverzeichnisses.
    16. Ein Teil des Pfades "F:\_LibraryBackUp\testverzeichnisse\Dakota" konnte nicht gefunden werden.
    17. [ 03.05.2024 | 08:41:02 ] Fehler
    18. Fehler beim Erstellen des Zielverzeichnisses.
    19. Ein Teil des Pfades "F:\_LibraryBackUp\testverzeichnisse\Storys" konnte nicht gefunden werden.

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    @Amelie In der WndProc() bekommst Du die entsprechenden Informationen.
    Sieh Dir mal dies an:
    Ein USB-Dongel
    Wenn Du das Kopieren in Blöcke zerlegst, kannst Du selbst nach jedem Block testen, ob die Verbindung noch da ist und die Prozedur verlassen.
    Außerdem kannst Du mit einem Fortschrittsbalken den Verlauf darstellen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Eigentlich brauchst du für genau solche Sachen eine State-Machine.

    Deine State-Machine läuft dann immer durch, prüft den Status und kopiert dann Stück für Stück. So kannst du dann auch rechtzeitig Fehler abfangen.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.
    @Amelie Ich hab das jetzt nicht explizit getestet. Wie verhält sich denn das ganze wenn Du anstelle einer eigenen Kopierroutine folgendes zum kopieren verwendest? -> Dateien und Ordner löschen, kopieren, verschieben und umbenennen per IFileOperation Vorteil des ganzen wäre auch, das Du hier gleich einen Dialog mit dem Vortschritt angezeigt bekommst. Du kannst, bevor Du Dir den Code anschaust, das ganze auch einfach im Explorer testen. Also was passiert wenn Du beim Kopiervorgang im Explorer den Stick abziehst. Was anderes würde der Code auch nicht machen.
    Mfg -Franky-
    @-Franky-
    Der Test im Explorer wirft mir folgendes Fenster. Siehe Bildanhang. Nach klick auf Abbrechen schließt sich das Fenster.
    Werde mir mal Dein Beispiel runterladen und ansehen.

    @RodFromGermany
    Zugegeben, hatte ich das schon im Kopf, schien mir dann aber wieder zu "aufwendig" zu sein und dache es gäbe eine einfache Lösung.

    @siycah
    Hab mal flüchtig etwas über "State-Machine" gehört aber noch nie etwas mit gemacht.
    Bilder
    • explorerfehler-1.jpg

      149,4 kB, 453×383, 81 mal angesehen
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    gehört aber noch nie etwas mit gemacht.

    Irgendwo fängt ja jeder an.

    Eine State-Machine ist nichts anderes, als eine Schleife, die immer wieder einen Status prüft und abhängig davon dann eine Aktion ausführt.

    Wenn du schon mal was mit ​async/await gemacht hast, dann hast du auch schon mit State Machines gearbeitet. In dem Fall abstrahiert dotnet das alles weg, aber im Hintergrund ist es nichts anderes als das.

    Hier das so ziemlichste einfachste Beispiel einer State-Machine, die ich mir ausdenken kann.

    C#-Quellcode

    1. class StateMachine {
    2. public bool State { get; set; } = true;
    3. public void DoWork() {
    4. while (true) {
    5. if (State) {
    6. Console.WriteLine("State is true");
    7. } else {
    8. Console.WriteLine("State is false");
    9. }
    10. }
    11. }
    12. }
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.
    Der Verursacher von meinem Problem: ​GlobalEventLogger.ExceptionToFile($"{Messa.......
    Der ist wohl in so eine Art Endlosschleife gelaufen.

    VB.NET-Quellcode

    1. Private Function CreateTargetDirectory(targetDir As String) As Boolean
    2. Try
    3. Dim targetDirectoryInfo As DirectoryInfo = Directory.CreateDirectory(targetDir)
    4. Return True
    5. Catch ex As Exception
    6. Copysuccess = False
    7. Dim message As String = $"Fehler beim Erstellen des Zielverzeichnisses."
    8. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs(Message))
    9. GlobalEventLogger.ExceptionToFile($"{Message}{Environment.NewLine}{ex.Message}", ExStatus.Failure)
    10. Return False
    11. End Try
    12. End Function


    @siycah
    Ja ​await / async kenn ich mittlerweile. Nutze das ja auch bei meiner Kopiermethode.
    Ich baue gerade die Copy-Class um.

    @-Franky-
    Habe dein zip mal angesehen. Püüüühh da ist noch vieles was ich noch nicht verstehe. Da brauche ich noch etwas (viel) Zeit. ;)
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Püüüühh da ist noch vieles was ich noch nicht verstehe.

    Der Umgang mit COM Interfaces ist auf den ersten Blick für viele erst einmal undurchsichtig und kompliziert. Wenn man sich damit aber mal intensiver beschäftigt, wird einem das gar nicht mehr so kompliziert vorkommen und man erkennt auch die Vorteile, die Windows von Haus aus in Form von APIs und COM Interfaces anbietet die es in .Net so nicht gibt.

    Für Dich wäre wahrscheinlich das WindowsAPICodePack, gibt es als NuGet, der einfachere Einstieg da hier viele neuere Schnittstellen, die es in .Net nicht gibt, enthalten sind. In diesem WindowsAPICodePack sollte auch IFileOperation, in Form von irgendeiner Klasse, enthalten sein die Du einfach nutzen kannst.
    Mfg -Franky-
    @-Franky-

    Ich werde mir das jedenfalls noch genauer ansehen. Mich erschlagen dabei diese Werte " SFGAO_CANCOPY = &H1 " usw. mit denen ich mal so gar nichts anfangen kann.

    Mit meinem Code, bin ich so weit das ich die Anfänge einer von @siycah erwähnten "StateMashine" am formulieren bin.
    Erste Versuche waren schonmal nicht schlecht.

    Na und dann war da noch die fast Endlos-Schleife von meiner "LoggerClass". Das Problem konnte ich nun auch beseitigen.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Moin moin

    Habe meine Class nun nach dem Vorschlag von @siycah umgebaut. :)
    Nach ersten Test läuft alles so wie ich es mir vorstellte.

    Wäre hier noch etwas zu "verbessern"?

    Spoiler anzeigen

    VB.NET-Quellcode

    1. ' Zustände des Kopiervorgangs
    2. Public Enum CopyState
    3. Busy
    4. Failure
    5. End Enum
    6. Public Class FileCopier
    7. Public CurrentState As CopyState = CopyState.Busy
    8. ' Zustand des Kopiervorgang
    9. Private Property ErrorLog As Boolean = False
    10. ' Flag für das einmalige Eintragen ins LogFile
    11. Public Property Canceling As Boolean = False
    12. ' Gibt an, ob der Kopiervorgang abgebrochen werden soll
    13. Public Event CopyProgressChanged As EventHandler(Of CopyProgressEventArgs)
    14. ' Ereignis, das ausgelöst wird, wenn sich der Kopierfortschritt ändert
    15. Public Event CopyCompleted As EventHandler(Of CopyCompletedEventArgs)
    16. ' Ereignis, das ausgelöst wird, wenn der Kopiervorgang erfolgreich abgeschlossen wurde
    17. Public Event CopyFailed As EventHandler(Of CopyFailedEventArgs)
    18. ' Ereignis, das ausgelöst wird, wenn ein Fehler beim Kopieren auftritt
    19. Public Sub New()
    20. End Sub
    21. Public Async Function CopyDirectoryAsync(sourceDir As String, targetDir As String) As Task
    22. ' Status setzen um einen erneuten Vorgang zu aktivieren
    23. CurrentState = CopyState.Busy
    24. ' Flag setzen um erneute Einträge zu zulassen
    25. ErrorLog = False
    26. Try
    27. ' Überprüfen, ob das Zielverzeichnis existiert, und wenn nicht, es erstellen
    28. Dim targetDirInfo As New DirectoryInfo(targetDir)
    29. If Not targetDirInfo.Exists Then
    30. targetDirInfo.Create()
    31. End If
    32. ' Starten des Kopiervorgangs
    33. Await CopyFilesAndSubDirectoriesAsync(sourceDir, targetDir)
    34. ' Überprüfen, ob der Kopiervorgang erfolgreich war
    35. If CurrentState <> CopyState.Failure Then
    36. Dim message As String = $"Kopieren erfolgreich abgeschlossen."
    37. RaiseEvent CopyCompleted(Me, New CopyCompletedEventArgs(message))
    38. GlobalEventLogger.ExceptionToFile(message, ExStatus.Success)
    39. End If
    40. Catch ex As Exception
    41. ' Fehlerbehandlung
    42. Dim message As String = $"Ein Fehler ist aufgetreten.{Environment.NewLine}{ex.Message}"
    43. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs(message))
    44. CurrentState = CopyState.Failure
    45. End Try
    46. End Function
    47. ' Methode um bei User-Abbruch ins LogFile zu schreiben
    48. Private Sub HandleCancellation()
    49. If Not ErrorLog Then
    50. Dim CancelingMessage As String = "Kopieren wurde vom Benutzer abgebrochen!"
    51. RaiseEvent CopyCompleted(Me, New CopyCompletedEventArgs(CancelingMessage))
    52. GlobalEventLogger.ExceptionToFile(CancelingMessage, ExStatus.Notifier)
    53. ErrorLog = True
    54. End If
    55. End Sub
    56. Private Async Function CopyFilesAndSubDirectoriesAsync(sourceDir As String, targetDir As String) As Task
    57. Dim sourceDirectoryInfo As New DirectoryInfo(sourceDir)
    58. For Each sourceFileOrDir As FileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos()
    59. ' Prüfen ob vom User abgebrochern werden soll
    60. If Canceling Then
    61. HandleCancellation()
    62. Exit For
    63. End If
    64. ' Prüfen ob durch Fehler abgebrochen werden soll
    65. If CurrentState = CopyState.Failure Then
    66. Exit For
    67. End If
    68. ' Überprüfung auf versteckte Dateien oder Ordner
    69. If (sourceFileOrDir.Attributes And FileAttributes.Hidden) <> FileAttributes.Hidden Then
    70. If TypeOf sourceFileOrDir Is FileInfo Then ' Wenn es sich um eine Datei handelt
    71. Await CopyFileAsync(DirectCast(sourceFileOrDir, FileInfo), targetDir)
    72. ElseIf TypeOf sourceFileOrDir Is DirectoryInfo Then ' Wenn es sich um ein Verzeichnis handelt
    73. Await CreateDirectoryAsync(DirectCast(sourceFileOrDir, DirectoryInfo), targetDir)
    74. End If
    75. End If
    76. Next
    77. End Function
    78. Private Async Function CopyFileAsync(file As FileInfo, targetDir As String) As Task
    79. Try
    80. ' Abbruchprüfungen
    81. 'CheckForCancellationAndFailure()
    82. ' Angezeigten Pfad kürzen
    83. Dim targetFile As String = Path.Combine(targetDir, file.Name)
    84. Dim formattedPath As String = targetFile
    85. Dim directoryStructure As String() = formattedPath.Split("\"c)
    86. Dim driveLetter As String = Path.GetPathRoot(targetDir)
    87. formattedPath = Path.Combine(driveLetter, directoryStructure(1), " ..... ", directoryStructure(directoryStructure.Length - 1))
    88. ' Größeren Puffer verwenden, um die Leistung zu optimieren
    89. Dim bufferSize As Integer = 256 * 1024 * 1024
    90. Using sourceStream As FileStream = file.OpenRead(),
    91. destinationStream As New FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, True)
    92. Await sourceStream.CopyToAsync(destinationStream)
    93. End Using
    94. ' Copymethode ohne Bufferzeuweisung
    95. 'Await Task.Run(Sub() file.CopyTo(targetFile, True))
    96. RaiseEvent CopyProgressChanged(Me, New CopyProgressEventArgs(formattedPath))
    97. Catch ex As Exception
    98. Dim message As String = $"Fehler beim Kopieren der Datei {file.Name}:{Environment.NewLine}{ex.Message}"
    99. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs(message))
    100. CurrentState = CopyState.Failure
    101. Exit Function
    102. End Try
    103. End Function
    104. Private Async Function CreateDirectoryAsync(directory As DirectoryInfo, targetDir As String) As Task
    105. Try
    106. ' Abbruchprüfungen
    107. 'CheckForCancellationAndFailure()
    108. Dim targetSubDir As String = Path.Combine(targetDir, directory.Name)
    109. Dim targetSubDirInfo As New DirectoryInfo(targetSubDir)
    110. If Not targetSubDirInfo.Exists Then
    111. targetSubDirInfo.Create()
    112. End If
    113. Await CopyFilesAndSubDirectoriesAsync(directory.FullName, targetSubDir)
    114. Catch ex As Exception
    115. Dim message As String = $"Fehler beim Erstellen des Verzeichnisses {directory.Name}:{Environment.NewLine}{ex.Message}"
    116. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs(message))
    117. CurrentState = CopyState.Failure
    118. Exit Function
    119. End Try
    120. End Function
    121. '' Diese Prüfungen funktionieren auch ohne diesen Abschnitt in den Funktionen
    122. '' Bis auf weiteres Auskommentiert
    123. 'Private Sub CheckForCancellationAndFailure()
    124. ' ' Prüfen ob vom User abgebrochen werden soll
    125. ' If Canceling Then
    126. ' HandleCancellation()
    127. ' Exit Sub
    128. ' End If
    129. ' ' Prüfen ob durch Fehler abgebrochen werden soll
    130. ' If CurrentState = CopyState.Failure Then
    131. ' Exit Sub
    132. ' End If
    133. 'End Sub
    134. End Class
    135. Public Class CopyProgressEventArgs
    136. Inherits EventArgs
    137. Public Property FileName As String
    138. Public Sub New(fileName As String)
    139. Me.FileName = fileName
    140. End Sub
    141. End Class
    142. Public Class CopyCompletedEventArgs
    143. Inherits EventArgs
    144. Public Property Message As String
    145. Public Sub New(message As String)
    146. Me.Message = message
    147. End Sub
    148. End Class
    149. Public Class CopyFailedEventArgs
    150. Inherits EventArgs
    151. Public Property ErrorMessage As String
    152. Public Sub New(errorMessage As String)
    153. Me.ErrorMessage = errorMessage
    154. End Sub
    155. End Class





    Beim testen meiner neuen Class meldete mir irgendwann während des kopieren, der Logger folgendes:

    XML-Quellcode

    1. [ 05.05.2024 | 11:56:39 ] Hinweis
    2. EventLogfile für Mai 2024 erstellt.
    3. [ 05.05.2024 | 11:56:39 ] Erfolgreich
    4. Das Laden der Programm-Konfiguration aus der XML-Datei B:\Debug\Settings.xml war erfolgreich.
    5. [ 05.05.2024 | 11:56:58 ] Hinweis
    6. Der Backup-Prozess wurde gestartet.
    7. [ 05.05.2024 | 12:09:29 ] Fehler
    8. Fehler beim Kopieren der Datei Microsoft.VisualStudio.LanguageServices.ConvertTupleToStructCodeRefactoring64.servicehub.service.json:
    9. Der angegebene Pfad und/oder Dateiname ist zu lang. Der vollständig qualifizierte Dateiname muss kürzer als 260 Zeichen und der Pfadname kürzer als 248 Zeichen sein.


    OK, die Class, fängt also Fehler ordentlich ab usw...
    Aber wie kann ich so etwas vermeiden? Dieser Pfad / Datei ist ja irgendwann mal von Visualstudio angelegt worden????

    Beiträge zusammengefügt. ~Thunderbolt
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    Amelie schrieb:


    OK, die Class, fängt also Fehler ordentlich ab usw...
    Aber wie kann ich so etwas vermeiden? Dieser Pfad / Datei ist ja irgendwann mal von Visualstudio angelegt worden????


    Das ist eine Einstellung deines OS welches mit dem Gruppenrichtlinieneditor oder der Regitry aufgehoben werden kann. Fuer letzteres versuche mal in der Registry unter:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem
    den DWORD 'LongPathsEnabled' auf '1' zu setzen.
    @Amelie Ich bin mir da immer nicht sicher ob dieser Reg-Key die Beschränkung von MAX_PATH (260 Zeichen) bei alten APIs wirklich aufhebt. Genaues Erfährst Du hier: learn.microsoft.com/en-us/wind…-limitation?tabs=registry Evtl. noch -> The application manifest must also include the longPathAware element. Und wenn ich das so lese, gilt das erst ab Win10.
    Mfg -Franky-
    @-Franky-
    Nach ersten Test habe ich das wohl gelöst bekommen.

    Habe das: "_LibraryBackUp" gegen "_BackUp" getauscht. Das wären schonmal 7 Zeichen weniger. ;) Das ist das Verzeichnis wo die BackUps reingeschrieben werden.

    Habe mir unter anderem folgendes in eine "LibDrive.manifest" gepackt die im selben Verzeichnis wie die EXE-Datei liegt. So habe ich das in dem Text auf der Webseite verstanden.

    XML-Quellcode

    1. <application xmlns="urn:schemas-microsoft-com:asm.v3">
    2. <windowsSettings>
    3. <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    4. <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
    5. </windowsSettings>
    6. </application>



    Und die Funktion folgendermaßen geändert.

    VB.NET-Quellcode

    1. Private Async Function CopyFileAsync(file As FileInfo, targetDir As String) As Task
    2. Try
    3. ' Ziel-Dateipfad erstellen
    4. Dim targetFile As String = Path.Combine(targetDir, file.Name)
    5. ' Größeren Puffer verwenden, um die Leistung zu optimieren
    6. Dim bufferSize As Integer = 8 * 1024 * 1024
    7. ' Angezeigten Pfad kürzen
    8. Dim directoryStructure As String() = targetDir.TrimEnd("\"c).Split("\"c)
    9. Dim driveLetter As String = Path.GetPathRoot(targetDir)
    10. Dim formattedPath As String = Path.Combine(driveLetter, String.Join("\", directoryStructure.Take(3)), " .... ", file.Name)
    11. ' Quell- und Zielstreams öffnen
    12. Using sourceStream As FileStream = file.OpenRead(),
    13. destinationStream As New FileStream(targetFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, True)
    14. ' Datei kopieren
    15. Await sourceStream.CopyToAsync(destinationStream)
    16. End Using
    17. ' Fortschritt aktualisieren
    18. Dim fileSize As Long = file.Length ' Größe der Quelldatei
    19. RaiseEvent CopyProgressChanged(Me, New CopyProgressEventArgs(formattedPath))
    20. RaiseEvent CopyProgressChangedSize(fileSize)
    21. Catch ex As UnauthorizedAccessException
    22. ' Behandle Zugriffsfehler
    23. Dim message As String = $"Zugriff auf die Datei {file.Name} verweigert: {ex.Message}"
    24. RaiseEvent CopyWarning(Me, New CopyWarningEventArgs(message))
    25. Catch ex As IOException
    26. ' Behandle andere E/A-Fehler
    27. Dim message As String = $"Fehler beim Kopieren der Datei {file.Name}: {ex.Message}"
    28. RaiseEvent CopyWarning(Me, New CopyWarningEventArgs(message))
    29. Catch ex As Exception
    30. ' Andere Ausnahmen behandeln
    31. Dim message As String = $"Ein unerwarteter Fehler ist aufgetreten beim Kopieren der Datei {file.Name}: {ex.Message}"
    32. RaiseEvent CopyFailed(Me, New CopyFailedEventArgs(message))
    33. CurrentState = CopyState.Failure
    34. Exit Function
    35. End Try
    36. End Function
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Entschuldige die späte Antwort, gibt im Moment viel zu tun :)

    Amelie schrieb:

    Wäre hier noch etwas zu "verbessern"?

    Immer! :)

    Amelie schrieb:

    Public Sub New()
    End Sub


    Wenn du den Constructor nicht braucht, schreib ihn nicht explizit rein. Lass das den Compiler machen.

    Und entferne deinen auskommentierten Code.

    Ansonsten muss ich sagen, ist das wirklich gut gelungen. Daumen hoch :thumbup:
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.
    @Amelie Wenn ich mich richtig erinnere, entwickelst Du Deine Software noch nicht unter Win10 oder? Wenn dem noch so ist, dann wird Dir der Reg-Key bzw. der Teil für das Manifest nichts nützen da das erst ab Windows 10, Version 1607 eingeführt wurde. Du brauchst auch keine extra Manifestdatei neben der Exe liegen zu haben. Das Manifest für Dein Projekt kannst Du direkt in den Projekteigenschaften bearbeiten.
    Mfg -Franky-
    @siycah

    Danke :)
    Ja den "nicht verwendeten" Code nehme ich in der Release Version immer raus.
    Ja und den Konstruktor, las ich mal irgendwo, das man den reinsetzen soll, damit er nicht von "außen" manipuliert werden kann :?:

    @-Franky-

    Genau, ich habe noch Windows 7-64Bit. :thumbsup:

    Thema Manifest.
    Ja das habe ich im Studio unter den "Windows-Einstellungen" gemacht. Las aber irgendwo, das ich diese "Manifest-Datei" neben der Exe-Datei packen sollte.

    Dann hat es evtl gereicht, das ich den Anfang von dem kompletten Zielpfad etwas gekürzt habe um den Fehler mit dem "überlangen Namen" zu beheben??
    Werde das mal austesten :)
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    @Amelie Es gibt 2 Möglichkeiten für ein Manifest. Eines das neben der Exe liegt und eines das direkt in die Exe einkompiliert ist. Vorzugsweise verwendet man die zweite Möglichkeit. Da in .NET sowieso ein Manifest mit einkompiliert wird, würde ich auch dieses Manifest bearbeiten und nicht zusätzlich eines neben die Exe legen.
    Mfg -Franky-

    Amelie schrieb:

    Ja und den Konstruktor, las ich mal irgendwo, das man den reinsetzen soll


    Den Constructur musst du nur händisch einbauen, wenn du ein anderes Verhalten brauchst, als das Standardverhalten.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.