Announcement

Collapse
No announcement yet.

Kopieren klappt nicht immer

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Kopieren klappt nicht immer

    Hallo zusammen

    Ich habe ein eigenartiges Problem dem ich nicht auf die schliche komme. Ich bin mir nicht mal sicher ob es sich hier um ein Programmier-Problem oder ein Windows-Problem handelt. Es ist wie folgt:

    Ich habe ein Programm was sich von einem Netzwerkpfad (nicht Netzlaufwerk) eine Datei kopiert. Und genau hier das Problem. Wenn ich das Programm (welches als Dienst läuft) starte kopiert er das erste mal die Datei nicht weil er sagt die ZIEL-Datei sei in Verwendung. dann läuft ein Timer und nach 5 Minuten startet der Kopiervorgang wieder (gleiche Ziel und Quell-Datei, nichts an beiden Dateien geändert) und es klappt. innerhalb dieser 5 Minuten versucht die Kopier-Prozedur alle 10 Sekunden die Datei zu kopieren und es klappt nicht (mittels Schleife wie im Code unten zu sehen ist). Wenn das Programm dann im 5-Minuten Modus käuft klappt es in weiterer Folge immer und die Datei wird erfolreich kopiert. nur beim 1. mal nicht.

    Interessant ist noch folgendes: wenn ich den Timer runterdrehe, so das er alle 2 Minuten feuert klappt es mal ja, mal nein (zu 95% abwechselnd).

    Hier der Code der Kopier-Funktion welche vom Timer aufgerufen wird:

    [highlight=vbnet]
    Public Sub CopyImportFile()
    Dim CountCopyTries_act As Integer = 0
    Dim CountCopyTries_ms As Integer = 0

    Dim retvalue As Long
    Try
    Do
    If File.Exists(ImportFilePersons_temp) Then File.Delete(ImportFilePersons_temp)
    If CountCopyTries_act = 0 Then WriteLog("Copy File " & ImportFilePersons & " to " & ImportFilePersons_temp)

    retvalue = CopyFile(ImportFilePersons, ImportFilePersons_temp, 0)
    WriteLog("CopyImportFile: " & retvalue)

    CountCopyTries_act = CountCopyTries_act + 1
    CountCopyTries_ms = CountCopyTries_ms + 10
    If retvalue = 1 Then
    Thread.CurrentThread.Sleep(10000) 'wait 10 seconds
    End If
    WriteLog("Try Nr. " & CountCopyTries_act & " waited for " & CountCopyTries_ms & " seconds")
    Loop Until retvalue = 0 Or CountCopyTries_act = CountCopyTries

    If CountCopyTries_act = CountCopyTries Then
    WriteLog("Copying of File " & ImportFilePersons & " not possible")
    End If
    Catch ex As Exception
    WriteLog("CopyImportFile: " & ex.Message)
    End Try
    End Sub
    [/highlight]

    Hier die Funktion CopyFile:

    [highlight=vbnet]
    Public Declare Function CopyFile Lib "kernel32.dll" _
    Alias "CopyFileA" ( _
    ByVal lpExistingFileName As String, _
    ByVal lpNewFileName As String, _
    ByVal bFailIfExists As Long) As Long
    [/highlight]

    Ich habe keine Ahnung was das sein kann... habt ihr vielleicht eine idee?

    LG
    michael

  • #2
    Hallo

    Hat denn niemand eine Idee oder einen Ansatz den ich noch verfolgen könnte?

    Ich häng noch immer dran...
    LG
    Michael

    Comment


    • #3
      Hallo Michael,

      "von einem Netzwerkpfad" ... "Wenn ich das Programm (welches als Dienst läuft)"

      Als welcher Benutzer läuft der Dienst?
      Was ist das für ein Server? Windows, Samba?

      Was für ein Fehler tritt denn auf, wenn es nicht funktioniert?
      Was sagt denn GetlastError?

      Um was für Dateien handelt es sich? Kann es evtl sein, dass ein Virenscanner die Datei lockt?

      Haste mal mit processexplorer geschaut, ob wirklich "jemand" die Datei offen hat?
      --------------------------------------------------------
      Signatur im Brandfall nicht benutzen !

      Comment


      • #4
        Hallo moppedmann

        Das sind viele Fragen auf einmal einen Teil mag ich dir jetzt mal beantworten, den rest muss ich erst checken (processexplorer)
        Der Dienst läuft als LocalSystem. Das Kopieren der QUELL Datei macht auch nie Probleme. Das Programm behauptet immer das die ZIEL Datei (die ja lokal liegt) in Verwendung ist.


        GetLastError sagt mir nichts. Was genau ist das? Ich kann dir die Fehlermeldung der Exception sagen:
        Der Prozess kann nicht auf die Datei "D:\Pfad\Unterpfad\datei_temp.csv" zugreifen, da sie von einem anderen Prozess verwendet wird.

        D:\Pfad\Unterpfad\datei_temp.csv ist hierbei wie gesagt die Ziel und nicht die Quelldatei

        Es handelt sich um eine CSV-Datei. Also eigentlich nichts wo ein VirenScanner mucken könnte. Dennoch werde ich ihm zum testen mal deaktivieren.

        LG
        Michael

        [UPDATE]

        der Virenscanner ist es nicht. Auch wenn dieser deaktiviert ist gehts mal ja mal nein.

        Comment


        • #5
          Der Prozess kann nicht auf die Datei "D:\Pfad\Unterpfad\datei_temp.csv" zugreifen, da sie von einem anderen Prozess verwendet wird.
          Konkret jetzt beim File.Delete oder beim CopyFile? Und warum benutzt du die CopyFile API direkt? Wenn du schon File.Delete benutzt würde ich auch File.Copy nehmen.

          Edit: Insbesondere merkwürdig weil du CopyFileA benutzt und .Net eine durchgängig Unicode Umgebung ist die mit ANSI nicht wirklich viel anzufangen weiß(oder überhaupt müsste) .

          Comment


          • #6
            Hallo Ralf

            Diese Funktion verwende ich anstatt File.Copy (was ich zunächst verwendet habe) weil ich es nicht hinbekommen habe mit File.Copy eine Rückmeldung zu bekommen ob das kopieren geklappt hat. Die brauch ich aber um die Schleife zu durchlaufen die es immer wieder versucht. Mit File.Copy habe ich aber auf jeden fall das gleiche Bild.

            Die Fehlermeldung kommt konkret beim kopieren. In diesem Fall kommt die Fehlermeldung von einem File.Copy welches ich schnell vor das CopyFile geschrieben habe, da mit das CopyFile keine Fehlermeldung auswirft, sondern nur die Info das es nicht geklappt hat.

            zu deinem Edit: Das verstehe ich nicht so ganz. Wärst du so lieb und beschreibst genauer was du meinst?

            LG
            Michael

            Comment


            • #7
              zu deinem Edit: Das verstehe ich nicht so ganz. Wärst du so lieb und beschreibst genauer was du meinst?
              Die Windows API exitiert weitestgehend in zweifacher Ausfertigung. Zum Beispiel hier bei CopyFile gibt es dahinter die gedoppelten Methoden CopyFileA und CopyFileW. Einmal für ANSI (A) und einmal für Unicode (W). Wenn man einfach CopyFile referenziert wird das System selbstständig erkennen welche der beiden konkreten Implementierungen den zu verwenden ist. Du hast aber explizit die ANSI Version gewählt und das fand ich merkwürdig da .Net ein reines Unicode System ist. Wenn man also selbst entscheidet ob man die A oder W Version verwendet würde man wohl immer zur W Version greifen un dnicht zu A. Daher wollte ich wissen ob du dafür einen speziellen Grund hast.


              weil ich es nicht hinbekommen habe mit File.Copy eine Rückmeldung zu bekommen ob das kopieren geklappt hat
              Wenn File.Copy einfach durchgeht hat es geklappt wenn du eine Exception bekommst nicht. Das erscheint mir eigentlich ein ziemlich eindeutiges Kennzeichen . Bei CopyFile bekommst du sogar nur eine Ja/Nein Aussage die noch viel weniger Aussage kräftig ist. Außer du wertest mit GetLastError genau aus was den passiert ist was du aber gar nicht tust. Worauf mopped (ist das dein Vorname?) ja auch schon hingewiesen hat. Eigentlich ist das auch genau das was File.Copy intern tut. Also CopyFile aufrufen, Return Wert überprüfen, im Falle des Falles GetLastError Aufrufen und dann mit diesem Error eine Exception werfen. Oder eben bei Erfolg dann CopyFile einfach weiterlaufen lassen.

              Comment


              • #8
                ich hab eben mal ausprobiert, ob ich das reproduzieren kann. Leider negativ.

                Vielleicht testest du mal diesen code hier, ob der Ferhler damit auch auftritt und wenn ja, welcher...

                [highlight=vbnet]

                Imports System.IO
                Imports System.Runtime.InteropServices

                Module Module1
                <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
                Public Function CopyFile(ByVal src As String, ByVal dst As String, ByVal failIfExists As Boolean) As Boolean
                End Function

                Dim origfile As String = "\\10.1.1.1\buero$\asd\hypertrm.exe"
                Dim newfile As String = "F:\header\neuedatei.raw"


                Sub Main()
                Try

                Dim retvalue As Long

                If File.Exists(newfile) Then File.Delete(newfile)

                retvalue = CopyFile(origfile, newfile, 0)

                Console.WriteLine(retvalue)
                Console.WriteLine(Err.LastDllError)

                Console.ReadKey()

                Catch ex As System.ComponentModel.Win32Exception

                Console.WriteLine(ex.Message.ToString)
                Console.ReadKey()

                End Try

                End Sub

                End Module
                [/highlight]
                --------------------------------------------------------
                Signatur im Brandfall nicht benutzen !

                Comment


                • #9
                  Hallo zusammen

                  Zunächst zu Ralf:
                  Ich verstehe immernoch nicht was du meinst. Ich verwende ja CopyFile und nicht CopyFileA. Also nehme ich eh das richtige weil die API selber entscheidet was genommen werden soll richtig?
                  Das mit GetLastError kannte ich ehrlichgesagt bisher gar nicht. Ich werde diese Funktion mal genauer unter die Lupe nehmen

                  Nun zu Moped:
                  ich habe deinen Code verwendet und bekomme als Meldung von getLastDllError: 183

                  Ich habe das Problem mithilfe deiner Funktion aber gefunden. Also eigentlich bin ich drauf gekommen weil ich mal ein paar Tage Abstand vom Programm hatte und so neu an das Problem gehen konnte.
                  Ich habe in weiterer Folge eine Funktion welche die CSV-Datei ausliest. Offfensichtlich habe ich den FileStream nicht richtig geschlossen. Daher war die Datei noch offen. Ich finde es zwar eigenartig das bisher diese Fehler auch teilweise beim 1. Durchlauf kam (wo die Datei noch nicht offen war) aber bis jetzt habe ich 10 Druchläufe ohne Fehler. Ich hoffe das bleibt so.

                  Euch beiden meinen herzlichen Dank für eure tolle Unterstützung!

                  LG
                  Michael

                  Comment


                  • #10
                    Ich verwende ja CopyFile und nicht CopyFileA.
                    Public Declare Function CopyFile Lib "kernel32.dll" Alias "CopyFileA"
                    Wenn ich den Declare Function Syntax nicht total falsch in Erinnerung habe ist der Alias der Name der importierten Funktion. Also hast du ursprünglich mal die CopyFileA Methode benutzt die du in deinem VB.Net Code aber über den Namen CopyFile aufgerufen hattest. Aber da der Fehler ja offensichtlich aus einer anderen Ecke kam könntest du jetzt ja einfach wieder zum File.Copy zurückkehren.

                    Comment

                    Working...
                    X