Worauf muss ich achten wenn ich aus folgendem Code ein modul erstellen möchte
Private Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" \_
(ByVal lpFileName As String, ByVal dwDesiredAccess As Long, \_
ByVal dwShareMode As Long, lpSecurityAttributes As Any, \_
ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, \_
ByVal hTemplateFile As Long) As Long
Private Declare Function GetFileTime Lib "kernel32" (ByVal hFile As Long, \_
lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As \_
FILETIME) As Long
Private Declare Function FileTimeToLocalFileTime Lib "kernel32" (lpFileTime As \_
FILETIME, lpLocalFileTime As FILETIME) As Long
Private Declare Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As \_
FILETIME, lpSystemTime As SYSTEMTIME) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) \_
As Long
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
' CreateFile dwDesiredAccess Konstanten
Private Const GENERIC\_READ = &H80000000 ' Nur Lesen
Private Const GENERIC\_WRITE = &H40000000 ' Nur Schreiben
' CreateFile dwShareMode Konstanten
Private Const FILE\_SHARE\_READ = &H1
Private Const FILE\_SHARE\_WRITE = &H2
' CreateFile dwCreationDisposition Konstanten
' ===========================================
' Erstellt eine neue Datei und überschreibt eine bereits vorhandene
Private Const CREATE\_ALWAYS = 2
' Erstellt eine neue Datei nur, wenn sie noch nicht existiert
Private Const CREATE\_NEW = 1
' Öffnet eine bereits vorhande Datei bzw. erstellt diese,
' wenn sie noch nicht existiert
Private Const OPEN\_ALWAYS = 4
' Öffnet eine bereits vorhandene Datei
Private Const OPEN\_EXISTING = 3
' Öffnet eine bereits vorhandene Datei und löscht den Inhalt
Private Const TRUNCATE\_EXISTING = 5
' CreateFile dwFlagsAndAttributes
' ===============================
Private Const FILE\_ATTRIBUTE\_ARCHIVE = &H20 ' Archiv
Private Const FILE\_ATTRIBUTE\_HIDDEN = &H2 ' Versteckt
Private Const FILE\_ATTRIBUTE\_NORMAL = &H80 ' Normal
Private Const FILE\_ATTRIBUTE\_READONLY = &H1 ' Schreibgeschützt
Private Const FILE\_ATTRIBUTE\_SYSTEM = &H4 ' Systemdatei
' Datei wird beim Schließen gelöscht
Private Const FILE\_FLAG\_DELETE\_ON\_CLOSE = &H4000000
' Es wird kein Puffer/Cache benutzt
Private Const FILE\_FLAG\_NO\_BUFFERING = &H20000000
' Erlaubt gleichzeitiges Lesen und Schreiben
' (nicht bei Windows 95, 98, CE)
Private Const FILE\_FLAG\_OVERLAPPED = &H40000000
' Erlaubt Case-Sensitive Dateinamen
Private Const FILE\_FLAG\_POSIX\_SEMANTICS = &H1000000
' Richtet den Puffer für einen Random-Access Zugriff aus
Private Const FILE\_FLAG\_RANDOM\_ACCESS = &H10000000
' Richtet den Puffer für einen sequentuellen Zugriff aus
Private Const FILE\_FLAG\_SEQUENTIAL\_SCAN = &H8000000
' Nutzt keinen Platten-Cache, sondern schreibt direkt in die Datei
Private Const FILE\_FLAG\_WRITE\_THROUGH = &H80000000
' Datumsinformationen einer Datei ermitteln (Erstellungsdatum)
Private Sub Command1\_Click()
Dim hFile As Long
Dim Retval As Long
Dim CTime As FILETIME
Dim STime As SYSTEMTIME
Dim Dummi As FILETIME
' Datei öffnen (nicht Erstellen, falls nicht vorhanden)
hFile = CreateFile("c:\autoexec.bat", GENERIC\_READ, FILE\_SHARE\_READ, \_
ByVal 0&, OPEN\_EXISTING, FILE\_ATTRIBUTE\_ARCHIVE, 0&:wink:
If hFile = -1 Then
MsgBox "Die Datei wurde nicht gefunden", vbOKOnly + vbInformation, \_
"Fehler"
Exit Sub
End If
' Erstellungsdatum ermitteln
GetFileTime hFile, CTime, Dummi, Dummi
' Konvertieren nach "Lokale Zeitzone"
FileTimeToLocalFileTime CTime, CTime
' In Systemzeit umwandeln
FileTimeToSystemTime CTime, STime
' Ausgabe des Datums
MsgBox "Die datei wurde erstellt am: " & STime.wDay & "." & \_
STime.wMonth & "." & STime.wYear, vbOKOnly + vbInformation, \_
"Erstellt am"
' Resourcen wieder frei geben
CloseHandle hFile
End Sub
Der Code ist offensichtlich für ein Formularmodul gedacht - du musst halt die entsprechende Schaltfläche bereitstellen usw.
Ansonsten ist die Frage wohl eher, was du erreichen willst (Und womit? Was soll das werden? Ein VB6-Programm? Ein Access-VBA-Modul?) - wenn du die Prozeduren allgemein zugänglich machen willst, musst du sie Public deklarieren.
Warum nimmst du nicht einfach das FileSystemObject der Scripting Runtime? Das ist doch weitaus benutzerfreundlicher als derartige API-Aufrufe!
Moin,
ich habe das Problem (ein Thema tiefer im FOrum) das bei vereinzelten Files das Änderungsdatum falsch ausgegeben wird. Also möchte ich bei diesen datein das erstellungsdatum erfragen.
Aber ich würde die abfrage nur als Modul in mein Projekt aufnehmen.
Meinst du wenn ich einen Ordner rekursiv durchsuche mit API und die datumsabfrage mit FSO das ich die suche dadurch ausbremse ? hier gilt wohl probieren
Am saubersten ist es, wenn man Datumsangaben (wenn man sie überhaupt als String handhaben will) im ISO-Format (yyyy-mm-dd) anlegt. Mit allem anderen handelt man sich Einstellungsabhängigkeiten ein.
Hmmm… dann hast du wohl 60 x so viele Programme installiert wie ich - bei mir dauert das rekursive Durchlaufen von „C:\Programme“ mit dem FSO eineinhalb Minuten… Zum Gegentest mit der API-Lösung bin ich jetzt zu müde (Ich glaube gerne, dass sie schneller ist, aber sooo viel schneller!? Da glaube ich dann eher, dass du mit dem FSO Mist gemacht hast (z.B. beim rekursiven Abstieg das FSO immer wieder neu instantiiert hast…)
Hmmm… dann hast du wohl 60 x so viele Programme installiert
wie ich -
*gg* möglich, daß ich ein paar Dateien mehr auf der Platte habe als Du, aber eher unwahrscheinlich.
bei mir dauert das rekursive Durchlaufen von
„C:\Programme“ mit dem FSO eineinhalb Minuten… Zum Gegentest
mit der API-Lösung bin ich jetzt zu müde (Ich glaube gerne,
dass sie schneller ist, aber sooo viel schneller!? Da glaube
ich dann eher, dass du mit dem FSO Mist gemacht hast (z.B.
beim rekursiven Abstieg das FSO immer wieder neu instantiiert
hast…)
Möglich, daß mein Code nicht optimal ist …
Option Explicit
Dim MyFSO As Object
Sub ScanDir(ScanPfad)
Dim PathObject As Object
Dim FileObject As Object
Dim FileNow As Object
Dim SubFolders As Object
Dim SubFoldersNow As Object
Set PathObject = MyFSO.getFolder(ScanPfad)
Set FileObject = PathObject.Files
For Each FileNow In FileObject
List1.AddItem FileNow
Next
Set SubFolders = PathObject.SubFolders
For Each SubFoldersNow In SubFolders
List1.AddItem SubFoldersNow
ScanDir (SubFoldersNow.ParentFolder + "\" + SubFoldersNow.Name)
Next
End Sub
Private Sub Command1\_Click()
Set MyFSO = CreateObject("Scripting.FileSystemObject")
List1.Visible = False
ScanDir ("C:\Programme")
List1.Visible = True
End Sub
Nein, einen Fehler sehe ich nicht - im Wesentlichen habe ich es genau so gemacht (allerdings um den Listenfeld-Kram bereinigt: 2 Minuten für 65036 Dateien in 5288 Verzeichnissen…) Ich neige eher dazu, zu vermuten, dass du Opfer eines Äpfel-mit-Birnen-Vergleichs bist. Hast du im Fall der API-Funktion auch das Listenfeld jeweils dateiweise aktualisiert?
Hast du im Fall
der API-Funktion auch das Listenfeld jeweils dateiweise
aktualisiert?
die Zeile eingefügt, wie im Beispiel mit FSO, ja. Die Liste ist aber unsichtbar, aktualisiert wird sie erst am Schluß, sonst bremst die Liste.
Ich hatte beide Prozeduren zusammen in einem Programm, habe die Liste jeweils vorher gelöscht und mal per FSO, mal per API mit den selben Daten gefüllt und die benötigte Zeit anzeigen lassen. Faktor 20!
Verstehe ich das richtig, daß FSO - (’ Scripting File System Object’) als Script abgearbeitet wird, nicht wie der Rest des VB-Programms in Maschinencode compiliert wird? Dafür, daß das durch einen Interpreter muß, ist es dann schon wieder richtig schnell.
Das geht ohne FSO auch noch mit Dir$, ist aber auch nicht schneller. FSO wird wohl Dir$ verwenden, der Weg über die API mit ‚FindNextFile‘, den ich bei AVB gefunden habe ist wirklich so viel schneller. Joe will damit ganze Fileserver synchronisieren, dabei spielt die Geschwindigkeit dann schon eine erhebliche Rolle.
(Das Programm habe ich aber nicht gesichert, im Moment habe ich wenig Lust, das noch mal zusammen zu kopieren … )
Nein, „Scripting“ heisst in diesem Zusammenhang, dass man damit Scripts schreiben kann - das Teil ist halt eine DLL und wird in einer systemnahen Sprache geschrieben sein (und selber natürlich auch API-Calls und diese nicht über den Umweg von VB-Konstrukten verwenden). Aber ich bin nicht MS und kenne die Dinge auch nur von der Oberfläche her…