![]() |
Re: Erweiterte Dateiinformationen schreiben
Hi Mathias,
ich hatte ja noch nicht in Luckies Implementierung reingeschaut, aber ich persönlich würde das am ehesten über ADS machen. Die Native API erlaubt dir genau dies. Ich habe 2 Exemplare der Native API Reference, wenn du willst, kann ich dir eine vorbeibringen. Ich würde dir natürlich bei der Ausarbeitung helfen. Auch wenn mich ADS nicht so primär interessieren, kann eine Umsetzung dahingehend schon interessant sein :) ... wie zB auch meine Hardlink-Geschichte. |
Re: Erweiterte Dateiinformationen schreiben
Liste der Anhänge anzeigen (Anzahl: 1)
So, noch ein Nachtrag meinerseits:
Zitat:
Zitat:
Delphi-Quellcode:
Die bearbeitete Unit (storage.pas) hänge ich ran, damit ihr das testen könnt. Die Grundlage ist zwar von Luckie, aber die Bezeichner für die Konstanten usw. stammen jetzt aus dem PSDK; aus der Datei "PropIdl.h" um genau zu sein)
procedure TForm1.Button1Click(Sender: TObject);
var mal : TMultipleArrayList; begin SetLength(mal,3); mal[0].pidInfoType := PIDSI_AUTHOR; mal[0].pidInfoStr := 'Ich'; mal[1].pidInfoType := PIDSI_COMMENTS; mal[1].pidInfoStr := 'Tralala'; mal[2].pidInfoType := PIDSI_TITLE; mal[2].pidInfoStr := 'Mein Titel'; SetMultipleFileSummaryInfo('MeineDatei.txt', FMTID_SummaryInformation, mal); SetLength(mal,0); end; Zitat:
Delphi-Quellcode:
Dagegen gehört die Quelle (PIDMSI_SOURCE) zur Kategorie FMTID_MediaFileSummaryInformation, und die GUID war nicht einfach zu finden. *schwitz* Aber ich habe sie ja doch entdeckt (s. Unit im Anhang). ;) Und hier das Beispiel
SetFileSummaryInfo('MeineDatei.txt',
FMTID_SummaryInformation, PIDSI_REVNUMBER, '3.0');
Delphi-Quellcode:
btw: Die Funktionen sind bisher nur darauf ausgelegt, Strings zu lesen und zu schreiben. Einige der Konstanten besitzen aber ein anderes Format. In der Unit steht es dahinter (steht nichts da, hat die Konstanten den gleichen Typ wie die in der Zeile zuvor, usw.). Ihr müsstet die Funktionen also umschreiben um solche Werte auslesen zu können. Ich wollt´s nur gesagt haben. ;)
SetFileSummaryInfo('MeineDatei.txt',
FMTID_MediaFileSummaryInformation, PIDMSI_SOURCE, 'www.delphipraxis.net'); |
Re: Erweiterte Dateiinformationen schreiben
Hey, da hat sich ja einer reingedrängelt.
Zitat:
|
Re: Erweiterte Dateiinformationen schreiben
Liste der Anhänge anzeigen (Anzahl: 1)
So, ich habe die Unit noch mal poliert. Es klappt jetzt auch unter Windows 9x. Eben getestet mit einer DOC-Datei. Natürlich macht es IMHO nur mit solchen Dateien Sinn, die auch über die entsprechenden Infos verfügen. Aber evtl. klappt es jetzt auch mit den "normalen" Dateiinfos unter NT4. Ich hänge die neue Unit mal ran.
@Assarbad: Ihr Auftritt, mein Herr! :) |
Re: Erweiterte Dateiinformationen schreiben
Hallo!
Ich hätte mal noch eine Frage zu den erweiterten Dateiinformationen. Wie bekomme ich mit Hilfe der von MathiasSimmack bereits angehängten Unit die "$DATA"-Streams (also den Teil wo z.B. auch die "Zone Identfier" hinterlegt ist) ausgelesen? Gruss Dieter |
Re: Erweiterte Dateiinformationen schreiben
Hello,
For the community. I was just fighting to read the filesummaryinfo and nothing seems to work, so I puzzled with some sources from this site and the main source from Serge Perevoznyk (that you can find on 10.000 sites via Google) Here is the source that will work on WindowsXP and Delphi >= 5.
Code:
Use the function in this way:
unit UFileSummaryInfo;
interface uses Windows, ActiveX, ComObj; const FmtID_SummaryInformation: TGUID = '{F29F85E0-4FF9-1068-AB91-08002B27B3D9}'; FMTID_DocSummaryInformation : TGUID = '{D5CDD502-2E9C-101B-9397-08002B2CF9AE}'; FMTID_UserDefinedProperties : TGUID = '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'; IID_IPropertySetStorage : TGUID = '{0000013A-0000-0000-C000-000000000046}'; STGFMT_FILE = 3; //Indicates that the file must not be a compound file. //This element is only valid when using the StgCreateStorageEx //or StgOpenStorageEx functions to access the NTFS file system //implementation of the IPropertySetStorage interface. //Therefore, these functions return an error if the riid //parameter does not specify the IPropertySetStorage interface, //or if the specified file is not located on an NTFS file system //volume. STGFMT_ANY = 4; //Indicates that the system will determine the file type and //use the appropriate structured storage or property set //implementation. //This value cannot be used with the StgCreateStorageEx function. //I've changed the numbers of the original constants to get the right PID... //e.g. I decreased all const with 2... // Summary Information PID_TITLE = 0; //2; PID_SUBJECT = 1; PID_AUTHOR = 2; PID_KEYWORDS = 3; PID_COMMENTS = 4; PID_TEMPLATE = 5; PID_LASTAUTHOR = 6; PID_REVNUMBER = 7; PID_EDITTIME = 8; PID_LASTPRINTED = 9; PID_CREATE_DTM = 10; PID_LASTSAVE_DTM = 11; PID_PAGECOUNT = 12; PID_WORDCOUNT = 13; PID_CHARCOUNT = 14; PID_THUMBNAIL = 15; PID_APPNAME = 16; PID_SECURITY = 17; // Document Summary Information PID_CATEGORY = 2; PID_PRESFORMAT = 3; PID_BYTECOUNT = 4; PID_LINECOUNT = 5; PID_PARCOUNT = 6; PID_SLIDECOUNT = 7; PID_NOTECOUNT = 8; PID_HIDDENCOUNT = 9; PID_MMCLIPCOUNT = 10; PID_SCALE = 11; PID_HEADINGPAIR = 12; PID_DOCPARTS = 13; PID_MANAGER = 14; PID_COMPANY = 15; PID_LINKSDIRTY = 16; PID_CHARCOUNT2 = 17; function IsNTFS(AFileName : string) : boolean; function GetFileSummaryInfo(const FileName: WideString; GUID_SummaryType: TGUID; PID_InfoType: cardinal): WideString; function StgOpenStorageEx ( const pwcsName : POleStr; //Pointer to the path of the //file containing storage object grfMode : LongInt; //Specifies the access mode for the object stgfmt : DWORD; //Specifies the storage file format grfAttrs : DWORD; //Reserved; must be zero pStgOptions : Pointer; //Address of STGOPTIONS pointer reserved2 : Pointer; //Reserved; must be zero riid : PGUID; //Specifies the GUID of the interface pointer out stgOpen : //Address of an interface pointer IStorage ) : HResult; stdcall; external 'ole32.dll'; implementation uses SysUtils; function PropertyPIDToCaption(const ePID: Cardinal): string; begin case ePID of PID_TITLE: Result := 'Title'; PID_SUBJECT: Result := 'Subject'; PID_AUTHOR: Result := 'Author'; PID_KEYWORDS: Result := 'Keywords'; PID_COMMENTS: Result := 'Comments'; PID_TEMPLATE: Result := 'Template'; PID_LASTAUTHOR: Result := 'Last Saved By'; PID_REVNUMBER: Result := 'Revision Number'; PID_EDITTIME: Result := 'Total Editing Time'; PID_LASTPRINTED: Result := 'Last Printed'; PID_CREATE_DTM: Result := 'Create Time/Date'; PID_LASTSAVE_DTM: Result := 'Last Saved Time/Date'; PID_PAGECOUNT: Result := 'Number of Pages'; PID_WORDCOUNT: Result := 'Number of Words'; PID_CHARCOUNT: Result := 'Number of Characters'; PID_THUMBNAIL: Result := 'Thumbnail'; PID_APPNAME: Result := 'Creating Application'; PID_SECURITY: Result := 'Security'; else Result := '$' + IntToHex(ePID, 8); end end; function IsNTFS(AFileName : string) : boolean; var fso, drv : OleVariant; begin IsNTFS := False; fso := CreateOleObject('Scripting.FileSystemObject'); drv := fso.GetDrive(fso.GetDriveName(AFileName)); if drv.FileSystem = 'NTFS' then IsNTFS := True; end; function GetFileSummaryInfo(const FileName: WideString; GUID_SummaryType: TGUID; PID_InfoType: cardinal): WideString; var Stg: IStorage; PropSetStg: IPropertySetStorage; PropStg: IPropertyStorage; PropVariant: array of TPropVariant; PropEnum: IEnumSTATPROPSTG; PropStat: STATPROPSTG; PIDCount: Integer; HRslt: HResult; PropSpec: array of TPropSpec; begin Result:=''; //I use the STGFMT_ANY const instead of the original STGFMT_FILE that didn't work at all... if(StgOpenStorageEx(pwidechar(FileName),STGM_READ or STGM_SHARE_DENY_WRITE, STGFMT_ANY,0,nil,nil,@IID_IPropertySetStorage,Stg) = S_OK) then begin PropSetStg := Stg as IPropertySetStorage; If (PropSetStg.Open(GUID_SummaryType, STGM_READ or STGM_SHARE_EXCLUSIVE, PropStg)) = S_OK Then Begin If PropStg.Enum(PropEnum) = S_OK then Begin PIDCount := 0; HRslt := PropEnum.Next(1, PropStat, nil); while HRslt = S_OK do begin inc(PIDCount); SetLength(PropSpec,PIDCount); PropSpec[PIDCount-1].ulKind := PRSPEC_PROPID; PropSpec[PIDCount-1].propid := PropStat.propid; HRslt := PropEnum.Next(1, PropStat, nil); end; SetLength(PropVariant,PIDCount); HRslt := PropStg.ReadMultiple(PIDCount, @PropSpec[0], @PropVariant[0]); // Use this to get the Incomming PID_InfoType if HRslt <> S_FALSE then Begin if PropVariant[PID_InfoType].vt = VT_LPSTR then if Assigned(PropVariant[PID_InfoType].pszVal) then Result := PropVariant[PID_InfoType].pszVal; End; //Use This to loop through all PID's //(and ignore the incomming PID_InfoType) { for k := 0 to PIDCount -1 do begin S := ''; if PropVariant[k].vt = VT_LPSTR then if Assigned(PropVariant[k].pszVal) then S := PropVariant[k].pszVal; S := Format(IntToStr(k)+' '+PropertyPIDToCaption(PropSpec[k].Propid)+ ' %s',[s]); if S <> '' then Result := Result + S + #13; end; } End; End; end; end; end.
Code:
Experiment with the PID_ numbers and these values
Var FileName,Info : WideString;
Begin If IsNTFS(FileName) Then Begin Info:=GetFileSummaryInfo(FileName,FmtID_SummaryInformation,PID_KEYWORDS); MessageDlg(Info,mtCustom,[mbOK], 0); End; End FmtID_SummaryInformation FMTID_DocSummaryInformation FMTID_UserDefinedProperties Greets, Delphi-Lover |
Re: Erweiterte Dateiinformationen schreiben
Zitat:
![]() Zitat:
|
Re: Erweiterte Dateiinformationen schreiben
Ich nutze jetzt folgenden Code um die FileSummaryInfos unter Delphi 2009 auszulesen. Wie kann ich das unicode-kompatibel machen? Wenn in den FileSummaryInfos Unicode gespeicher ist kommen mit dieser Funktion nur kryptische falsche Zeichen zurück:
Delphi-Quellcode:
function GetFileSummaryInfo(const FileName: WideString;
GUID_SummaryType: TGUID; PID_InfoType: cardinal): string; var hr : HRESULT; Stg : IStorage; PropSetStg : IPropertySetStorage; PropStg : IPropertyStorage; PropSpec : TPropSpec; PropVariant : TPropVariant; begin Result := ''; hr := S_FALSE; // for 9x and NT4 users if(not Win2k) or (@StgOpenStorageEx = nil) then hr := StgOpenStorage(pwidechar(FileName),nil,STGM_READ or STGM_SHARE_DENY_WRITE,nil,0,Stg) // for 2000, XP and higher else if(@StgOpenStorageEx <> nil) then hr := StgOpenStorageEx(pwidechar(FileName),STGM_READ or STGM_SHARE_DENY_WRITE,STGFMT_ANY,0,nil,nil, @IID_IPropertySetStorage,Stg); if(hr = S_OK) then begin PropSetStg := Stg as IPropertySetStorage; if(PropSetStg.Open(GUID_SummaryType,STGM_READ or STGM_SHARE_EXCLUSIVE,PropStg) = S_OK) then begin PropSpec.ulKind := PRSPEC_PROPID; PropSpec.propid := PID_InfoType; if(PropStg.ReadMultiple(1,@PropSpec,@PropVariant) = S_OK) and (PropVariant.vt = VT_LPSTR) and (PropVariant.pszVal <> nil) then Result := PropVariant.pszVal; end; end; end; |
Re: Erweiterte Dateiinformationen schreiben
Hallo,
Ich benutzte SetFileSummaryInfo und GetFileSummaryInfo auf XP-Rechnern ohne Probleme. Der Explorer und auch der TotalCommander (mit Plugin ShellDetails) zeigen die Infos problemlos an. Wenn ich das nun aber auf einem Vista-Laptop mache, bekomme ich die Felder nicht im Explorer angezeigt. Auch der TotalCommander zeigt nichts mehr an. WIN 7 konnte ich nicht testen. Es gibt zwar sehr viel mehr Feld-Namen, aber die alten Einträge werden nicht gefunden. Sie sind aber vorhanden da ich die Einträge mit meiner GetFileSummaryInfo immer noch lesen kann. Hat MS da wieder was geändert? Grüsse, Hans-Peter |
Re: Erweiterte Dateiinformationen schreiben
Nach weiterer Recherche habe ich herausgefunden, das MS das gravierend geändert hat.
Die Metadaten sind jetzt Bestandteil des File-Formats und nicht mehr im separaten NTFS-Stream. So kann man bei MS lesen das eine TXT oder RTF-Datei keine Dateiinfo mehr habe kann, da deren Dateiformat das eben nicht vorsieht. Nun ist das von MS mal wieder schlecht gemacht. Eine inkompatible Umstellung des Explorers. Man hat in der XP-Welt tausende Dateien mit Infos im NTFS-Stream angelegt und bekommt Sie nach einem Windows-Upgrade einfach nicht mehr zu sehen. Super. Da bleibt nur einen Custom-Browser zu schreiben der die Info wieder mit anzeigt. Grüsse, Hans-Peter |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz