347 lines
14 KiB
VB.net
347 lines
14 KiB
VB.net
Imports System.IO
|
|
Imports DigitalData.Modules.Logging
|
|
''' <summary>
|
|
''' Zentrale Klasse für Dokumentenpfad-Verwaltung mit optionalem Laufwerks-Mapping und Temp-Kopie
|
|
''' </summary>
|
|
Public Class DocumentPathHandler
|
|
|
|
Private ReadOnly _Logger As Logger
|
|
Private ReadOnly _LogConfig As LogConfig
|
|
Private _mappedDrive As String = ""
|
|
Private _clsmapDrive As Map_Drive
|
|
|
|
Public Sub New(LogConfig As LogConfig)
|
|
_LogConfig = LogConfig
|
|
_Logger = LogConfig.GetLogger()
|
|
_clsmapDrive = New Map_Drive(LogConfig)
|
|
End Sub
|
|
|
|
Private Function EnsureTempFolder(ByRef tempFolder As String, ByRef errorMessage As String) As Boolean
|
|
Try
|
|
_Logger.Debug($"📂 Überprüfe Temp-Ordner: [{tempFolder}]")
|
|
If String.IsNullOrWhiteSpace(tempFolder) Then
|
|
_Logger.Debug("⚠️ Temp-Ordner nicht konfiguriert, verwende TEMP_DOCUMENT_FOLDER aus AppSettings")
|
|
tempFolder = TEMP_DOCUMENT_FOLDER
|
|
End If
|
|
|
|
' Fallback, falls global nichts konfiguriert ist
|
|
If String.IsNullOrWhiteSpace(tempFolder) Then
|
|
tempFolder = Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
|
"Digital Data",
|
|
"taskFLOW",
|
|
"DocumentViewer",
|
|
"Temp")
|
|
_Logger.Info($"⚠️ TEMP_DOCUMENT_FOLDER war leer - verwende Fallback: [{tempFolder}]")
|
|
TEMP_DOCUMENT_FOLDER = tempFolder
|
|
End If
|
|
|
|
If Not Directory.Exists(tempFolder) Then
|
|
Directory.CreateDirectory(tempFolder)
|
|
_Logger.Info($"📁 Temp-Ordner erstellt: [{tempFolder}]")
|
|
End If
|
|
|
|
If Not Directory.Exists(tempFolder) Then
|
|
errorMessage = $"Temp-Ordner konnte nicht erstellt werden: [{tempFolder}]"
|
|
Return False
|
|
End If
|
|
|
|
Return True
|
|
|
|
Catch ex As Exception
|
|
errorMessage = $"Fehler bei Temp-Ordner-Initialisierung: {ex.Message}"
|
|
_Logger.Error($"❌ {errorMessage}")
|
|
_Logger.Error(ex)
|
|
Return False
|
|
End Try
|
|
End Function
|
|
''' <summary>
|
|
''' Verarbeitet einen Dokumentenpfad: Optional Mapping, dann Temp-Kopie
|
|
''' </summary>
|
|
''' <param name="sourcePath">Quell-Pfad der Datei (UNC oder lokal)</param>
|
|
''' <param name="options">Optionen für die Verarbeitung</param>
|
|
''' <returns>DocumentPathResult mit finalem Pfad und Mapping-Info</returns>
|
|
Public Function ProcessDocumentPath(sourcePath As String, options As DocumentPathOptions) As DocumentPathResult
|
|
Dim result As New DocumentPathResult With {
|
|
.SourcePath = sourcePath,
|
|
.FinalPath = sourcePath,
|
|
.Success = False,
|
|
.WasMapped = False,
|
|
.WasCopiedToTemp = False
|
|
}
|
|
|
|
Try
|
|
' Validierung
|
|
If String.IsNullOrEmpty(sourcePath) Then
|
|
result.ErrorMessage = "Quell-Pfad ist leer"
|
|
_Logger.Error("❌ ProcessDocumentPath: Quell-Pfad ist leer")
|
|
Return result
|
|
End If
|
|
|
|
Dim workingPath As String = sourcePath
|
|
|
|
' ========== SCHRITT 1: OPTIONALES LAUFWERKS-MAPPING ==========
|
|
If options.EnableMapping AndAlso Not String.IsNullOrEmpty(options.WMSuffix) Then
|
|
Dim mappingResult = TryMapNetworkDrive(sourcePath, options)
|
|
If mappingResult.Success Then
|
|
workingPath = mappingResult.MappedPath
|
|
_mappedDrive = mappingResult.DriveLetter
|
|
result.WasMapped = True
|
|
result.MappedDrive = _mappedDrive
|
|
_Logger.Info($"✓ Laufwerk gemappt: {_mappedDrive}")
|
|
Else
|
|
_Logger.Warn("⚠️ Laufwerks-Mapping fehlgeschlagen - verwende Original-UNC-Pfad")
|
|
workingPath = sourcePath
|
|
End If
|
|
End If
|
|
|
|
' ========== SCHRITT 2: PRÜFEN OB DATEI EXISTIERT ==========
|
|
If Not File.Exists(workingPath) Then
|
|
result.ErrorMessage = $"Datei nicht gefunden: [{workingPath}]"
|
|
_Logger.Error($"❌ {result.ErrorMessage}")
|
|
|
|
' Cleanup bei Fehler
|
|
If result.WasMapped Then
|
|
UnmapDrive()
|
|
End If
|
|
|
|
Return result
|
|
End If
|
|
|
|
' ========== SCHRITT 3: OPTIONALE TEMP-KOPIE ==========
|
|
If options.CopyToTemp Then
|
|
_Logger.Debug($"📂 Starte Temp-Kopie für: [{workingPath}]")
|
|
Dim tempResult = CopyToTempFolder(workingPath, options.TempFolder)
|
|
If tempResult.Success Then
|
|
result.FinalPath = tempResult.TempPath
|
|
result.WasCopiedToTemp = True
|
|
result.TempPath = tempResult.TempPath
|
|
_Logger.Info($"✓ Datei in Temp kopiert: [{Path.GetFileName(tempResult.TempPath)}]")
|
|
|
|
' Laufwerk unmappen nach erfolgreicher Kopie
|
|
If result.WasMapped AndAlso options.UnmapAfterCopy Then
|
|
UnmapDrive()
|
|
result.WasMapped = False
|
|
End If
|
|
Else
|
|
_Logger.Warn($"⚠️ Temp-Kopie fehlgeschlagen: {tempResult.ErrorMessage}")
|
|
|
|
' WICHTIG: Nicht den gemappten Pfad behalten, wenn danach ungemappt wird.
|
|
' Fallback immer auf stabilen Originalpfad (UNC).
|
|
result.FinalPath = sourcePath
|
|
result.WasCopiedToTemp = False
|
|
result.TempPath = String.Empty
|
|
|
|
If result.WasMapped Then
|
|
UnmapDrive()
|
|
result.WasMapped = False
|
|
End If
|
|
End If
|
|
Else
|
|
result.FinalPath = workingPath
|
|
_Logger.Debug($"📄 Verwende Pfad ohne Temp-Kopie: [{workingPath}]")
|
|
End If
|
|
|
|
result.Success = True
|
|
Return result
|
|
|
|
Catch ex As Exception
|
|
result.ErrorMessage = $"Unerwarteter Fehler: {ex.Message}"
|
|
_Logger.Error($"❌ ProcessDocumentPath: {ex.Message}")
|
|
_Logger.Error(ex)
|
|
|
|
' Cleanup bei Exception
|
|
If result.WasMapped Then
|
|
UnmapDrive()
|
|
End If
|
|
|
|
Return result
|
|
End Try
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Versucht ein Netzlaufwerk zu mappen
|
|
''' </summary>
|
|
Private Function TryMapNetworkDrive(sourcePath As String, options As DocumentPathOptions) As MappingResult
|
|
Dim result As New MappingResult With {.Success = False}
|
|
|
|
Try
|
|
' Prüfen ob Pfad mit WMSUFFIX beginnt
|
|
If Not sourcePath.StartsWith(options.WMSuffix, StringComparison.OrdinalIgnoreCase) Then
|
|
_Logger.Debug($"📄 Pfad beginnt nicht mit WMSUFFIX - kein Mapping erforderlich")
|
|
Return result
|
|
End If
|
|
|
|
_Logger.Debug($"📂 WMSUFFIX erkannt - starte Laufwerks-Mapping")
|
|
|
|
' Laufwerk mappen
|
|
Dim mappedDrive As String = ""
|
|
|
|
If Not String.IsNullOrEmpty(options.SpecificDrive) AndAlso options.SpecificDrive.Length = 1 Then
|
|
' Spezifisches Laufwerk
|
|
If _clsmapDrive.MapSpecificDrive(options.SpecificDrive, options.DriveBlacklist, options.WMSuffix) Then
|
|
mappedDrive = options.SpecificDrive & ":"
|
|
End If
|
|
Else
|
|
' Automatisches Mapping
|
|
mappedDrive = _clsmapDrive.MapDriveAutomatic(options.DriveBlacklist, options.WMSuffix)
|
|
End If
|
|
|
|
If String.IsNullOrEmpty(mappedDrive) Then
|
|
_Logger.Warn("⚠️ Kein Laufwerk gemappt")
|
|
Return result
|
|
End If
|
|
|
|
' Pfad umschreiben
|
|
Dim relativePath As String = sourcePath.Substring(options.WMSuffix.Length)
|
|
If relativePath.StartsWith("\") Then
|
|
relativePath = relativePath.Substring(1)
|
|
End If
|
|
|
|
Dim mappedPath As String = mappedDrive.TrimEnd(":"c, "\"c) & ":\" & relativePath
|
|
|
|
_Logger.Debug($"📄 Original: [{sourcePath}]")
|
|
_Logger.Debug($"📄 Gemappt: [{mappedPath}]")
|
|
|
|
result.Success = True
|
|
result.DriveLetter = mappedDrive
|
|
result.MappedPath = mappedPath
|
|
Return result
|
|
|
|
Catch ex As Exception
|
|
_Logger.Error($"Fehler beim Mapping: {ex.Message}")
|
|
_Logger.Error(ex)
|
|
Return result
|
|
End Try
|
|
End Function
|
|
|
|
Private Function CopyToTempFolder(sourcePath As String, tempFolder As String) As TempCopyResult
|
|
Dim result As New TempCopyResult With {.Success = False}
|
|
|
|
Try
|
|
Dim configuredTempFolder As String = tempFolder
|
|
Dim globalTempFolder As String = TEMP_DOCUMENT_FOLDER
|
|
|
|
' Temp-Ordner validieren/initialisieren (kann tempFolder per ByRef setzen)
|
|
If Not EnsureTempFolder(tempFolder, result.ErrorMessage) Then
|
|
_Logger.Warn($"⚠️ {result.ErrorMessage}")
|
|
_Logger.Warn($"[TempCopy] InputTemp=[{If(String.IsNullOrWhiteSpace(configuredTempFolder), "<leer>", configuredTempFolder)}], GlobalTemp=[{If(String.IsNullOrWhiteSpace(globalTempFolder), "<leer>", globalTempFolder)}]")
|
|
Return result
|
|
End If
|
|
|
|
' NEU: Effektiven Zielordner immer transparent loggen
|
|
_Logger.Info($"[TempCopy] Effektiver Temp-Ordner: [{tempFolder}]")
|
|
_Logger.Debug($"[TempCopy] InputTemp=[{If(String.IsNullOrWhiteSpace(configuredTempFolder), "<leer>", configuredTempFolder)}], GlobalTemp=[{If(String.IsNullOrWhiteSpace(globalTempFolder), "<leer>", globalTempFolder)}]")
|
|
|
|
' Eindeutigen Dateinamen generieren
|
|
Dim originalFileName As String = Path.GetFileName(sourcePath)
|
|
Dim fileNameWithoutExt As String = Path.GetFileNameWithoutExtension(originalFileName)
|
|
Dim extension As String = Path.GetExtension(originalFileName)
|
|
Dim timestamp As String = DateTime.Now.ToString("yyyyMMdd_HHmmss_fff")
|
|
Dim uniqueFileName As String = $"{fileNameWithoutExt}_{timestamp}{extension}"
|
|
Dim targetPath As String = Path.Combine(tempFolder, uniqueFileName)
|
|
|
|
_Logger.Debug($"📄 Kopiere nach Temp:")
|
|
_Logger.Debug($" Von: [{sourcePath}]")
|
|
_Logger.Debug($" Nach: [{targetPath}]")
|
|
|
|
File.Copy(sourcePath, targetPath, overwrite:=True)
|
|
|
|
result.Success = True
|
|
result.TempPath = targetPath
|
|
result.TempFileName = uniqueFileName
|
|
Return result
|
|
|
|
Catch ex As Exception
|
|
result.ErrorMessage = $"Fehler beim Kopieren: {ex.Message}"
|
|
_Logger.Error($"❌ {result.ErrorMessage}")
|
|
_Logger.Error(ex)
|
|
Return result
|
|
End Try
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Trennt das gemappte Laufwerk
|
|
''' </summary>
|
|
Public Sub UnmapDrive()
|
|
If Not String.IsNullOrEmpty(_mappedDrive) Then
|
|
Try
|
|
If _clsmapDrive.DisconnectNetworkDrive(_mappedDrive, force:=True) Then
|
|
_Logger.Info($"🔌 Laufwerk {_mappedDrive} getrennt")
|
|
Else
|
|
_Logger.Warn($"⚠️ Warnung beim Trennen von {_mappedDrive}")
|
|
End If
|
|
Catch ex As Exception
|
|
_Logger.Debug($"Fehler beim Trennen von {_mappedDrive}: {ex.Message}")
|
|
Finally
|
|
_mappedDrive = ""
|
|
End Try
|
|
End If
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Cleanup-Methode (z.B. beim Schließen des Forms)
|
|
''' </summary>
|
|
Public Sub Cleanup()
|
|
UnmapDrive()
|
|
End Sub
|
|
|
|
#Region "Nested Classes für Optionen und Ergebnisse"
|
|
|
|
''' <summary>
|
|
''' Optionen für die Dokumentenpfad-Verarbeitung
|
|
''' </summary>
|
|
Public Class DocumentPathOptions
|
|
''' <summary>Soll Laufwerks-Mapping versucht werden?</summary>
|
|
Public Property EnableMapping As Boolean = False
|
|
|
|
''' <summary>WMSUFFIX für Mapping-Erkennung (z.B. "\\windream\objects")</summary>
|
|
Public Property WMSuffix As String = ""
|
|
|
|
''' <summary>Spezifischer Laufwerksbuchstabe (z.B. "V") oder leer für automatisch</summary>
|
|
Public Property SpecificDrive As String = ""
|
|
|
|
''' <summary>Blacklist für Laufwerksbuchstaben (z.B. "Y,M,V")</summary>
|
|
Public Property DriveBlacklist As String = ""
|
|
|
|
''' <summary>Soll Datei in Temp kopiert werden?</summary>
|
|
Public Property CopyToTemp As Boolean = False
|
|
|
|
''' <summary>Temp-Ordner-Pfad</summary>
|
|
Public Property TempFolder As String = ""
|
|
|
|
''' <summary>Laufwerk nach erfolgreicher Temp-Kopie unmappen?</summary>
|
|
Public Property UnmapAfterCopy As Boolean = True
|
|
End Class
|
|
|
|
''' <summary>
|
|
''' Ergebnis der Dokumentenpfad-Verarbeitung
|
|
''' </summary>
|
|
Public Class DocumentPathResult
|
|
Public Property Success As Boolean
|
|
Public Property SourcePath As String
|
|
Public Property FinalPath As String
|
|
Public Property ErrorMessage As String
|
|
Public Property WasMapped As Boolean
|
|
Public Property MappedDrive As String
|
|
Public Property WasCopiedToTemp As Boolean
|
|
Public Property TempPath As String
|
|
End Class
|
|
|
|
Private Class MappingResult
|
|
Public Property Success As Boolean
|
|
Public Property DriveLetter As String
|
|
Public Property MappedPath As String
|
|
End Class
|
|
|
|
Private Class TempCopyResult
|
|
Public Property Success As Boolean
|
|
Public Property TempPath As String
|
|
Public Property TempFileName As String
|
|
Public Property ErrorMessage As String
|
|
End Class
|
|
|
|
#End Region
|
|
|
|
End Class
|