プロパティ一覧

手元のVista SP1で、System.*という形のプロパティだけを抜き出して表にしました。
表が横に長すぎるので、Canonical Nameからは、"System."を削っています。そのため、参考にする場合には、System.が必要なことを忘れないでください。

GUID/PID Canonical Name Display Name Type
{65A98875-3C80-40AB-ABBC-EFDAF77DBEE2},100 AcquisitionID - VT_I4
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},18 ApplicationName プログラム名 VT_LPWSTR
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},4 Author 作成者 4127
{9B174B35-40FF-11D2-A27E-00C04FC30871},3 Capacity 合計サイズ VT_UI8
{D5CDD502-2E9C-101B-9397-08002B2CF9AE},2 Category 分類項目 4127
{3F5D9B45-5E9F-4D5C-8A5E-403181BF177B},8 CheckState - VT_UI4
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},6 Comment コメント VT_LPWSTR
{D5CDD502-2E9C-101B-9397-08002B2CF9AE},15 Company 会社 VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},5 ComputerName コンピュータ VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},29 ContainedItems 含まれる内容 4168
{D5CDD502-2E9C-101B-9397-08002B2CF9AE},27 ContentStatus 状態 VT_LPWSTR
{D5CDD502-2E9C-101B-9397-08002B2CF9AE},26 ContentType 内容の種類 VT_LPWSTR
{64440492-4C8B-11D1-8B70-080036B11A03},11 Copyright 著作権 VT_LPWSTR
{B725F130-47EF-101A-A5F1-02608C9EEBAC},16 DateAccessed アクセス日時 VT_FILETIME
{2CBAA8F5-D81F-47CA-B17A-F8D822300131},100 DateAcquired 取得日時 VT_FILETIME
{43F8D7B7-A444-4F87-9383-52271C9B915C},100 DateArchived アーカイブ日時 VT_FILETIME
{72FAB781-ACDA-43E5-B155-B2434F85E678},100 DateCompleted 完了日 VT_FILETIME
{B725F130-47EF-101A-A5F1-02608C9EEBAC},15 DateCreated 作成日時 VT_FILETIME
{14B81DA1-0135-4D31-96D9-6CBFC9671A99},18258 DateImported インポート日時 VT_FILETIME
{B725F130-47EF-101A-A5F1-02608C9EEBAC},14 DateModified 更新日時 VT_FILETIME
{28636AA6-953D-11D2-B5D6-00C04FD918D0},32 DelegateIDList - VT_NULL
{28636AA6-953D-11D2-B5D6-00C04FD918D0},2 DescriptionID - 4113
{3F8472B5-E0AF-4DB2-8071-C53FE76AE7CE},100 DueDate 期限 VT_FILETIME
{EA810849-87FF-4B54-ABD6-5B71ADF466F8},1 DuiControlResource - VT_UI4
{C75FAA05-96FD-49E7-9CB4-9F601082D553},100 EndDate 終了日 VT_FILETIME
{B725F130-47EF-101A-A5F1-02608C9EEBAC},18 FileAllocationSize ディスク上のサイズ VT_UI8
{B725F130-47EF-101A-A5F1-02608C9EEBAC},13 FileAttributes 属性 VT_UI4
{8D72ACA1-0716-419A-9AC1-ACB07B18DC32},2 FileAttributesDisplay - VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},12 FileCount ファイル数 VT_UI8
{0CEF7D53-FA64-11D1-A203-0000F81FEDEE},3 FileDescription ファイルの説明 VT_LPWSTR
{E4F10A3C-49E6-405D-8288-A23BD4EEAA6C},100 FileExtension ファイル拡張子 VT_LPWSTR
{B725F130-47EF-101A-A5F1-02608C9EEBAC},21 FileFRN - VT_UI8
{B725F130-47EF-101A-A5F1-02608C9EEBAC},8 FileIndex - VT_UI8
{41CF5AE0-F75A-4806-BD87-59C7D9248EB9},100 FileName ファイル名 VT_LPWSTR
{9B174B34-40FF-11D2-A27E-00C04FC30871},4 FileOwner 所有者 VT_LPWSTR
{3D75E4F5-A391-4952-81F7-C7072FE53025},100 FileReparsePointTag - VT_UI4
{0CEF7D53-FA64-11D1-A203-0000F81FEDEE},4 FileVersion ファイル バージョン VT_LPWSTR
{1E3EE840-BC2B-476C-8237-2ACD1A839B22},2 FilterInfo - VT_STREAM
{28636AA6-953D-11D2-B5D6-00C04FD918D0},0 FindData - 4113
{67DF94DE-0CA7-4D6F-B792-053A3E4F03CF},100 FlagColor フラグの色 VT_UI2
{45EAE747-8E2A-40AE-8CBF-CA52ABA6152A},100 FlagColorText - VT_LPWSTR
{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD},12 FlagStatus フラグの状態 VT_I4
{DC54FD2E-189D-4871-AA01-08C2F57A4ABC},100 FlagStatusText - VT_LPWSTR
{1173F62A-2A55-4F62-AED6-8C7112E0F7A3},5 ForceFullText - VT_LPWSTR
{9B174B35-40FF-11D2-A27E-00C04FC30871},2 FreeSpace 空き領域 VT_UI8
{1E3EE840-BC2B-476C-8237-2ACD1A839B22},6 FullText - VT_LPWSTR
{C6F039E7-F6A4-4185-AE48-07938262C274},1 HideInGrepSearch - VT_BOOL
{28636AA6-953D-11D2-B5D6-00C04FD918D0},34 HideOnDesktop - VT_BOOL
{5CBF2787-48CF-4208-B90E-EE5E5D420294},26 IconIndex - VT_I4
{5CBF2787-48CF-4208-B90E-EE5E5D420294},25 IconPath - VT_LPWSTR
{A26F4AFC-7346-4299-BE47-EB1AE613139F},100 Identity ID VT_LPWSTR
{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD},11 Importance 重要度 VT_I4
{A3B29791-7713-4E1D-BB40-17DB85F01831},100 ImportanceText - VT_LPWSTR
{0CEF7D53-FA64-11D1-A203-0000F81FEDEE},5 InternalName 内部名 VT_LPWSTR
{F23F425C-71A1-4FA8-922F-678EA4A60408},100 IsAttachment 添付 VT_BOOL
{5CDA5FC8-33EE-4FF3-9094-AE7BD8868C4D},100 IsDeleted 削除 VT_BOOL
{90E5E14E-648B-4826-B2AA-ACAF790E3513},10 IsEncrypted 暗号化の状態 VT_BOOL
{5DA84765-E3FF-4278-86B0-A27967FBDD03},100 IsFlagged フラグの有無 VT_BOOL
{A6F360D2-55F9-48DE-B909-620E090A647C},100 IsFlaggedComplete 終了済 VT_BOOL
{346C8BD1-2E6A-4C45-89A4-61B78E8E700F},100 IsIncomplete 未完了 VT_BOOL
{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD},10 IsRead 開封の状態 VT_BOOL
{28636AA6-953D-11D2-B5D6-00C04FD918D0},33 IsSendToTarget - VT_BOOL
{EF884C5B-2BFE-41BB-AAE5-76EEDF4F9902},100 IsShared 共有 VT_BOOL
{B9B4B3FC-2B51-4A42-B5D8-324146AFCF25},6 ItemAfter - VT_NULL
{D0A04F0A-462A-48A4-BB2F-3706E88DBD7D},100 ItemAuthors 製作者 4127
{F7DB74B4-4287-4103-AFBA-F1B13DCD75CF},100 ItemDate 日付 VT_FILETIME
{B725F130-47EF-101A-A5F1-02608C9EEBAC},2 ItemFolderNameDisplay フォルダ名 VT_LPWSTR
{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD},6 ItemFolderPathDisplay フォルダのパス VT_LPWSTR
{DABD30ED-0043-4789-A7F8-D013A4736622},100 ItemFolderPathDisplayNarrow フォルダ VT_LPWSTR
{1E3EE840-BC2B-476C-8237-2ACD1A839B22},8 ItemId - VT_NULL
{1E3EE840-BC2B-476C-8237-2ACD1A839B22},4 ItemKey - VT_NULL
{6B8DA074-3B5C-43BC-886F-0A2CDCE00B6F},100 ItemName - VT_LPWSTR
{B725F130-47EF-101A-A5F1-02608C9EEBAC},10 ItemNameDisplay 名前 VT_LPWSTR
{D7313FF1-A77A-401C-8C99-3DBDD68ADD36},100 ItemNamePrefix - VT_LPWSTR
{D4D0AA16-9948-41A4-AA85-D97FF9646993},100 ItemParticipants 参加者 4127
{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD},7 ItemPathDisplay パス VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},8 ItemPathDisplayNarrow パス VT_LPWSTR
{1E3EE840-BC2B-476C-8237-2ACD1A839B22},10 ItemSourceCLSID - VT_CLSID
{28636AA6-953D-11D2-B5D6-00C04FD918D0},11 ItemType 種類 VT_LPWSTR
{B725F130-47EF-101A-A5F1-02608C9EEBAC},4 ItemTypeText 種類 VT_LPWSTR
{49691C90-7E17-101A-A91C-08002B2ECDA9},9 ItemUrl - VT_LPWSTR
{1E3EE840-BC2B-476C-8237-2ACD1A839B22},7 ItemsInStack - VT_NULL
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},5 Keywords タグ 4127
{1E3EE840-BC2B-476C-8237-2ACD1A839B22},3 Kind 分類 4127
{F04BEF95-C585-4197-A2B7-DF46FDC9EE6D},100 KindText - VT_LPWSTR
{D5CDD502-2E9C-101B-9397-08002B2CF9AE},28 Language 言語 VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},23 ListDescription - VT_UI8
{0B63E350-9CCC-11D0-BCDB-00805FCCCE04},5 MIMEType - VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},22 MaxStackCount - VT_UI8
{FDF84370-031A-4ADD-9E91-0D775F1C6605},100 MileageInformation 経費情報 VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},4 NetworkLocation ネットワークの場所 VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},35 NetworkPlacesDefaultName - VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},31 NetworkProvider - VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},1 NetworkResource - VT_NULL
{9B174B34-40FF-11D2-A27E-00C04FC30871},10 NewMenuAllowedTypes - VT_LPWSTR
{9B174B34-40FF-11D2-A27E-00C04FC30871},8 NewMenuPreferredTypes - VT_LPWSTR
{A94688B6-7D9F-4570-A648-E3DFC0AB2B3F},100 OfflineAvailability オフラインで利用可能 VT_UI4
{6D24888F-4718-4BDA-AFED-EA0FB4386CD8},100 OfflineStatus オフラインの状態 VT_UI4
{4E9CFC01-5D36-406A-83CD-4E7423923604},2 OfflineSyncTime - VT_FILETIME
{28636AA6-953D-11D2-B5D6-00C04FD918D0},26 Order 順序 VT_I4
{0CEF7D53-FA64-11D1-A203-0000F81FEDEE},6 OriginalFileName 元のファイル名 VT_LPWSTR
{64440492-4C8B-11D1-8B70-080036B11A03},21 ParentalRating 保護者による制限 VT_LPWSTR
{10984E0A-F9F2-4321-B7EF-BAF195AF4319},100 ParentalRatingReason 保護者による制限の理由 VT_LPWSTR
{A7FE0840-1344-46F0-8D37-52ED712A4BF9},100 ParentalRatingsOrganization 保護者による制限の組織 VT_LPWSTR
{DFB9A04D-362F-4CA3-B30B-0254B17B5B84},100 ParsingBindContext - VT_NULL
{28636AA6-953D-11D2-B5D6-00C04FD918D0},24 ParsingName - VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},30 ParsingPath - VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},9 PerceivedType 認識された種類 VT_I4
{9B174B35-40FF-11D2-A27E-00C04FC30871},5 PercentFull 使用領域 VT_UI4
{0CEF7D53-FA64-11D1-A203-0000F81FEDEE},11 Platform プラットフォーム VT_LPWSTR
{9C1FCF74-2D97-41BA-B4AE-CB2E3661A6E4},5 Priority 優先度 VT_UI2
{D98BE98B-B86B-4095-BF52-9D23B2E0A752},100 PriorityText - VT_LPWSTR
{39A7F922-477C-48DE-8BC8-B28441E342E3},100 Project プロジェクト VT_LPWSTR
{F21D9941-81F0-471A-ADEE-4E74B49217ED},100 ProviderItemID - VT_LPWSTR
{64440492-4C8B-11D1-8B70-080036B11A03},9 Rating 評価 VT_UI4
{90197CA7-FD8F-4E8C-9DA3-B57E1E609295},100 RatingText - VT_LPWSTR
{B725F130-47EF-101A-A5F1-02608C9EEBAC},2147483650 SDID - VT_UI4
{28636AA6-953D-11D2-B5D6-00C04FD918D0},25 SFGAOFlags - VT_UI4
{F8D3F6AC-4874-42CB-BE59-AB454B30716A},100 Sensitivity 秘密度 VT_UI2
{D0C7F054-3F72-4725-8527-129A577CB269},100 SensitivityText - VT_LPWSTR
{64440492-4C8B-11D1-8B70-080036B11A03},12 ShareUserRating 共有ユーザーの評価 VT_UI4
{EF884C5B-2BFE-41BB-AAE5-76EEDF4F9902},200 SharedWith 共有ユーザー 4127
{A09F084E-AD41-489F-8076-AA5BE3082BCA},100 SimpleRating - VT_UI4
{B725F130-47EF-101A-A5F1-02608C9EEBAC},12 Size サイズ VT_UI8
{14B81DA1-0135-4D31-96D9-6CBFC9671A99},305 SoftwareUsed 作成ソフトウェア VT_LPWSTR
{668CDFA5-7A1B-4323-AE4B-E527393A1D81},100 SourceItem ソース VT_LPWSTR
{48FD6EC8-8A12-4CDF-A03E-4EC5A511EDDE},100 StartDate 開始日 VT_FILETIME
{000214A1-0000-0000-C000-000000000046},9 Status 状態 VT_LPWSTR
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},3 Subject 表題 VT_LPWSTR
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},17 Thumbnail - 71
{446D16B1-8DAD-4870-A748-402EA43D788C},100 ThumbnailCacheId - VT_UI8
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},27 ThumbnailStream - VT_STREAM
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},2 Title タイトル VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},14 TotalFileSize 総ファイル サイズ VT_UI8
{0CEF7D53-FA64-11D1-A203-0000F81FEDEE},9 Trademarks 商標 VT_LPWSTR
{5CBF2787-48CF-4208-B90E-EE5E5D420294},4 UrlHostName - VT_LPWSTR
{5CBF2787-48CF-4208-B90E-EE5E5D420294},3 UrlScheme URL スキーマ VT_LPWSTR
{54B3A473-59AA-445B-AECD-77541BA8B7C9},3 UserDisplayName - VT_LPWSTR
{54B3A473-59AA-445B-AECD-77541BA8B7C9},2 UserName - VT_LPWSTR
{54B3A473-59AA-445B-AECD-77541BA8B7C9},5 UserProfilePath - VT_LPWSTR
{28636AA6-953D-11D2-B5D6-00C04FD918D0},3 WhichFolder - VT_LPWSTR
{1E3EE840-BC2B-476C-8237-2ACD1A839B22},5 WordWheel 文字列 VT_LPWSTR

