Seite 1 von 1
OpenSharedFile(...)
Verfasst: 08.11.2011 16:43
von mk-soft
Habe mal wieder den Fall das ich eine Datei einlesen muss wo ein anderes Programm die Datei noch zum schreiben geöffnet hat.
Da Purebasic immer die Datei für andere den Zugriffe sperrt habe ich nun eine (schmutzige) Methode gefunden diese zu umgehen.
Hoffe das Purebasic bald Dateien auch Shared öffnen kann.
Bugfix: Ergebnis von CreateFile(...)
Code: Alles auswählen
#FILE_SHARE_DELETE = 4 ; NT4
#FILE_SHARE_READWRITE = #FILE_SHARE_READ | #FILE_SHARE_WRITE
Procedure OpenSharedFile(ID, FileName.s, DesiredAccess = #GENERIC_READ, ShareMode = #FILE_SHARE_READWRITE, TempFile.s = "temp.tmp")
Protected hFile, addr, result
hFile = CreateFile_(FileName, DesiredAccess, ShareMode, 0, #OPEN_ALWAYS, #FILE_ATTRIBUTE_NORMAL, 0)
If hFile = #INVALID_HANDLE_VALUE
result = 0
Else
result = OpenFile(ID, TempFile)
If result
If ID = #PB_Any
addr = IsFile(result)
CloseHandle_(FileID(result))
Else
addr = IsFile(ID)
CloseHandle_(FileID(ID))
EndIf
PokeI(addr, hFile)
Else
CloseHandle_(hFile)
ProcedureReturn 0
EndIf
EndIf
ProcedureReturn result
EndProcedure
Alles Gute
Michael
Re: OpenSharedFile(...)
Verfasst: 09.11.2011 10:59
von Kiffi
Hallo Michael,
erstmal Danke für den Code

Das ermöglicht mir vielleicht, ein
liegengelassenes Projekt weiterzuführen. Ziel ist es, eine gesperrte
Datei zu kopieren, um dann damit weiterarbeiten zu können.
Problem: Öffne ich diese Datei mit OpenSharedFile() und versuche
die Dateigröße zu ermitteln, bekomme ich einen falschen (viel zu
großen) Wert.
Code: Alles auswählen
If OpenSharedFile(0, MeineDatei)
Debug Lof(0) ; liefert 4294967295 anstelle von 49942528 Bytes
CloseFile(0)
EndIf
Hast Du evtl. eine Idee, woran es liegen könnte?
Grüße ... Kiffi
Re: OpenSharedFile(...)
Verfasst: 09.11.2011 12:33
von Bisonte
Reine Spekulation:
Evt. liegt es an CreateFile_().
Laut MSDN buffert Windows Daten, für die evt schon Platz freigehalten wird.
Und wenn ich das englisch auf
http://msdn.microsoft.com/en-us/library ... 85%29.aspx richtig gedeutet habe,
könnte man das evt. steuern, wenn man bei dwFlagsAndAttributes die Konstante FILE_FLAG_NO_BUFFERING nutzt.
also anstelle von :
Code: Alles auswählen
hFile = CreateFile_(FileName, DesiredAccess, ShareMode, 0, #OPEN_ALWAYS, #FILE_ATTRIBUTE_NORMAL, 0)
mal
Code: Alles auswählen
hFile = CreateFile_(FileName, DesiredAccess, ShareMode, 0, #OPEN_ALWAYS, #FILE_FLAG_NO_BUFFERING, 0)
probieren.
Aber wie gesagt, nur reiner Spekulatius...
Re: OpenSharedFile(...)
Verfasst: 09.11.2011 19:05
von mk-soft
Habe es mal getestet...
OpenFile und OpenSharedFile liefert bei mir immer die richtige Grösse.
Habe es auch mit "Eigendschaften von Datei" verglichen.
XP-Pro SP3
FF
P.S. Es kommt auch darauf an wer die Datei als erstes geöffnet hat.
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
PB4.60
Re: OpenSharedFile(...)
Verfasst: 09.11.2011 21:24
von Kiffi
Hallo Michael,
mk-soft hat geschrieben:Habe es mal getestet...
hast Du Skype? Wenn ja, dann versuch mal die Datei
"main.db" zu öffnen (bzw. die Dateigröße zu ermitteln).
Liegt bei mir (Win 7) unter:
C:\Users\[MeinBenutzername]\AppData\Roaming\Skype\[MeinSkypeName]\main.db
@Bisonte: Danke für den Tipp. Brachte allerdings nicht
den erhofften Erfolg.
Grüße ... Kiffi
// Edit: FileSize() funktioniert! Dafür schlägt das nachfolgende ReadData()
jetzt fehl.
Code: Alles auswählen
If OpenSharedFile(0, File)
SizeOfFile = FileSize(File)
Debug SizeOfFile ; <- Korrekt
*mem = AllocateMemory(SizeOfFile)
Debug ReadData(0, *mem, SizeOfFile) ; <- 0 :-(
CloseFile(0)
EndIf
Re: OpenSharedFile(...)
Verfasst: 10.11.2011 08:30
von mk-soft
Hm....
ich habe hier Windows XP Pro Sp3 und PB4.51(x86) und PB4.60(x86)
Mit Windows 7 konnte ich es noch nicht testen. Glaube allerdings nicht das es daran liegt.
Habe es auch noch nicht mit X64 getestet da ich nicht zu Hause bin.
*** Bugfix ***
Code: Alles auswählen
#FILE_SHARE_DELETE = 4 ; NT4
#FILE_SHARE_READWRITE = #FILE_SHARE_READ | #FILE_SHARE_WRITE
Procedure OpenSharedFile(ID, FileName.s, DesiredAccess = #GENERIC_READ, ShareMode = #FILE_SHARE_READWRITE, TempFile.s = "temp.tmp")
Protected hFile, addr, result
hFile = CreateFile_(FileName, DesiredAccess, ShareMode, 0, #OPEN_ALWAYS, #FILE_ATTRIBUTE_NORMAL, 0)
If hFile = #INVALID_HANDLE_VALUE
result = 0
Else
result = OpenFile(ID, TempFile)
If result
If ID = #PB_Any
addr = IsFile(result)
CloseHandle_(FileID(result))
Else
addr = IsFile(ID)
CloseHandle_(FileID(ID))
EndIf
PokeI(addr, hFile)
Else
CloseHandle_(hFile)
ProcedureReturn 0
EndIf
EndIf
ProcedureReturn result
EndProcedure
; *************************************************************************************************
datei.s = OpenFileRequester("Open","","",0)
If OpenSharedFile(0,datei)
size = Lof(0)
Debug size
If size < 512 * 1024
*mem = AllocateMemory(size)
ReadData(0,*mem,size)
For i = 0 To 32
temp.s + RSet(Hex(PeekB(*mem+i),#PB_Byte),2,"0")
Next
Debug temp
EndIf
CloseFile(0)
EndIf
P.S. Nimm mal #FILE_SHARE_DELETE raus. Weis nicht wie Win7 darauf reagiert.
Re: OpenSharedFile(...)
Verfasst: 10.11.2011 11:40
von Kiffi
mk-soft hat geschrieben:P.S. Nimm mal #FILE_SHARE_DELETE raus. Weis nicht wie Win7 darauf reagiert.
leider keine Besserung. Soweit ich das verstanden habe,
kann die Datei unter Vista / Win 7 nur mit dem
"Volume Shadow Service" kopiert werden.
http://msdn.microsoft.com/en-us/library ... s.85).aspx
Das zu implementieren ist mir aber zu aufwändig. Dann bleibt
das Tool halt noch ein wenig länger in der TODO-Schublade
liegen
Nochmals Danke für Deine Hilfe & Grüße ... Kiffi
Re: OpenSharedFile(...)
Verfasst: 10.11.2011 12:55
von mk-soft
Ich schau mir das mal am Wochenende mit Win7 (X64) an

Re: OpenSharedFile(...)
Verfasst: 10.11.2011 13:00
von Kiffi
mk-soft hat geschrieben:Ich schau mir das mal am Wochenende mit Win7 (X64) an

mach Dir mal keinen Stress! Wie gesagt: Wenn's bei mir
funktionieren würde, wäre es nett. Aber so ist es auch
kein Beinbruch. Habe sowieso noch andere Sachen in
der Pipeline...
Grüße ... Kiffi
Re: OpenSharedFile(...)
Verfasst: 11.11.2011 18:05
von mk-soft
Hallo Kiffi,
Konnte durch ein Zufall dein Ergebnis (4294967295) reproduzieren.
Bin da rauf gekommen als ich bei meinen Test den OpenFileRequester abgebrochen habe.
CreateFile liefert nicht NULL sondern -1 (INVALID_HANDLE_VALUE) zurück wenn die Datei nicht geöffnet werden kann.
Jetzt nur mal schauen warum die Datei nicht geöffnet werden kann.
Es kann sein da die Datei von dem anderen Programm nicht mit FILE_SHARE_READ geöffnet wurde.
Alles Gute
Michael
P.S. Mit Win7 Pro X64 (PB v4.51 und v4.60, X86 und X64) ausprobiert