AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Erweiterte Dateiinformationen schreiben

Erweiterte Dateiinformationen schreiben

Ein Thema von Luckie · begonnen am 15. Apr 2004 · letzter Beitrag vom 17. Mai 2015
Antwort Antwort
Seite 2 von 3     12 3   
Assarbad
(Gast)

n/a Beiträge
 
#11

Re: Erweiterte Dateiinformationen schreiben

  Alt 28. Apr 2004, 10:14
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.
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#12

Re: Erweiterte Dateiinformationen schreiben

  Alt 28. Apr 2004, 10:16
So, noch ein Nachtrag meinerseits:

Zitat von MathiasSimmack:
Dabei ist mir aufgefallen, dass die Funktion nichts anzeigt, wenn man die gewünschte Eigenschaft vorher mit Bordmitteln (sprich: Rechtsklick auf die Datei -> Eigenschaften -> Dateiinfos) setzt.
Mittlerweile weiß ich auch warum. Windows legt diese Einträge nicht als WideString sondern nur als String ab. Ändere ich die Funktion "GetFileSummaryInfo" entsprechend um, sehe ich das auch.

Zitat von Luckie:
In mehrer Felder schreiben geht nicht, entweder du schreibst sie dir selber um, dass sie es kann oder rufst sie entsprechend oft nacheinander auf.
Das klappt ja im Original wg. "Create" nicht, aber ich war mal so frei, eine zusätzliche Funktion "SetMultipleFileSummaryInfo" zu schreiben, die sich wie folgt aufrufen lässt:
Delphi-Quellcode:
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;
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)

Zitat von schitho:
Außerdem hab ich keine Möglichkeit gefunden, wie ich das Feld Revisionsnummer und Quelle mit Daten füllen kann.
Erstere ist PIDSI_REVNUMBER und lässt sich recht einfach setzen
Delphi-Quellcode:
  SetFileSummaryInfo('MeineDatei.txt',
    FMTID_SummaryInformation,
    PIDSI_REVNUMBER,
    '3.0');
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
Delphi-Quellcode:
  SetFileSummaryInfo('MeineDatei.txt',
    FMTID_MediaFileSummaryInformation,
    PIDMSI_SOURCE,
    'www.delphipraxis.net');
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.
Angehängte Dateien
Dateityp: pas storage.pas (9,9 KB, 56x aufgerufen)
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#13

Re: Erweiterte Dateiinformationen schreiben

  Alt 28. Apr 2004, 10:19
Hey, da hat sich ja einer reingedrängelt.

Zitat von Assarbad:
[...] 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.
Anschauen würde ich mir das gern mal. Aber damit du nicht ständig CDs versaust (wie viele schulde ich dir jetzt eigentlich schon?) würde ich eine Email vorziehen. Aber davon abgesehen würde mich mal interessieren, wie sich die Unit von mir auf deinem NT4 macht. Kannst du mal ein kleines Beispielprojekt zusammenschrauben und spaßeshalber ein paar Eigenschaften setzen und lesen? Das wäre sehr nett.
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#14

Re: Erweiterte Dateiinformationen schreiben

  Alt 22. Mai 2004, 23:13
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!
Angehängte Dateien
Dateityp: pas storage_178.pas (11,0 KB, 133x aufgerufen)
  Mit Zitat antworten Zitat
ringli

Registriert seit: 7. Okt 2004
482 Beiträge
 
Delphi 11 Alexandria
 
#15

Re: Erweiterte Dateiinformationen schreiben

  Alt 15. Okt 2004, 21:25
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
  Mit Zitat antworten Zitat
Delphi-Lover

Registriert seit: 19. Okt 2004
Ort: Amsterdam
30 Beiträge
 
Delphi 2005 Professional
 
#16

Re: Erweiterte Dateiinformationen schreiben

  Alt 25. Apr 2005, 16:00
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:
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.
Use the function in this way:

Code:
Var FileName,Info : WideString;
Begin
  If IsNTFS(FileName) Then
  Begin
    Info:=GetFileSummaryInfo(FileName,FmtID_SummaryInformation,PID_KEYWORDS);
    MessageDlg(Info,mtCustom,[mbOK], 0);
  End;
End
Experiment with the PID_ numbers and these values

FmtID_SummaryInformation
FMTID_DocSummaryInformation
FMTID_UserDefinedProperties

Greets,

Delphi-Lover
Rob
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#17

Re: Erweiterte Dateiinformationen schreiben

  Alt 25. Apr 2005, 17:19
Zitat von Delphi-Lover:
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.
You just renamed a few variables, huh? I'm sorry, but I don't see a difference between your version and the one, Luckie spoke about in his first post. To be honest: I didn't like the original unit. So, I made another version, you can get here. I mean, I can set values
Zitat:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  mal : TMultipleArrayList;
begin
  SetLength(mal,3);
  mal[0].pidInfoType := PIDSI_AUTHOR;
  mal[0].pidInfoStr := 'Me, the one and only';
  mal[1].pidInfoType := PIDSI_COMMENTS;
  mal[1].pidInfoStr := 'Tralala';
  mal[2].pidInfoType := PIDSI_TITLE;
  mal[2].pidInfoStr := 'My title';

  SetMultipleFileSummaryInfo('MeineDatei.txt',
    FMTID_SummaryInformation,
    mal);

  SetLength(mal,0);
end;
you just read them.
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
705 Beiträge
 
Delphi 11 Alexandria
 
#18

Re: Erweiterte Dateiinformationen schreiben

  Alt 22. Jul 2009, 21:35
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;
  Mit Zitat antworten Zitat
HPW

Registriert seit: 28. Feb 2003
160 Beiträge
 
Delphi 7 Professional
 
#19

Re: Erweiterte Dateiinformationen schreiben

  Alt 1. Mär 2010, 08:27
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
Hans-Peter
  Mit Zitat antworten Zitat
HPW

Registriert seit: 28. Feb 2003
160 Beiträge
 
Delphi 7 Professional
 
#20

Re: Erweiterte Dateiinformationen schreiben

  Alt 2. Mär 2010, 20:36
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
Hans-Peter
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf