CAB-Dateien extrahieren (PB4)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

CAB-Dateien extrahieren (PB4)

Beitrag von ts-soft »

Code: Alles auswählen

Structure FILE_IN_CABINET_INFO
  NameInCabinet.l
  FileSize.l
  Win32Error.l
  DosDate.w
  DosTime.w
  DosAttribs.w
  FullTargetName.s{260}
EndStructure

Procedure PSP_FileCallback(Context.l, Notification.l, Param1.l, Param2.l)
  Protected *CAB_INFO.FILE_IN_CABINET_INFO
  Protected Path.s
  If Notification = $11
    *CAB_INFO = Param1
    Path = PeekS(Context)
    Path + PeekS(*CAB_INFO\NameInCabinet)
    MakeSureDirectoryPathExists_(GetPathPart(Path))
    *CAB_INFO\FullTargetName = Path
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure CAB_Extract(ArchivName.s, ExtractPath.s)
  If Right(ExtractPath, 1) <> "\" : ExtractPath + "\" : EndIf
  ProcedureReturn SetupIterateCabinet_(@ArchivName, 0, @PSP_FileCallback(), @ExtractPath)
EndProcedure

ArchivName.s = "MyCab.cab" ; Achtung: absoluten Pfad angeben
ExtractPath.s = "C:\windows\temp"

If CAB_Extract(ArchivName, ExtractPath)
  Debug "Alles okay my Friend"
Else
  Debug "ERROR, das ist nicht gut"
EndIf
Vielleicht kanns der eine oder andere mal gebrauchen
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ABBKlaus
Beiträge: 61
Registriert: 15.03.2006 22:09
Wohnort: Ratingen
Kontaktdaten:

Beitrag von ABBKlaus »

Hi TS-Soft,

habs gleich mal ausprobiert und deine Version verbessert :twisted:

Code: Alles auswählen

#SPFILENOTIFY_STARTCOPY=$11
#FILEOP_ABORT=0
#FILEOP_DOIT=1
#FILEOP_SKIP=2

Structure FILE_IN_CABINET_INFO 
  NameInCabinet.l 
  FileSize.l 
  Win32Error.l 
  DosDate.w 
  DosTime.w 
  DosAttribs.w 
  FullTargetName.s{260} 
EndStructure 

Procedure PSP_FileCallback(Context.l, Notification.l, Param1.l, Param2.l)
;http://msdn.microsoft.com/library/en-us/setupapi/setup/psp_file_callback.asp
  Protected *CAB_INFO.FILE_IN_CABINET_INFO 
  Protected Path.s 
  If Notification = #SPFILENOTIFY_STARTCOPY
  ;http://msdn.microsoft.com/library/en-us/setupapi/setup/spfilenotify_startcopy.asp
    *CAB_INFO = Param1 
    Path = PeekS(Context) 
    Path + PeekS(*CAB_INFO\NameInCabinet) 
    If MakeSureDirectoryPathExists_(GetPathPart(Path))
      Debug Path
      *CAB_INFO\FullTargetName = Path 
      ProcedureReturn #FILEOP_DOIT
    Else
      ProcedureReturn #FILEOP_SKIP
    EndIf
  EndIf 
  ProcedureReturn 0
EndProcedure 

Procedure CAB_Extract(ArchivName.s, ExtractPath.s) 
  If Right(ExtractPath, 1) <> "\" : ExtractPath + "\" : EndIf 
  ProcedureReturn SetupIterateCabinet_(@ArchivName, 0, @PSP_FileCallback(), @ExtractPath) 
EndProcedure 

ArchivName.s = "C:\Data1.cab" ; Achtung: absoluten Pfad angeben 
ExtractPath.s = "D:\Backup\in" 

If CAB_Extract(ArchivName, ExtractPath) 
  Debug "Alles okay my Friend" 
Else 
  Debug "ERROR, das ist nicht gut" 
EndIf
PureBasicPower TailBite Printer_Lib / PDFBarcode / PrintBarcode / ExcelWriter
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

ABBKlaus hat geschrieben:Hi TS-Soft,

habs gleich mal ausprobiert und deine Version verbessert :twisted:
Da haste aber was verkehrt verstanden :mrgreen:
#FILEOP_SKIP=2 dient dafür, z.B. eine Vorschau zu erstellen, ohne zu
entpacken. Hab ich absichtlich nicht implementiert, weil dann müßten noch
die Werte in eine Linklist übertragen werden, o. ä.

Wenn es so aufwendig sein soll, hätte ich gleich die Cabinet-API verwandt
und Packroutinen beigelegt :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ABBKlaus
Beiträge: 61
Registriert: 15.03.2006 22:09
Wohnort: Ratingen
Kontaktdaten:

Beitrag von ABBKlaus »