Vista/XPのプロパティシステムで使えるプロパティ

Windows VistaやXP SP2では、Windows Searchをはじめとする各種アプリケーションで、共通のプロパティシステムがある。このシステムには、IPropertySystem経由でアクセスできる。また、XMLベースのProperty Description Schemaを利用すれば、プログラマが自由に拡張することも出来る。

これらのプロパティは、通常、GUID+PIDの組み合わせで判別され、それとは別にCanonical Name(正規名)とDisplay Name(表示名)を持っている。たとえば、

GUID/PID Canonical Name Display Name
{F29F85E0-4FF9-1068-AB91-08002B27B3D9},2 System.Title タイトル

となっている。また、Canonical NameとGUID/PIDは相互に変換可能(PSGetNameFromPropertyKeyや、PSGetPropertyKeyFromName)なので、どちらか片方が分かれば、プロパティを識別することは可能だ。ただし、Canonical Nameはない場合もある。

下記のプログラムはこのプロパティ一覧を取得するプログラム。

// enumproptypes.cpp
#include <windows.h>
#include <initguid.h>
#include <propsys.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <stdexcept>

#include "atlbase.h"
#include "atlcom.h"
#include "atlstr.h"

#define TOF(expr) do {HRESULT hr = expr; if(FAILED(hr)) {CStringA s; s.Format("%s(%d): HR=0x%08X: %s", __FILE__, __LINE__, hr, #expr); throw std::runtime_error((const char*)s);}} while(0)

