2010-06-15 3 views
3

Lorsque j'utilise l'Explorateur Windows pour afficher des fichiers, j'ai la possibilité de définir une "étiquette", une "catégorie" ou d'autres attributs. Pour un JPEG, un ensemble d'attributs différent (y compris "tag") sont des options. J'aimerais pouvoir les définir par programme.Comment paramétrer une étiquette de fichier par programme

Comment est-ce que je programme par programme un balise de fichier et d'autres attributs de fichier en utilisant Delphi (j'ai Delphi 2010 Pro)?

Répondre

5

Les balises dans les fichiers JPEG sont stockées en tant que mots-clés IPTC. Il y a quelques bibliothèques disponibles pour lire et écrire celles-ci, si c'est ce que vous demandez.

L'explorateur affiche différentes colonnes pour différents types de fichiers car il sait que ces types de fichiers prennent en charge ces colonnes supplémentaires. Vous pouvez définir des plug-ins shell pour prendre en charge les informations de colonne personnalisées pour vos propres types de fichiers. MSDN provides an overview.

+0

+1 pour le lien MSDN. –

+0

Selon mon commentaire à Robert, j'ai eu la fausse idée que je pouvais assigner des balises à TOUS les fichiers, pas seulement mon propre format. Je pensais que ce serait un bon moyen de faciliter la création d'un système de gestion de documents basé sur un disque de pauvre en reliant n'importe quel fichier à un projet ou contact en utilisant une balise dans le fichier pour stocker le ProjectID ou ContactID. Il semble que je sois malchanceux si cela ne peut être fait que pour les formats de fichiers pour lesquels les attributs souhaités ont été définis (ou pour mes propres formats de fichier). Nous vous remercions de votre aide. –

+0

Non, nous ne sommes pas encore là. Il y a les débuts d'un [système de fichiers par étiquette] (http://code.google.com/p/xtagfs/) pour Macintosh qui fonctionne en manipulant des liens symboliques. Microsoft travaillait sur un [système de fichiers basé sur une base de données] (http://en.wikipedia.org/wiki/WinFS) il y a de nombreuses années qui pourrait probablement fonctionner avec des tags plutôt bien, mais il semble que ce projet a été en grande partie stagné pour le passé plusieurs années; c'était censé être à Vista. –

2

Je ne connais aucun moyen standard de stocker des informations de métadonnées supplémentaires. Chaque application peut enregistrer son propre onglet de propriétés et stocker ces informations de méta-données de quelque manière que ce soit.

Je crois que vous parlez de la fonctionnalité de marquage d'image de la Galerie de photos Windows. Les informations sont stockées dans deux fichiers: images.pd4 et NavTree.state comme déterminé par Gail Bjork person who wanted to remove this information.

Ceci est stocké dans: C: \ Utilisateurs \ YourUser \ AppData \ Local \ Microsoft \ Windows Galerie de photos.

Some people ont trouvé le format de fichier. Mais je n'ai pas trouvé de spécification publiée de quiconque interne à Microsoft ou externe.

Vous avez également demandé d'autres attributs de fichier peuvent être initialisés par les

FileSetAttr(FileName,Attribute) 

Les attributs qui peuvent être définis:

  • faReadOnly
  • faHidden
  • faSysFile
  • faVolumeID
  • faDirectory
  • faArchive
  • faSymLink

//The following sets test.txt to a readonly and hidden file. FileSetAttr('C:\Test.txt',faReadOnly or faHidden);

La fonction a un résultat booléen que vous pouvez vérifier si l'opération terminée.

+0

On dirait que mon hypothèse de départ était erronée, que tous les fichiers peuvent avoir une étiquette assignée. Vous avez raison, j'utilise Windows Live avec la galerie de photos; Je n'ai pas réalisé qu'une partie de la fonctionnalité d'étiquetage avait été installée avec. Merci pour votre aide. –

4

Je pense que vous voulez récupérer toutes les propriétés du fichier qui peut être accédé en appuyant sur le bouton droit de la souris dans l'explorateur.

Vous pouvez utiliser cet appareil:

unit u_fsummary; 

interface 

uses Windows, ComObj, ActiveX, Variants, Sysutils; 

procedure SetFileSummaryInfo(const FileName : WideString; Author, Title, Subject, Keywords, Comments : WideString); 
function GetFileSummaryInfo(const FileName: WideString): String; 
function IsNTFS(AFileName : string) : boolean; 

implementation 

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. 


// Summary Information 
PID_TITLE  = 2; 
PID_SUBJECT  = 3; 
PID_AUTHOR  = 4; 
PID_KEYWORDS  = 5; 
PID_COMMENTS  = 6; 
PID_TEMPLATE  = 7; 
PID_LASTAUTHOR = 8; 
PID_REVNUMBER = 9; 
PID_EDITTIME  = 10; 
PID_LASTPRINTED = 11; 
PID_CREATE_DTM = 12; 
PID_LASTSAVE_DTM = 13; 
PID_PAGECOUNT = 14; 
PID_WORDCOUNT = 15; 
PID_CHARCOUNT = 16; 
PID_THUMBNAIL = 17; 
PID_APPNAME  = 18; 
PID_SECURITY  = 19; 

// 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; 
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 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'; 


function GetFileSummaryInfo(const FileName: WideString): String; 

