Autor Beitrag
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 12.05.04 17:03 
Hinweis

Das bezieht sich diesen Beitrag und auf ein Programm von Luckie (Links s. Link ;)). Da ich die Unit ein bisschen verfeinert habe, nehme ich mir einfach mal die Freiheit, sie unter meinem Namen zu posten. :mrgreen:

Die Funktionen sind momentan nur zum Lesen und Schreiben von Strings ausgelegt. Ein paar der Konstanten benutzen aber ein anderes Format. In so einem Fall müsste die Funktion umgeschrieben oder erweitert werden.

Hier der Code der Unit "storage.pas":
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
unit storage;

interface

uses
  Windows, ComObj, ActiveX;

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}';
  FMTID_AudioSummaryInformation     : TGuid =
    '{64440490-4C8B-11D1-8B70-080036B11A03}';
  FMTID_VideoSummaryInformation     : TGUID =
    '{64440491-4C8B-11D1-8B70-080036B11A03}';
  FMTID_ImageSummaryInformation     : TGUID =
    '{6444048f-4c8b-11d1-8b70-080036b11a03}';
  FMTID_MediaFileSummaryInformation : TGUID =
    '{64440492-4c8b-11d1-8b70-080036b11a03}';


  STGFMT_STORAGE     = 0;
  STGFMT_FILE        = 3;
  STGFMT_ANY         = 4;
  STGFMT_DOCFILE     = 5;

  // Summary Information
  PIDSI_TITLE        = $00000002;     // VT_LPSTR
  PIDSI_SUBJECT      = $00000003;
  PIDSI_AUTHOR       = $00000004;
  PIDSI_KEYWORDS     = $00000005;
  PIDSI_COMMENTS     = $00000006;
  PIDSI_TEMPLATE     = $00000007;
  PIDSI_LASTAUTHOR   = $00000008;
  PIDSI_REVNUMBER    = $00000009;
  PIDSI_EDITTIME     = $0000000A;     // VT_FILETIME (UTC)
  PIDSI_LASTPRINTED  = $0000000B;
  PIDSI_CREATE_DTM   = $0000000C;
  PIDSI_LASTSAVE_DTM = $0000000D;
  PIDSI_PAGECOUNT    = $0000000E;     // VT_I4
  PIDSI_WORDCOUNT    = $0000000F;
  PIDSI_CHARCOUNT    = $00000010;
  PIDSI_THUMBNAIL    = $00000011;     // VT_CF
  PIDSI_APPNAME      = $00000012;     // VT_LPSTR
  PIDSI_DOC_SECURITY = $00000013;     // VT_I4

  // Document Summary Information
  PIDDSI_CATEGORY    = $00000002;     // VT_LPSTR
  PIDDSI_PRESFORMAT  = $00000003;
  PIDDSI_BYTECOUNT   = $00000004;     // VT_I4
  PIDDSI_LINECOUNT   = $00000005;
  PIDDSI_PARCOUNT    = $00000006;
  PIDDSI_SLIDECOUNT  = $00000007;
  PIDDSI_NOTECOUNT   = $00000008;
  PIDDSI_HIDDENCOUNT = $00000009;
  PIDDSI_MMCLIPCOUNT = $0000000A;
  PIDDSI_SCALE       = $0000000B;     // VT_BOOL
  PIDDSI_HEADINGPAIR = $0000000C;     // VT_VARIANT | VT_VECTOR
  PIDDSI_DOCPARTS    = $0000000D;     // VT_LPSTR | VT_VECTOR
  PIDDSI_MANAGER     = $0000000E;     // VT_LPSTR
  PIDDSI_COMPANY     = $0000000F;
  PIDDSI_LINKSDIRTY  = $00000010;     // VT_BOOL

  // FMTID_MediaFileSummaryInfo
  PIDMSI_EDITOR      = $00000002;     // VT_LPWSTR
  PIDMSI_SUPPLIER    = $00000003;
  PIDMSI_SOURCE      = $00000004;
  PIDMSI_SEQUENCE_NO = $00000005;
  PIDMSI_PROJECT     = $00000006;
  PIDMSI_STATUS      = $00000007;     // VT_UI4
  PIDMSI_OWNER       = $00000008;     // VT_LPWSTR
  PIDMSI_RATING      = $00000009;
  PIDMSI_PRODUCTION  = $0000000A;     // VT_FILETIME (UTC)
  PIDMSI_COPYRIGHT   = $0000000B;     // VT_LPWSTR

  // FMTID_AudioSummaryInformation
  PIDASI_FORMAT        = $00000002;   // VT_BSTR
  PIDASI_TIMELENGTH    = $00000003;   // VT_UI4, milliseconds
  PIDASI_AVG_DATA_RATE = $00000004;   // VT_UI4,  Hz
  PIDASI_SAMPLE_RATE   = $00000005;   // VT_UI4,  bits
  PIDASI_SAMPLE_SIZE   = $00000006;   // VT_UI4,  bits
  PIDASI_CHANNEL_COUNT = $00000007;   // VT_UI4
  PIDASI_STREAM_NUMBER = $00000008;   // VT_UI2
  PIDASI_STREAM_NAME   = $00000009;   // VT_LPWSTR
  PIDASI_COMPRESSION   = $0000000A;   // VT_LPWSTR

  // FMTID_VideoSummaryInformation
  PIDVSI_STREAM_NAME   = $00000002;   // "StreamName", VT_LPWSTR
  PIDVSI_FRAME_WIDTH   = $00000003;   // "FrameWidth", VT_UI4
  PIDVSI_FRAME_HEIGHT  = $00000004;   // "FrameHeight", VT_UI4
  PIDVSI_TIMELENGTH    = $00000007;   // "TimeLength", VT_UI4, milliseconds
  PIDVSI_FRAME_COUNT   = $00000005;   // "FrameCount". VT_UI4
  PIDVSI_FRAME_RATE    = $00000006;   // "FrameRate", VT_UI4, frames/millisecond
  PIDVSI_DATA_RATE     = $00000008;   // "DataRate", VT_UI4, bytes/second
  PIDVSI_SAMPLE_SIZE   = $00000009;   // "SampleSize", VT_UI4
  PIDVSI_COMPRESSION   = $0000000A;   // "Compression", VT_LPWSTR
  PIDVSI_STREAM_NUMBER = $0000000B;   // "StreamNumber", VT_UI2