static CStringW GetVTStr(VARTYPE vt)
{
#define VTDEF_ENTRY(a) {#a, a},
  static const struct VTDEF {const char* name; VARTYPE vt;} tbl[] = {
  VTDEF_ENTRY(VT_NULL)
  VTDEF_ENTRY(VT_LPWSTR)
  VTDEF_ENTRY(VT_BOOL)
  VTDEF_ENTRY(VT_UI1)
  VTDEF_ENTRY(VT_I2)
  VTDEF_ENTRY(VT_UI2)
  VTDEF_ENTRY(VT_I4)
  VTDEF_ENTRY(VT_UI4)
  VTDEF_ENTRY(VT_I8)
  VTDEF_ENTRY(VT_UI8)
  VTDEF_ENTRY(VT_R8)
  VTDEF_ENTRY(VT_FILETIME)
  VTDEF_ENTRY(VT_CLSID)
  VTDEF_ENTRY(VT_BLOB)
  VTDEF_ENTRY(VT_UNKNOWN)
  VTDEF_ENTRY(VT_STREAM)
  {NULL, 0}};
#undef VTDEF_ENTRY
  for(size_t i = 0; tbl[i].name != NULL; i++)
    if(tbl[i].vt == vt)
      return tbl[i].name;
  
  CStringW ret;
  ret.Format(L"%u", vt);
  return ret;
}

