none
Aufruf von CopyFile aus WinAPI RRS feed

  • Frage

  • Um es vorab zu sagen: ja ich habe schon gegoogelt, finde allerdings immer nur dieselben Hinweise mit immer ähnlichen Code-Beispielen (als wenn der eine vom anderen plaggiiert hat).

    Ich brauche zur Datensicherung eine Möglichkeit, auch geöffnete Dateien zu kopieren. VBA deshalb, weil mein aDMINISTRATOR keine EXE duldet.

    Die Kopierfunktion aus VBA wie auch der Befehl NAME scheiden deshalb aus.

    CopyFile der WinAPI soll wie manuelles Kopieren im Explorer auch bei geöffneten Dateien funktionieren. Dummerweise läuft mein Code nicht fehlerfrei durch:

    Private Declare Function CopyFile Lib "kernel32" Alias "CopyFileA" _
    (ByVal sourc As String, dest As String, exists As Long) As Long

    Sub kopieren()
    Dim so As String, de As String
    Set fso = CreateObject("scripting.FileSystemObject")
    so = "C:\Users\kg\utf.txt"
    If fso.FileExists(so) = False Then End
    de = "C:\Users\kg\utf.cop"
    MsgBox CBool(CopyFile(so, de, 0)) & vbCrLf & Err.LastDllError
    End Sub

    err.lastdllerror gibt 123 aus. Ich gehe davon aus , dass dieser Fehlercode zu den Windows Errorcodes gehört, dann bedeutet dieser: The filename, directory name, or volume label syntax is incorrect. Ich kann hier jedoch keine falsche Pfad-Angabe erkennen, zumal auch .FileExists True ausgibt.

    Hat jemand eine Idee?

    Betriebssystem ist übrigens XP (mit Win 7 verhält sich die Sache ebenso), die Ausführung erfolgt als Standardnutzer.

    Gruß Tom

    Samstag, 16. Februar 2013 08:40

Antworten

  • Hallo Tom,

    wie unten in meiner Antwort bereits geschrieben:
    Du wertest die Rückgabe der API-Methode falsch aus.

    Und da sie keinen Mehrwert bringt (was hoffentlich klar geworden ist), verwende CopyFile vom FileSystemObject.

    Gruß Elmar

    • Als Antwort markiert tom krist Sonntag, 17. Februar 2013 12:11
    Sonntag, 17. Februar 2013 11:22
    Beantworter

Alle Antworten

  • Hallo Tom,

    Versuch es mit der System.IO.File.Copy methode.

    Win API benutzt man für solche einfachen Operationen nicht mehr.

    Gruss Ellen

    Imports System.IO
    Module Module1
    
        Sub Main()
            Try
                File.Copy("test.txt", "test2.txt")
            Catch ex As Exception
                Console.WriteLine(ex.Message)
            End Try
    
            Console.ReadKey()
    
        End Sub
    
    End Module


    (VB2008 Express, VB2010 Express, VST2008 professional) Ellens Codegallerie

    Samstag, 16. Februar 2013 13:34
  • Hallo Tom,

    Du kannst eine Datei die exklusiv geöffnet wurde, nicht kopieren... egal auf welchem Wege,
    siehe Creating and Opening Files (Windows). Dort insbesondere:

    An application also uses CreateFile to specify whether it wants to share the file for reading, writing, both, or neither. This is known as the sharing mode. An open file that is not shared (dwShareMode set to zero) cannot be opened again, either by the application that opened it or by another application, until its handle has been closed. This is also referred to as exclusive access.

    Auch in den Fällen, in denen ein paralleler Zugriff erlaubt ist, garantiert ein Kopieren keinen Erfolg. So kann z. B. eine Acccess-Datenbank, die im Mehrplatzzugriff geöffnet ist, kopiert werden. Nur können Zugriffe während des Kopierens sie verändern und das Endergebnis ist eine kaputte Kopie.

    Dies gilt unabhängig von der verwendeten Umgebung. Ein API-Aufruf ändert daran nichts.
    Zumal sowohl das FileScripting-Object wie .NET CopyFile(Ex) verwenden, denn andere gibt es gar nicht, siehe Moving and Replacing Files (Windows)

    Mehr am Rande: Die Rückgabe der API-Methoden ist bei Erfolg 0, ansonsten ungleich 0; den Fehlercode muss man mit GetLastError ermitteln.

    Gruß Elmar

    Samstag, 16. Februar 2013 16:51
    Beantworter
  • Hallo Elke, ich bin in diesem Fall auf VBA angewiesen, da die IT-Abteilung in meiner Behörde äußerst restriktiv agiert.

    Hallo Elmar, bisher habe ich programmtechnisch anscheinend nur Dateien kopiert, die nicht durch andere Prozesse geöffnet waren. Allerdings kopiere ich des öfteren manuell im WindowsExplorer eben offene Dateien, Excel-, Word- und sonst noch welche, so dass ich eigentlich völlig überrascht bin, vor solch einem Problem zu stehen.

    Wie macht das denn der Explorer? Gibts den Explorer vielleicht als COM-Komponente?

    Gruß Tom

    Samstag, 16. Februar 2013 17:44
  • Hallo Tom,

    Elke heißt keiner der Antwortenden, auch wenn beide Namen mit El beginnen :)

    Geöffnete Dateien sind an sich nicht das Problem, sondern die Art, wie die Dateien gesperrt sind. Eine exklusive Sperre lässt eben auch kein Kopieren zu.

    Schau dir dazu auch mal das hier an:

      http://msdn.microsoft.com/de-de/library/vstudio/system.io.fileshare.aspx

    Den Explorer zu automatisieren nützt dir auch nichts. Öffne bspw. mal Outlook und versuch, die geöffnete .pst Datei zu kopieren. Das geht auch im Explorer nicht (zumindest nicht bei meiner OL2010 Installation^^)


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Samstag, 16. Februar 2013 19:00
    Moderator
  • Moin in die Runde

    Ellen, entschuldige bitte meine Unachtsamkeit!

    Wir haben uns gestern von der eigentlichen Problematik entfernt. Mein aktuelles Problem war, dass der anfangs beschriebene Fehler bereits auftritt beim Versuch, eine NICHT geöffnete Datei, die im Zielordner auch noch nicht existiert, zu kopieren.

    Das war in meiner Anfrage nicht deutlich hervorgehoben, mein Fehler.

    Also wenn Ihr hier noch eine Idee hättet?

    Gruß Tom


    • Bearbeitet tom krist Sonntag, 17. Februar 2013 11:11
    Sonntag, 17. Februar 2013 11:04
  • Hallo Tom,

    wie unten in meiner Antwort bereits geschrieben:
    Du wertest die Rückgabe der API-Methode falsch aus.

    Und da sie keinen Mehrwert bringt (was hoffentlich klar geworden ist), verwende CopyFile vom FileSystemObject.

    Gruß Elmar

    • Als Antwort markiert tom krist Sonntag, 17. Februar 2013 12:11
    Sonntag, 17. Februar 2013 11:22
    Beantworter
  • Elmar Dein Link:

    Visual Basic:  Applications should call err.LastDllError instead of GetLastError.

    Werd ich dann so machen.  

    Einen schönen Sonntag Euch

    Sonntag, 17. Februar 2013 12:11