type
  TMultipleArray     = record
    pidInfoType : cardinal;
    pidInfoStr  : pchar;
  end;
  TMultipleArrayList = array of TMultipleArray;


function GetFileSummaryInfo(const FileName: WideString;
  GUID_SummaryType: TGUID; PID_InfoType: cardinal): string;
function SetFileSummaryInfo(const FileName: WideString; GUID_InfoType: TGUID;
  PID_InfoType: cardinal; InfoStr: string): boolean;
function SetMultipleFileSummaryInfo(const FileName: WideString;
  GUID_InfoType: TGUID; MultipleArrayList: TMultipleArrayList): boolean;



implementation


const
  szOleDll                = 'ole32.dll';
  IID_IPropertySetStorage : TGUID = '{0000013A-0000-0000-C000-000000000046}';
type
  TStgOpenStorageEx       = function(const pwcsName: PWideChar;
    grfMode: DWORD; stgfmt: DWORD; grfAttrs: DWORD; pStgOptions: pointer;
    reserved2: pointer; riid: PGUID; out ppObjectOpen: IStorage): HRESULT;
    stdcall;
var
  StgOpenStorageEx        : TStgOpenStorageEx = nil;
  dll                     : dword = 0;
  Win2k                   : boolean = false;


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 = nilthen
    hr := StgOpenStorage(pwidechar(FileName),nil,STGM_READ or
      STGM_SHARE_DENY_WRITE,nil,0,Stg)
  // for 2000, XP and higher
  else if(@StgOpenStorageEx <> nilthen
    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 <> nilthen
      Result := PropVariant.pszVal;
    end;
  end;
end;

function SetFileSummaryInfo(const FileName: WideString; GUID_InfoType: TGUID;
  PID_InfoType: cardinal; InfoStr: string): boolean;
var
  hr          : HRESULT;
  Stg         : IStorage;
  PropSetStg  : IPropertySetStorage;
  PropStg     : IPropertyStorage;
  PropSpec    : TPropSpec;
  PropVariant : TPropVariant;
begin
  Result      := false;
  hr          := S_FALSE;

  // 9x and NT4
  if(not Win2k) or (@StgOpenStorageEx = nilthen
    hr := StgOpenStorage(pwidechar(FileName),nil,STGM_SHARE_EXCLUSIVE or
      STGM_READWRITE,nil,0,Stg)
  // 2000, XP and higher
  else if(@StgOpenStorageEx <> nilthen
    hr := StgOpenStorageEx(pwidechar(FileName),STGM_SHARE_EXCLUSIVE or
    STGM_READWRITE,STGFMT_ANY,0,nil,nil,@IID_IPropertySetStorage,Stg);

  if(hr = S_OK) then
  begin
    PropSetStg := Stg as IPropertySetStorage;

    // try to open an existing Property set
    hr         := PropSetStg.Open(GUID_InfoType,STGM_READWRITE or
      STGM_SHARE_EXCLUSIVE,PropStg);

    // create a new set
    if(hr <> S_OK) then
      hr       := PropSetStg.Create(GUID_InfoType,GUID_InfoType,
        PROPSETFLAG_DEFAULT,STGM_CREATE or STGM_READWRITE or
        STGM_SHARE_EXCLUSIVE,PropStg);

    if(hr = S_OK) then
    begin
      PropSpec.ulKind    := PRSPEC_PROPID;
      PropSpec.propid    := PID_InfoType;
      PropVariant.vt     := VT_LPSTR;
      PropVariant.pszVal := pchar(InfoStr);

      if(PropStg.WriteMultiple(1,@PropSpec,@PropVariant,2) = S_OK) then
      begin
        Result := (PropStg.Commit(STGC_DEFAULT) = S_OK);
      end;
    end;
  end;
end;

function SetMultipleFileSummaryInfo(const FileName: WideString;
  GUID_InfoType: TGUID; MultipleArrayList: TMultipleArrayList): boolean;
var
  Stg         : IStorage;
  PropSetStg  : IPropertySetStorage;
  hr          : HRESULT;
  PropStg     : IPropertyStorage;
  PropSpec    : array of TPropSpec;
  PropVariant : array of TPropVariant;
  i           : integer;
begin
  Result      := false;
  hr          := S_FALSE;
  if(length(MultipleArrayList) = 0then exit;

  // 9x, NT4
  if(not Win2k) or (@StgOpenStorageEx = nilthen
    hr := StgOpenStorage(pwidechar(FileName),nil,STGM_SHARE_EXCLUSIVE or
      STGM_READWRITE,nil,0,Stg)
  // 2000, XP and higher
  else if(@StgOpenStorageEx <> nilthen
    hr := StgOpenStorageEx(pwidechar(FileName),STGM_SHARE_EXCLUSIVE or
    STGM_READWRITE,STGFMT_ANY,0,nil,nil,@IID_IPropertySetStorage,Stg);

  if(hr = S_OK) then
  begin
    PropSetStg := Stg as IPropertySetStorage;

    // try to open an existing Property set
    hr         := PropSetStg.Open(GUID_InfoType,STGM_READWRITE or
      STGM_SHARE_EXCLUSIVE,PropStg);

    // create a new set
    if(hr <> S_OK) then
      hr       := PropSetStg.Create(GUID_InfoType,GUID_InfoType,
        PROPSETFLAG_DEFAULT,STGM_CREATE or STGM_READWRITE or
        STGM_SHARE_EXCLUSIVE,PropStg);

    if(hr = S_OK) then
    begin
      // set default length
      SetLength(PropSpec,0);
      SetLength(PropVariant,0);

      // fill
      for i := 0 to length(MultipleArrayList) - 1 do
        if(MultipleArrayList[i].pidInfoType <> 0and
          (MultipleArrayList[i].pidInfoStr <> nilthen
        begin
          SetLength(PropSpec,length(PropSpec) + 1);
          PropSpec[length(PropSpec)-1].ulKind       := PRSPEC_PROPID;
          PropSpec[length(PropSpec)-1].propid       :=
            MultipleArrayList[i].pidInfoType;

          SetLength(PropVariant,length(PropVariant) + 1);
          PropVariant[length(PropVariant)-1].vt     := VT_LPSTR;
          PropVariant[length(PropVariant)-1].pszVal :=
            MultipleArrayList[i].pidInfoStr;
        end;

      // write
      if(length(PropSpec) > 0and
        (length(PropVariant) > 0and
        (length(PropSpec) = length(PropVariant)) then
      begin
        if(PropStg.WriteMultiple(length(PropSpec),@PropSpec[0],
          @PropVariant[0],2) = S_OK) then
        begin
          Result := (PropStg.Commit(STGC_DEFAULT) = S_OK);
        end;

        SetLength(PropSpec,0);
        SetLength(PropVariant,0);
      end;
    end;
  end;
end;


//
// Main
//
var
  os : TOSVersionInfo;

initialization
  // get OS
  ZeroMemory(@os,sizeof(os));
  os.dwOSVersionInfoSize := sizeof(os);

  // is it Windows 2000 or higher?
  Win2k                  := (GetVersionEx(os)) and
    (os.dwMajorVersion >= 5and
    (os.dwPlatformId = VER_PLATFORM_WIN32_NT);

  CoInitialize(nil);

  dll := LoadLibrary(szOleDll);
  if(dll <> 0then
  begin
    StgOpenStorageEx := GetProcAddress(dll,'StgOpenStorageEx');
    if(@StgOpenStorageEx = nilthen
    begin
      FreeLibrary(dll);
      dll := 0;
    end;
  end;
finalization
  if(dll <> 0then FreeLibrary(dll);
  CoUninitialize;
end.


Erläuterung

Unter NTFS bzw. in Office-Dokumenten kann man bestimmte Dateieigenschaften setzen (Rechtsklick auf die Datei -> Eigenschaften -> Dateiinfos). Mit den o.g. Funktionen lassen sich diese Eigenschaften auslesen und auch schreiben. Um bspw. den Autoren einer Datei anzuzeigen, genügt
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
  dummy : string;
begin
  dummy := GetFileSummaryInfo('Dateiname.txt',
    FMTID_SummaryInformation,        // <-- die gewünschte Kategorie
    PIDSI_AUTHOR);                   // <-- der gewünschte Wert

  ShowMessage(dummy);
end;


Um aber bspw. die Firma in einem Office-Dokument (einer DOC-Datei als Beispiel) anzuzeigen, muss eine andere Kategorie gewählt werden
ausblenden Delphi-Quelltext
1:
2:
3:
  dummy := GetFileSummaryInfo('Dateiname.doc',
    FMTID_DocSummaryInformation,     // <-- Office-Kategorie
    PIDDSI_COMPANY);                 // <-- Eintrag der Firma

usw.

Will man einen Wert setzen, kann man "SetFileSummaryInfo" verwenden. Die Quelle einer Datei als Beispiel:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
SetFileSummaryInfo('Dateiname.txt',
  FMTID_MediaFileSummaryInformation, // <-- Kategorie
  PIDMSI_SOURCE,                     // <-- Wert, der gesetzt werden soll
  'http://www.delphi-forum.de');     // <-- String

Den Erfolg kann man in den Eigenschaften der Datei kontrollieren, allerdings muss man dazu auf den Button "Erweitert" klicken, weil die Quelle nur dann und dort angezeigt wird.

Sollen mehrere Werte auf einen Streich gesetzt werden, dann stellt die Unit den Typ "TMultipleArrayList" und die Funktion "SetMultipleFileSummaryInfo" zur Verfügung. Das sieht dann so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
var
  mal : TMultipleArrayList;
begin
  SetLength(mal,3);
  mal[0].pidInfoType := PIDSI_AUTHOR;
  mal[0].pidInfoStr  := 'Ich';
  mal[1].pidInfyType := PIDSI_COMMENTS;
  mal[1].pidInfoStr  := 'Mein Kommentar';
  mal[2].pidInfoType := PIDSI_TITLE;
  mal[2].pidInfoStr  := 'Mein Titel';

  if(SetMultipleFileSummaryInfo('Dateiname.txt',
    FMTID_SummaryInformation,
    mal)) then
  ShowMessage('Werte gesetzt');

  SetLength(mal,0);
end;

Und das war´s auch schon.


Zuletzt bearbeitet von MathiasSimmack am So 23.05.04 08:50, insgesamt 1-mal bearbeitet
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 22.05.04 23:16 
Ich habe die Unit mal aktualisiert. Es klappt jetzt auch unter Windows 9x, dann allerdings natürlich nur bei Dateien, die auch die erweiterten Infos enthalten. Speziell also Office-Dateien, etwa DOCs. Evtl. kann man damit aber auch unter NT4 Dateiinfos setzen und lesen. Das müsste mal jemand probieren, der NT4 hat. ;)
Yusha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 20



BeitragVerfasst: Do 30.09.04 18:21 
Vielen Dank für die Hilfe ! Deine Unit funktioniert prächtig und tut seit heute Mittag ihren Dienst :D .

Nun wüsste ich noch gern, ob man auch Nicht - Office Dateien unter NTFS Metadaten verpassen kann. Zb. könnte man dann PDF's wunderbar zu den ursprünglichen Word-Dokumenten zuordnen.

Bei meinen Tests konnte ich alles wunderbar auslesen, ausser Wordcount und Charcount. Was hat es damit aufsich ? Muss man beim Speichern eines Officedokumentes diese Infos manuell setzen ?
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 30.09.04 19:47 
Yusha hat folgendes geschrieben:
Nun wüsste ich noch gern, ob man auch Nicht - Office Dateien unter NTFS Metadaten verpassen kann. Zb. könnte man dann PDF's wunderbar zu den ursprünglichen Word-Dokumenten zuordnen.

Unter NTFS kannst du im Prinzip alle Dateien mit erweiterten Infos versehen. Unter FAT klappt das nur bei Office-Dateien. Aber ich denke, das steht hier auch irgendwo. ;)

Zitat:
Bei meinen Tests konnte ich alles wunderbar auslesen, ausser Wordcount und Charcount. Was hat es damit aufsich ? Muss man beim Speichern eines Officedokumentes diese Infos manuell setzen ?

Ich schätze mal, die werden automatisch gesetzt. Wenn ich das richtig übersetze, dass heißen sie "Wordzahl" und "Zeichenzahl".
Superkaterchen
Hält's aus hier
Beiträge: 1

Win XP
D6 Prof
BeitragVerfasst: So 30.01.05 17:44 
Hallo,

auf der Suche nach Möglichkeiten, Dateiinfos zu lesen und zu schreiben, bin ich auf diese tolle Unit gestoßen :shock:.

Nun wüßte ich doch noch zu gerne, wie man den an die Filter der Kategorien kommt, da ich mir eigentlich ein Tool schreiben wollte, daß komfortabel meine MP3-Dateien verwaltet.

FMTID_SummaryInformation, // <-- die gewünschte Kategorie

Das wäre jetzt noch das Sahne-Häubchen...

Stephan
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8535
Erhaltene Danke: 473

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: So 30.01.05 19:21 
Ich habe mich zwar nicht mit dieser Unit hier auseinander gesetzt, aber ich glaube, dass man für deine Zwecke das anders machen sollte. Ich nehme mal schwer an, dass du Infos wie Dauer, Artist, Titel, Bitrate etc. auslesen willst. Diese Informationen sind in den Mp3-Dateien selbst enthalten, man muss sie nur finden. Und das geht auch - im Gegensatz zu dem hier, wenn ich das richtig überblicke - auf Nicht-NTFS.
Dazu gibts hier im Forum diverse Hilfen zu. Und ein Verwaltungstool gibts auch schon: Hier

_________________
We are, we were and will not be.
DerRudi
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mo 10.04.06 18:18 
Hallo,

ich bin ganz neu hier :-)

ich habe gehört, dass die Funktion "StgOpenStorageEx" genutzt werden kann um die Dateieigenschaften zu lesen und zu schreiben. Ich habe deshalb einfach mal danach gegoogelt. Es gab nicht sehr viele gute Ergebnisse - eigentlich nur ein paar Forumsbeiträge. Dieser Thread ist sehr gut. Der obige Code funktioniert toll. Ich bin aber auf ein paar Probleme gestoßen.
Das ganze funktioniert ja ausgehend von dieser Funktion transparent; d.h. es werden Dateinfos gelesen und geschrieben unabhängig davon ob sie im NTFS-Zusatzstrom oder in der Datei selbst stehen. Das funktioniert auch sehr gut für viele Dateitypen. Bei JPG bin ich allerdings auf ein Problem gestoßen. Mit der Unit werden die Infos bei JPGs immer in einen Zusatzstrom gelesen bzw. geschrieben. Das funktioniert für sich gesehen wunderprächtig. Dummerweise macht der Explorer das hier anders. Bei diesem Dateityp stehen die Infos auch in der Datei selbst drin. Es ist aber trotzdem keine compound-Datei. Hier meine Fragen:

- Weiß jemand wie das bei JPG funktioniert?
- Ist das ein generelles Problem? Wie schaffe ich es, dass es sich in allen Fällen so verhält wie der Explorer.
- Mit "doc summary" und summary" hatte ich keine Probleme. Bei z.B. "image summary" kriege ich gar nichts. Ich vermute dass das mit dem ersten Problem zusammenhängt.

Ich würde mich über jede nette Antwort freuen, vielen Dank!
DerRudi
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Do 20.04.06 15:00 
Hallo nochmal,

hat denn niemand eine Idee was Windows hier macht?

--------
Der Rudi
stewag
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mo 23.06.08 08:45 
Titel: Filedate Felder bleiben leer?
Hallo,

auch bei mir klappt die o.g. Routine von Mathias wunderbar - schönen Dank noch einmal an ihn an dieser Stelle.

Nur an einem Punkt habe ich ein Problem: Eine Abfrage der Felder
PIDSI_CREATE_DTM und
PIDSI_LASTSAVE_DTM mit GetFileSummaryInfo() liefert stets einen leeren String.

Hat dafür jemand eine Erklärung?

Danke im Vorraus,
Steffen
stewag
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mo 07.07.08 11:49 
Titel: Wo sind die Experten?
Hat den keiner eine Idee warum man die Datumsfelder der Dateieigenschaften nicht über die Prozedur von Mathias auslesen kann?

Gruß
Steffen
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 07.07.08 13:20 
Sind sie denn gesetzt? Hast du den entsprechenden Teil in der Unit von Mathias mal debuggt?
bayou
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 88


D6 PE
BeitragVerfasst: So 01.02.09 13:23 
Hallo,
auch ich möchte mich für diesen Beitrag bedanken.
Es hat mir sehr geholfen die Dateiinfos aus PDF Dateien ein und aus zu lesen.
Leider geht bei mir das Anzeigen des Datum "geändert am" auch nicht.
ich habe es mit
ausblenden Delphi-Quelltext
1:
  DDate := GetFileSummaryInfo(fig_filename, FMTID_SummaryInformation, PIDSI_LASTSAVE_DTM);					

versucht.

Kann mir jemand sagen was ich falsch mache?

Danke
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 01.02.09 15:52 
Das kann ich dir zwar nicht sagen, aber wenn du einfach nur das Datum der letzten Änderung haben möchtest, das hat gerade vor 2 Tagen jemand gefragt (Titel: "geändert am:" einer Datei auslesen ;-)). Das geht mit GetFileTime, hier meine Antwort dazu:
www.delphi-forum.de/....php?p=547059#547059
bayou
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 88


D6 PE
BeitragVerfasst: So 01.02.09 18:01 
OK, Danke.
Ich dachte nur es ginge über das gleiche System einfacher.

PS: Hat sich erledigt
nochmals Danke
bayou
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 88


D6 PE
BeitragVerfasst: Mo 02.02.09 10:09 
Hallo,
ich habe doch noch mal eine Frage,

Kann ich das Datum auch in Engl. Version anzeigen lassen, also Jahr:Monat:Tag . . .?

zur Erinnerung, der Code sieht so aus:
ins Programm bringen
ausblenden Delphi-Quelltext
1:
2:
3:
  WriteTime := MyGetFileTime(PChar(fig_filename));
  if WriteTime <> 0 then
     DDate := DateTimeToStr(WriteTime);

umwandeln
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function TFigureData.MyGetFileTime(FileName: PChar): TDateTime;
var
  FileHandle: Cardinal;
  CreatTime, LastWriteTime: TFileTime;
  UTCSystemTime, LocalSystemTime: TSystemTime;
begin
  Result := 0;
  FileHandle := CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 00);
  if FileHandle = INVALID_HANDLE_VALUE then
    Exit;
  if not GetFileTime(FileHandle, @CreatTime, nil, @LastWriteTime) then
    Exit;
  FileTimeToSystemTime(CreatTime, UTCSystemTime);
  SystemTimeToTzSpecificLocalTime(nil, UTCSystemTime, LocalSystemTime);
  Result := SystemTimeToDateTime(LocalSystemTime);
  CloseHandle(FileHandle);
end;


Danke
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 02.02.09 10:37 
FormatDateTime IIRC.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
bayou
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 88


D6 PE
BeitragVerfasst: Mo 02.02.09 10:57 
Danke für den Tip.

darauf hin habe ich etwas gefunden und folgendes geändert.
ausblenden Delphi-Quelltext
1:
DDate := FormatDateTime('yyyy/mm/dd/ hh:nn:ss', WriteTime);					


Man kann besser nach Datum sortieren wenn erst das Jahr dann Monat und Tag angezeigt werden.
master_of_strategy
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Sa 13.06.09 17:33 
Hallo,

ich möchte gerne die Länge einer avi-Datei auslesen. Dazu bietet sich ja diese unit an.
Allerdings habe ich ein Problem:
Egal, von welcher Datei, von irgendeinem Typ, an irgendeinem Speicherort ich irgendeine Information auslesen möchte, gibt die Funktion '' zurück.

Wie ich feststellen konnte, liegt das Problem an:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
    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 <> nilthen
      Result := PropVariant.pszVal;
    end;


Dabei wird die Bedingung

ausblenden Delphi-Quelltext
1:
2:
if(PropSetStg.Open(GUID_SummaryType,STGM_READ or
      STGM_SHARE_EXCLUSIVE,PropStg) = S_OK) then...

nie wahr. Lass ich die Bed. weg, gibts ne AV.

Deshalb meine Frage: Woran liegt das?
oder alternativ: Gibt es eine andere Möglichkeit, die Länge einer Filmdatei auszulesen?
HPW
Hält's aus hier
Beiträge: 4

WIN2K/WINXP
Delphi 5 Std / Delphi 7 Pro
BeitragVerfasst: Mo 01.03.10 16:06 
Ich habe meine Frage auch schon auf DelphiPraxis gestellt:

www.delphipraxis.net/post1134598.html

Wie funktioniert das mit den Daeiinfos unter Vista und dessen Explorer?
Da hat MS anscheinend grundlegend was geändert!
Ist das unter WIN 7 auch so?

Grüsse,

Hans-Peter
HPW
Hält's aus hier
Beiträge: 4

WIN2K/WINXP
Delphi 5 Std / Delphi 7 Pro
BeitragVerfasst: Di 02.03.10 21:38 
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