static size_t GetLevel(LPCWSTR propName)
{
  size_t lev = 0;
  while(propName = wcschr(propName, '.'))
  {
    propName++;
    lev++;
  }
  return lev;
}

int wmain(int argc, wchar_t* argv[])
{
  setlocale(LC_ALL, "");
  CoInitialize(NULL);

  try
  {
    CComPtr<IPropertySystem> propSys;
    TOF(propSys.CoCreateInstance(CLSID_PropertySystem));
    
    CComPtr<IPropertyDescriptionList> pdl;
    TOF(propSys->EnumeratePropertyDescriptions(
      PDEF_ALL,
      __uuidof(IPropertyDescriptionList),
      (void**)&pdl));
    
    UINT count = 0;
    TOF(pdl->GetCount(&count));
    for(UINT i = 0; i < count; i++)
    {
      CComPtr<IPropertyDescription> pd;
      if(FAILED(pdl->GetAt(i, IID_IPropertyDescription, (void**)&pd)))
        continue;
      
      VARTYPE type = VT_NULL;
      if(FAILED(pd->GetPropertyType(&type)))
        continue;
      
      LPWSTR cname = NULL;
      pd->GetCanonicalName(&cname);
      if(GetLevel(cname) == 1)
      {
        PROPERTYKEY key;
        pd->GetPropertyKey(&key);
        LPWSTR clsid;
        StringFromCLSID(key.fmtid, &clsid);
        
        LPWSTR dname = NULL;
        pd->GetDisplayName(&dname);
        wprintf(L"%s,%u\t%s\t%s\t%s\n", clsid, key.pid, cname, dname, GetVTStr(type));
        CoTaskMemFree(dname);
        CoTaskMemFree(clsid);
      }
      CoTaskMemFree(cname);
    }
  }
  catch(std::exception& e)
  {
    fprintf(stderr, "%s\n", e.what());
  }
  CoUninitialize();
  return 0;
}

