Erweiterte Datei Eigenschaften auslesen via COMmate

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
dige
Beiträge: 1239
Registriert: 08.09.2004 08:53

Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von dige »

Mit folgendem Code, kann man _alle_ Datei Attribute (u.a. Titel, Bewertung, Kommentar ...)
auslesen, die man mit Windows über Datei / Eigenschaften / Details (Win7) editieren kann.

Ich benötige aber nur bspw. den Inhalt von 'Comments' bzw. 'Kommentare'. Kann man das
direkt ansprechen? Mit TrialAndError habe ich den Wert 24 ermittelt, vermute aber das
kann sich auch ändern...

Wie würdet Ihr das machen? Geht das nur über COM? GetFileVersionInfo_() liefert leider
keine erweiterten Eigenschaften...

Code: Alles auswählen

XIncludeFile "COMatePLUS_Residents.pbi"
XIncludeFile "COMatePLUS.pbi"

Structure _EOP
  Description.s
  Value.s
EndStructure
  

NewMap EOP_Items._EOP()

Procedure GetExtendedFileProperties(file$, Map Item._EOP())
  Define.COMateObject oShell
  Define.COMateObject oFolder
  Define.COMateObject oFolderItem
  Define.COMateObject oFolderItems
  
  Define   DetailCounter
  Define.s DetailDescription, DetailValue
  
  
  oShell = COMate_CreateObject("Shell.Application")
  
  If oShell
    oFolder = oShell\GetObjectProperty("NameSpace('" + GetPathPart(file$) + "')")
    
    If oFolder
      oFolderItems = oFolder\GetObjectProperty("Items")
      
      If oFolderItems
        oFolderItem  = oFolder\GetObjectProperty("ParseName('" + GetFilePart(file$) + "')")
        
        If oFolderItem
          For DetailCounter = 0 To 512
            DetailDescription = oFolder\GetStringProperty("GetDetailsOf(" + Str(oFolderItems) + " As COMateObject, " + Str(DetailCounter) + ")")
            DetailValue       = oFolder\GetStringProperty("GetDetailsOf(" + Str(oFolderItem)  + " As COMateObject, " + Str(DetailCounter) + ")")
            
            If DetailValue
              If AddMapElement(Item(), Str(DetailCounter))
                Item()\Description = DetailDescription
                Item()\Value       = DetailValue
                Debug "Nr." + Str(DetailCounter) + " -> " + DetailDescription + ": " + DetailValue
              EndIf
            EndIf
          Next
          
          oFolderItem\Release()
          
        Else
          Debug "!oFolderItem"
          Debug COMate_GetLastErrorDescription()
        EndIf
        
        oFolderItems\Release()
        
      Else
        Debug "!oFolderItems"
        Debug COMate_GetLastErrorDescription()
      EndIf
      
      oFolder\Release()
      
    Else
      Debug "!oFolder"
      Debug COMate_GetLastErrorDescription()
    EndIf
    
    oShell\Release()
    
  Else
    Debug "!oShell"
    Debug COMate_GetLastErrorDescription()
  EndIf
EndProcedure

GetExtendedFileProperties("C:\Temp\Test.jpg", EOP_Items())
Debug EOP_Items("24")\Value ; Inhalt von Kommentare ausgeben
"Papa, ich laufe schneller - dann ist es nicht so weit."
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von Bisonte »

Ich nutze folgende Prozedur, die ich (von Droopy's Lib glaube ich) ein wenig modifiziert habe...
probier's ob's klappt. Getestet mit Win7x64 (pb51b4x32)...

Code: Alles auswählen

EnableExplicit
;
CompilerIf Defined(GetFileInfo, #PB_Procedure) = #False
CompilerIf Defined(FVI_FileVersion, #PB_Constant) = #False
  #FVI_FileVersion      = $0001
  #FVI_FileDescription  = $0002
  #FVI_LegalCopyright   = $0004
  #FVI_InternalName     = $0008
  #FVI_OriginalFilename = $0010
  #FVI_ProductName      = $0020
  #FVI_ProductVersion   = $0040
  #FVI_CompanyName      = $0080
  #FVI_LegalTrademarks  = $0100
  #FVI_SpecialBuild     = $0200
  #FVI_PrivateBuild     = $0400
  #FVI_Comments         = $0800
  #FVI_Language         = $1000
  #FVI_Email            = $1001
  #FVI_Website          = $1002
  #FVI_Special          = $1003
CompilerEndIf
;
CompilerIf #PB_Compiler_Unicode
  Prototype GetFileVersionInfoSizeW(lptstrFilename.p-unicode, lpdwHandle)
  Prototype GetFileVersionInfoW(lptstrFilename.p-unicode, dwHandle, dwLen.l, lpData.l)
  Prototype VerQueryValueW(pBlock.l, lpSubBlock.p-unicode, lplpBuffer, puLen.w)
  Prototype VerLanguageNameW(wLang.l, szLang.p-unicode, cchLang.l)
CompilerElse
  Prototype GetFileVersionInfoSizeA(lptstrFilename.p-ascii, lpdwHandle)
  Prototype GetFileVersionInfoA(lptstrFilename.p-ascii, dwHandle, dwLen.l, lpData.l)
  Prototype VerQueryValueA(pBlock.l, lpSubBlock.p-ascii, lplpBuffer, puLen.w)
  Prototype VerLanguageNameA(wLang.l, szLang.p-ascii, cchLang.l)
CompilerEndIf
;
Procedure.s GetFileInfo(FileName$, FVI_Flag)
  
  Protected TempString$ = "", TempPtr, TempBlkSize, *TempBlk, ElementName.s = ""
  Protected TempLibHandle, TempBuff, TempBuffSize, TempCPLI$, TempLangSize = 128, TempLang$ = Space(TempLangSize)
  
  If FileSize(FileName$) >= 0
    TempLibHandle = OpenLibrary(#PB_Any, "version.dll")
    If TempLibHandle
      CompilerIf #PB_Compiler_Unicode
        Protected GetFileVersionInfoSize.GetFileVersionInfoSizeW = GetFunction(TempLibHandle, "GetFileVersionInfoSizeW")
        Protected GetFileVersionInfo.GetFileVersionInfoW = GetFunction(TempLibHandle, "GetFileVersionInfoW")
        Protected VerQueryValue.VerQueryValueW = GetFunction(TempLibHandle, "VerQueryValueW")
        Protected VerLanguageName.VerLanguageNameW = GetFunction(TempLibHandle, "VerLanguageNameW")
      CompilerElse
        Protected GetFileVersionInfoSize.GetFileVersionInfoSizeA = GetFunction(TempLibHandle, "GetFileVersionInfoSizeA")
        Protected GetFileVersionInfo.GetFileVersionInfoA = GetFunction(TempLibHandle, "GetFileVersionInfoA")
        Protected VerQueryValue.VerQueryValueA = GetFunction(TempLibHandle, "VerQueryValueA")
        Protected VerLanguageName.VerLanguageNameA = GetFunction(TempLibHandle, "VerLanguageNameA")
      CompilerEndIf
      TempBlkSize = GetFileVersionInfoSize(FileName$, @TempPtr)
      If TempBlkSize > 0
        *TempBlk = AllocateMemory(TempBlkSize)
        If *TempBlk > 0
          If GetFileVersionInfo(FileName$, 0, TempBlkSize, *TempBlk)
            If VerQueryValue(*TempBlk, "\\VarFileInfo\\Translation", @TempBuff, @TempBuffSize)
              TempCPLI$ = RSet(Hex(PeekW(TempBuff)), 4, "0") + RSet(Hex(PeekW(TempBuff + 2)), 4, "0")
              VerLanguageName(PeekW(TempBuff), TempLang$, TempLangSize)
            EndIf
            
            Select FVI_Flag
              Case #FVI_FileVersion
                ElementName = "FileVersion"
              Case #FVI_FileDescription
                ElementName = "FileDescription"
              Case #FVI_LegalCopyright
                ElementName = "LegalCopyright"
              Case #FVI_InternalName
                ElementName = "InternalName"
              Case #FVI_OriginalFilename
                ElementName = "OriginalFilename"
              Case #FVI_ProductName
                ElementName = "ProductName"
              Case #FVI_ProductVersion
                ElementName = "ProductVersion"
              Case #FVI_CompanyName
                ElementName = "CompanyName"
              Case #FVI_LegalTrademarks
                ElementName = "LegalTrademarks"
              Case #FVI_SpecialBuild
                ElementName = "SpecialBuild"
              Case #FVI_PrivateBuild
                ElementName = "PrivateBuild"
              Case #FVI_Comments
                ElementName = "Comments"
              Case #FVI_Language
                ElementName = "Language"
              Case #FVI_Email
                ElementName = "Email"
              Case #FVI_Website
                ElementName = "Website"
              Case #FVI_Special
                ElementName = "Special"
            EndSelect
            
            If VerQueryValue(*TempBlk, "\\StringFileInfo\\" + TempCPLI$ + "\\" + ElementName, @TempBuff, @TempBuffSize)
              TempString$ = PeekS(TempBuff, TempBuffSize)
            EndIf
            
            If FVI_Flag = #FVI_Language
              TempString$ = TempLang$
            EndIf
          EndIf
        EndIf
        FreeMemory(*TempBlk)
      EndIf
    EndIf
    CloseLibrary(TempLibHandle)
  EndIf
  If FVI_Flag = #FVI_FileVersion
    TempString$ = ReplaceString(RemoveString(TempString$,Chr(32)),",",".")
  EndIf
  TempString$ = RemoveString(TempString$, FileName$)
  
  ProcedureReturn(TempString$)
EndProcedure
;
CompilerIf #PB_Compiler_IsMainFile
  Define File.s = "C:\windows\RtlExUpd.dll"
  Debug GetFileInfo(File,#FVI_Comments)
  Debug GetFileInfo(File,#FVI_FileDescription)
  Debug GetFileInfo(File,#FVI_FileVersion)
CompilerEndIf
;
CompilerEndIf
;
DisableExplicit
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
dige
Beiträge: 1239
Registriert: 08.09.2004 08:53

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von dige »

@Bisonte: Damit kann man nicht die erweiterten Eigenschaften abfragen.

Mir geht die Eigenschaften die bei einer Bilddatei bspw. JPEG editiert
werden können (Bewertung, Kommetar etc.)
"Papa, ich laufe schneller - dann ist es nicht so weit."
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von mk-soft »

Diese Informationen liegen nicht unter Eigenschaften, sonder inder Datei selber. Exif genannt.

http://de.wikipedia.org/wiki/Exchangeab ... ile_Format
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
dige
Beiträge: 1239
Registriert: 08.09.2004 08:53

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von dige »

Oje, da wir hier alle wunderbar aneinander vorbeireden ;-)
Ein Bild sagt mehr als 1.000 Worte:

Bild
"Papa, ich laufe schneller - dann ist es nicht so weit."
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

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von ts-soft »

Der Explorer liest die Exif Daten aus, insofern redet Ihr nicht aneinander vorbei. Um an die Daten zu kommen,
wäre es am sinnvollsten, es genauso zu tun :wink: und nicht es den Explorer tun zu lassen, um dann wieder
von diesem die Daten zu erhaschen :mrgreen: , zumal man ansonsten abhängig von der Windows Version wird.
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
dige
Beiträge: 1239
Registriert: 08.09.2004 08:53

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von dige »

Das verstehe ich jetzt nicht. Wie meinst Du das? Was, wie, wo vom Explorer erhaschen?
Momentan greife ich über COM drauf zu ...
"Papa, ich laufe schneller - dann ist es nicht so weit."
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

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von ts-soft »

Du versuchst auf das zuzugreifen, was der Explorer aus der Exif gelesen hat, statt diese direkt
auszulesen, was wesentlich sicherer sein sollte, da nicht jede Explorer Version diese Daten
liest und anzeigt.

Sinnvoller wäre es in jedem Falle, diese Daten aus der Datei zu lesen und nicht aus dem Explorer.
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
dige
Beiträge: 1239
Registriert: 08.09.2004 08:53

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von dige »

Hmm, Du meinst also, dass sind gar keine speziellen Windows Meta Infos, sondern Exif bzw. IPTC Tags?
Das Feld Bewertung (1..5 Sterne) kann ich bspw. mit Irfanview nicht auslesen...
"Papa, ich laufe schneller - dann ist es nicht so weit."
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

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Beitrag von ts-soft »

Das sind alles Exif Daten, bis auf der letzte Abschnitt (Datei), dort sind die Dateiattribute Deines PCs enthalten, die Du aber
auch so ermitteln kannst. Der Explorer holt sich keine Bewertungen über das Internet :mrgreen: , obwohl man es MS
zutrauen würde.
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