var 
I: Integer; 
PropSetStg: IPropertySetStorage; 
PropSpec: array of TPropSpec; 
PropStg: IPropertyStorage; 
PropVariant: array of TPropVariant; 
Rslt: HResult; 
S: String; 
Stg: IStorage; 
PropEnum: IEnumSTATPROPSTG; 
HR : HResult; 
PropStat: STATPROPSTG; 
k : integer; 

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; 

begin 
Result := ''; 
try 
OleCheck(StgOpenStorageEx(PWideChar(FileName), 
STGM_READ or STGM_SHARE_DENY_WRITE, 
STGFMT_FILE, 
0, nil, nil, @IID_IPropertySetStorage, stg)); 

PropSetStg := Stg as IPropertySetStorage; 

OleCheck(PropSetStg.Open(FmtID_SummaryInformation, 
    STGM_READ or STGM_SHARE_EXCLUSIVE, PropStg)); 

OleCheck(PropStg.Enum(PropEnum)); 
I := 0; 

hr := PropEnum.Next(1, PropStat, nil); 
    while hr = S_OK do 
    begin 
    inc(I); 
    SetLength(PropSpec,I); 
    PropSpec[i-1].ulKind := PRSPEC_PROPID; 
    PropSpec[i-1].propid := PropStat.propid; 
    hr := PropEnum.Next(1, PropStat, nil); 
end; 

SetLength(PropVariant,i); 
Rslt := PropStg.ReadMultiple(i, @PropSpec[0], @PropVariant[0]); 

if Rslt = S_FALSE then Exit; 

for k := 0 to i -1 do 
    begin 
    S := ''; 
    if PropVariant[k].vt = VT_LPSTR then 
     if Assigned(PropVariant[k].pszVal) then 
     S := PropVariant[k].pszVal; 

    S := Format(PropertyPIDToCaption(PropSpec[k].Propid)+ ' %s',[s]); 
    if S <> '' then Result := Result + S + #13; 
end; 
finally 
end; 
end; 

procedure SetFileSummaryInfo(const FileName : WideString; Author, Title, Subject, Keywords, Comments : WideString); 

var 
PropSetStg: IPropertySetStorage; 
PropSpec: array of TPropSpec; 
PropStg: IPropertyStorage; 
PropVariant: array of TPropVariant; 
Stg: IStorage; 

begin 
OleCheck(StgOpenStorageEx(PWideChar(FileName), STGM_SHARE_EXCLUSIVE or STGM_READWRITE, STGFMT_ANY, 0, nil, nil, @IID_IPropertySetStorage, stg)); 
PropSetStg := Stg as IPropertySetStorage; 
OleCheck(PropSetStg.Create(FmtID_SummaryInformation, FmtID_SummaryInformation, PROPSETFLAG_DEFAULT,STGM_CREATE or STGM_READWRITE or STGM_SHARE_EXCLUSIVE, PropStg)); 
Setlength(PropSpec,6); 
PropSpec[0].ulKind := PRSPEC_PROPID; 
PropSpec[0].propid := PID_AUTHOR; 
PropSpec[1].ulKind := PRSPEC_PROPID; 
PropSpec[1].propid := PID_TITLE; 
PropSpec[2].ulKind := PRSPEC_PROPID; 
PropSpec[2].propid := PID_SUBJECT; 
PropSpec[3].ulKind := PRSPEC_PROPID; 
PropSpec[3].propid := PID_KEYWORDS; 
PropSpec[4].ulKind := PRSPEC_PROPID; 
PropSpec[4].propid := PID_COMMENTS; 
PropSpec[5].ulKind := PRSPEC_PROPID; 
PropSpec[5].propid := 99; 

SetLength(PropVariant,6); 
PropVariant[0].vt:=VT_LPWSTR; 
PropVariant[0].pwszVal:=PWideChar(Author); 
PropVariant[1].vt:=VT_LPWSTR; 
PropVariant[1].pwszVal:=PWideChar(Title); 
PropVariant[2].vt:= VT_LPWSTR; 
PropVariant[2].pwszVal:=PWideChar(Subject); 
PropVariant[3].vt:= VT_LPWSTR; 
PropVariant[3].pwszVal:=PWideChar(Keywords); 
PropVariant[4].vt:= VT_LPWSTR; 
PropVariant[4].pwszVal:=PWideChar(Comments); 
PropVariant[5].vt:= VT_LPWSTR; 
PropVariant[5].pwszVal:=PWideChar(Comments); 
OleCheck(PropStg.WriteMultiple(6, @PropSpec[0], @PropVariant[0], 2)); 
PropStg.Commit(STGC_DEFAULT); 
end; 


end. 

Ce n'est pas mon code, mais je l'ont utilisé avec succès. Ça fonctionne bien. Pour récupérer les propriétés que vous pouvez faire:

mmProps2.Lines.Text := GetFileSummaryInfo(edtFile.Text); 

Cordialement


Neftali

0

Je développe une application de marquage en ce moment, et il semble que la meilleure réponse est le Windows Imaging Component API, qui a des implémentations pour lire et écrire des métadonnées pour différents formats d'image (Exif, IPTC, etc.). Une distinction doit être faite entre les métadonnées pour le fichier dans le système de fichiers et les métadonnées dans le fichier lui-même - c'est référencer ce dernier.

Getty Images also has a good article on programming with the WIC API.

Questions connexes