ファイルに関連づけられたプロパティ

また、ファイルなどに対して関連づけられたプロパティは、IShellItem2::GetPropertyStoreで取得できる。

下記のコードは、ファイルに関連づけられたプロパティ一覧を表示する物。

// listprops.cpp
#include <windows.h>
#include <initguid.h>
#include <propsys.h>
#include <propvarutil.h>
#include <shobjidl.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <stdexcept>

#include "atlbase.h"
#include "atlcom.h"
#include "atlstr.h"

#pragma comment(lib, "propsys.lib")

#define TOF(expr) do {HRESULT hr = expr; if(FAILED(hr)) {CStringA s; s.Format("%s(%d): HR=0x%08X: %s", __FILE__, __LINE__, hr, #expr); throw std::runtime_error((const char*)s);}} while(0)

static CStringW getKeyFromPROPERTYKEY(REFPROPERTYKEY key)
{
  CStringW keyStr;
  PWSTR name = NULL;
  if(SUCCEEDED(PSGetNameFromPropertyKey(key, &name)))
  {
    keyStr = name;
  }
  else
  {
    StringFromCLSID(key.fmtid, &name);
    keyStr.Format(L"%s,%u", name, key.pid);
  }
  if(name)
    CoTaskMemFree(name);
  return keyStr;
}