wie gesagt hab nur deinen code verbessert weil
MakeSureDirectoryPathExists_(GetPathPart(Path))
liefert immerhin ein Ergebnis zurück (#True/#False) und das habe Ich umgesetzt wie es sich gehört.
Und das überspringen einer Datei ist immerhin keine schlechte Alternative wenn ein Verzeichnis nicht existiert also warum nicht <)
SPFILENOTIFY_STARTCOPY
The callback routine should return one of the following values.
FILEOP_ABORT Abort the queue commit process.
FILEOP_DOIT Perform the file copy operation.
FILEOP_SKIP Skip the current copy operation.
PureBasicPower TailBite Printer_Lib / PDFBarcode / PrintBarcode / ExcelWriter
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Wenn das Verzeichnis nicht existiert oder schreibgeschützt ist, bricht die API
sowieso ab, aber schaden kann es nicht.

Man könnte jetzt den Context Parameter, der ja für Benutzerdefinierte
Sachen da ist, erweitern und die Adresse einer Structure übergeben, die
dann Parameter für Vorschau oder Extrahieren enthält, sowie die Adresse
einer Linkliste, die dann gefüllt wird, mit Pfaden, Dateinamen und Attributen.

So könnte man das CAB-Archiv durchsuchen, ohne zu entpacken.

Das wäre dann eine sinnvolle Erweiterung, zu der ich zu Faul war /:->

Das Beispiel ist auch mehr für Einsteiger gedacht.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ABBKlaus
Beiträge: 61
Registriert: 15.03.2006 22:09
Wohnort: Ratingen
Kontaktdaten:

Beitrag von ABBKlaus »

So hab mal ein wenig mit Google gesucht und ein MS-Beispiel gefunden /:->
PS : in meinem code war auch ein fehler :oops:
#SPFILENOTIFY_STARTCOPY <> $11

Code: Alles auswählen

#SPFILENOTIFY_FILEINCABINET  = $11
#SPFILENOTIFY_NEEDNEWCABINET = $12
#SPFILENOTIFY_FILEEXTRACTED  = $13

#FILEOP_ABORT = 0
#FILEOP_DOIT  = 1
#FILEOP_SKIP  = 2

Structure FILE_IN_CABINET_INFO 
  NameInCabinet.l 
  FileSize.l 
  Win32Error.l 
  DosDate.w 
  DosTime.w 
  DosAttribs.w 
  FullTargetName.s{260} 
EndStructure 

Structure FILEPATHS
  Target.l
  Source.l
  Win32Error.l
  Flags.l
EndStructure

Procedure PSP_FileCallback(Context.l, Notification.l, Param1.l, Param2.l)
;http://msdn.microsoft.com/library/en-us/setupapi/setup/psp_file_callback.asp
;Beispielcode : http://support.microsoft.com/kb/q189085/
  Protected *CAB_INFO.FILE_IN_CABINET_INFO 
  Protected *FILE_INFO.FILEPATHS
  Protected Path.s
  
  retval.l=#NO_ERROR
  
  Select Notification
    Case #SPFILENOTIFY_FILEINCABINET
      *CAB_INFO = Param1 
      Path = PeekS(Context) 
      Path + PeekS(*CAB_INFO\NameInCabinet) 
      If MakeSureDirectoryPathExists_(GetPathPart(Path))
        *CAB_INFO\FullTargetName = Path 
        retval = #FILEOP_DOIT
      Else
        retval = #FILEOP_SKIP
      EndIf
    Case #SPFILENOTIFY_FILEEXTRACTED
      *FILE_INFO = Param1
      Debug "Extracted "+PeekS(*FILE_INFO\Target)
      retval = #NO_ERROR
    Case #SPFILENOTIFY_NEEDNEWCABINET ; unexpected
      retval = #NO_ERROR
  EndSelect
  
  ProcedureReturn retval
EndProcedure 
PureBasicPower TailBite Printer_Lib / PDFBarcode / PrintBarcode / ExcelWriter
Benutzeravatar
DROOPY
Beiträge: 52
Registriert: 05.03.2005 00:20

Beitrag von DROOPY »

Hello, this code can be converted to pb 3.94 ?
Regards
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

DROOPY hat geschrieben:Hello, this code can be converted to pb 3.94 ?
Regards
I think, there is no convert required :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
DROOPY
Beiträge: 52
Registriert: 05.03.2005 00:20

Beitrag von DROOPY »

I got an error in the structure line

Code: Alles auswählen

FullTargetName.s{260}
Replaced by

Code: Alles auswählen

FullTargetName.s
And the code doesn't works :cry:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

@Droopy:
Change the structure like this:

Code: Alles auswählen

  FullTargetName.b[260]
And something to:

Code: Alles auswählen

PokeS(*CAB_INFO\FullTargetName[0],Path)
Not tested
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten