Seite 1 von 2

Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 21.01.2013 22:13
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

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 22.01.2013 07:43
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

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 22.01.2013 15:16
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.)

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 22.01.2013 19:01
von mk-soft
Diese Informationen liegen nicht unter Eigenschaften, sonder inder Datei selber. Exif genannt.

http://de.wikipedia.org/wiki/Exchangeab ... ile_Format

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 22.01.2013 20:49
von dige
Oje, da wir hier alle wunderbar aneinander vorbeireden ;-)
Ein Bild sagt mehr als 1.000 Worte:

Bild

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 22.01.2013 21:14
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.

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 22.01.2013 21:28
von dige
Das verstehe ich jetzt nicht. Wie meinst Du das? Was, wie, wo vom Explorer erhaschen?
Momentan greife ich über COM drauf zu ...

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 22.01.2013 22:39
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.

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 22.01.2013 23:22
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...

Re: Erweiterte Datei Eigenschaften auslesen via COMmate

Verfasst: 23.01.2013 05:07
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.