int wmain(int argc, wchar_t* argv[])
{
  if(argc != 2)
  {
    printf("props FILENAME\n");
    return 0;
  }
  
  setlocale(LC_ALL, "");
  CoInitialize(NULL);
  
  try
  {
    CComPtr<IShellItem2> si2;
    TOF(SHCreateItemFromParsingName(
      argv[1], NULL, __uuidof(IShellItem2), (void**)&si2));
    
    CComPtr<IPropertyStore> ps;
    TOF(si2->GetPropertyStore(
      GPS_DEFAULT, __uuidof(IPropertyStore), (void**)&ps));
    
    DWORD count = 0;
    TOF(ps->GetCount(&count));
    for(DWORD i = 0; i < count; i++)
    {
      PROPERTYKEY key;
      if(FAILED(ps->GetAt(i, &key)))
        continue;
      
      CStringW keyName = getKeyFromPROPERTYKEY(key);
      
      PROPVARIANT pv;
      PropVariantInit(&pv);
      if(FAILED(ps->GetValue(key, &pv)))
        continue;
      
      PWSTR pstr = NULL;
      if(SUCCEEDED(PropVariantToStringAlloc(pv, &pstr)) || pstr)
      {
        wprintf(L"%s=\"%s\"\n", keyName, pstr);
        CoTaskMemFree(pstr);
      }
      
      PropVariantClear(&pv);
    }
  }
  catch(std::exception& e)
  {
    fprintf(stderr, "%s\n", e.what());
  }
  CoUninitialize();
  return 0;

}

使い方は、簡単で、

listprops filename.pdf

のように使う。

内部格納形式

当然ながら、ファイルによってプロパティの保存のされ方は異なる。XMPによって管理されているかもしれないし、EXIFかもしれないし、独自形式かもしれない。ただ、一般的には、プロパティといわれる物は、通常、テキスト形式であることが多い。
XML形式で格納するならば、どうにかしてテキストで保存せざるを得ない。

ところが、Windowsのプロパティは、PROPVARIANTという非常にありがたくない形式で交換される。平たく言うと、何でも入る入れ物。これを自分でテキストに変換しなさいと言われても正直困るよというぐらいの代物。

幸いというか、当然というか、Vista/XPのプロパティシステムでは、プログラマが使っても良い、任意のPROPVARIANTを文字列に変換したり、その逆をやったりする関数がやっと提供されることになった。PropVariantToStringAllocInitPropVariantFromStringだ。

一つ目の関数、PropVariantToStringAllocは、すでに上のコードで利用しているが、任意のPROPVARIANTを文字列に変換してくれる。返された領域はCoTaskMemFreeで解放する。

こっちは簡単。

不思議なのは逆方向。InitPropVariantFromStringという関数。たとえば、

2008/11/19:11:15:08.000

というテキストがあっても、本来、これをVT_LPWSTR(テキスト)として認識するか、あるいは、VT_FILETIMEとして認識するかは非常に難しい。ユーザーがどちらを望んでいるのかは分からないからだ。実際、この関数は、そこまでの処理はしてくれない。せいぜい、数値が数値として認識される程度だ。

PROPERTYKEYに対する正規化

そこで、登場するのが、PSCoerceToCanonicalValue関数。この関数は、第一引数にPROPERTYKEYを受け取る。それによって、PROPVARIANTの中身をごにょごにょしてくれる。

// "2008/11/19:11:15:08.000" は、VT_LPWSTRとして処理される
PROPVARIANT pv;
InitPropVariantFromString(L"2008/11/19:11:15:08.000", &pv);

// "System.DateModified" ですよと教えると、VT_FILETIMEに変換される
PROPERTYKEY key;
PSGetPropertyKeyFromName(L"System.DateModified", &key);
PSCoerceToCanonicalValue(key, &pv);

...

PropVariantClear(&pv);

しかし、この関数、内部でいろいろやり過ぎているようで、本当のところ、何をやっているのかは不明。良きに計らってくれていることを祈るしかなさそう。ただ、タイムスタンプの認識に関しては、完全に、2008/11/19:11:15:08.000以外の形式は認めてくれないらしい。できれば、RFC3339ぐらい許容して欲しいところなんだけど・・・。