【问题标题】:How to retrieve creation date of an IShellItem?如何检索 IShellItem 的创建日期?
【发布时间】:2013-03-02 17:20:41
【问题描述】:

我有一个文件夹的 pidl(可能存在或已被删除)。

我可以使用以下代码获得IShellItem,但我需要的是获得该文件夹的创建日期。我想我可以通过PKEY_DateCreated 获得它,但我不知道如何。

SHCreateShellItem(nil, nil, pidl, ShellItem);

我该怎么做?

我使用 Delphi。

【问题讨论】:

  • 这不是德尔福问题。这是一个纯 COM shell 问题。
  • 您是否将IShellItem 绑定到IShellFolder2?还是绑定到 PIDL?
  • 经过调查,我改了问题
  • 如果文件夹已被删除,您如何获得任何信息?
  • 外壳项目有创建日期吗?还是只是文件系统对象?

标签: windows winapi windows-shell


【解决方案1】:

如果你有PIDL你可以使用SHGetDataFromIDList来获取对象的基本属性;你根本不需要IShellItem(或IShellItem2)。您可以为 nFormat 参数指定 SHGDFIL_FINDDATA(请参阅SHGetDataFromIDList? 详情)。

这样做的好处是,对于标准文件系统对象,元数据被编码在 PIDL 本身中,因此即使对象不再存在,该函数也会返回有用的数据。

【讨论】:

  • 看起来不错,但我只有一个绝对 pidl,而 SHGetDataFromIDList 需要一个 IShellFolder 和相对 pidl。也许我可以得到它们,但如何?
  • 查看SHBindToParent 函数。您也可以尝试使用桌面文件夹作为其父文件夹(您通过SHGetDesktopFolder 获得)传递绝对值,因为我发现即使它不应该这样做也经常有效。
【解决方案2】:

纯 Winapi 示例:

IShellItem2* pItem2 = NULL;
hr = pItem->QueryInterface(&pItem2);
if (SUCCEEDED(hr))
{
   FILETIME ft = {0};
   pItem2->GetFileTime(PKEY_DateCreated, &ft);
   SYSTEMTIME st = {0};
   ::FileTimeToSystemTime(&ft, &st);
   wprintf(
       L"Date Created: %04d-%02d-%02d %02d:%02d:%02d\n", 
       st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
   pItem2->Release();
}

正如 David Heffernan 指出的那样,您确定 所有 外壳项目都有创建日期吗?

翻译成 Delphi 会是这样的:

var
  Item: IShellItem;
  Item2: IShellItem2;
  ft: TFileTime;
  st: TSystemTime;
....
Item2 := Item as IShellItem2;
OleCheck(Item2.GetFileTime(PKEY_DateCreated, ft));
Win32Check(FileTimeToSystemTime(ft, st));

【讨论】:

  • 很好,但由于 IShellItem2,它在 XP 下不起作用。有什么解决办法吗?
【解决方案3】:

获取创建日期

使用 IShellItem2

IShellItem2 扩展了IShellItem,添加了许多帮助方法来从属性系统中检索类型化的属性。

var
   ft: FILETIME;
   createdDate: TDateTime;

// IShellItem2 provides many handy helper methods to IShellItem
(shellItem as IShellItem2).GetFileTime(PKEY_DateCreated, {out}ft);

createdDate := FileTimeToDateTime(ft);

使用 IShellItem

Windows Vista Windows XP1 添加了IShellItem,将[IShellFolder]+[ITEMID_CHILD] 封装成一个对象。 Windows Vista 增加了丰富的属性系统,IPropertyStore 是一组键值对属性(包括PKEY_DateCreated):

var
   ps: IPropertyStore;
   pv: TPropVariant;
   ft: FILETIME;
   createdDate: TDateTime;

//Get the IPropertyStore yourself, in order to read the property you want
shellItem.BindToHandler(nil, BHID_PropertyStore, IPropertyStore, {out}ps);
ps.GetValue(PKEY_DateCreated, {out}pv);  
PropVariantToFileTime(pv, PSTF_UTC, {out}ft);

createdDate := FileTimeToDateTime(ft);

使用 IShellFolder

IShellFolder 是原来的 Windows 95 界面。它仅代表一个文件夹,您必须询问该文件夹中的项目(ITEMID_CHILD)。 Vista之前没有PKEY_DateCreated,因为属性系统直到 Vista才存在。但文件和文件夹仍然有 CreationTime

var
   folder: IShellFolder;
   parent: PIDLIST_ABSOLUTE;
   child: PITEMID_CHILD;
   findData: WIN32_FIND_DATA;

// We have an IShellItem that represents IShellFolder+ChildItemID. 
// Ask the IShellItem to cough up its IShellFolder and child pidl
(shellItem as IParentAndItem).GetParentAndItem(parent, folder, child);

// Get the WIN32_FIND_DATA information associated with the child file/folder
SHGetDataFromIDList(folder, child, SHGDFIL_FINDDATA, findData, sizeof(findData));

createdDate := FileTimeToDateTime(findData.ftCreationTime);

【讨论】:

  • 虽然 IShellItem 技术上是在 XP SP0 中为资源管理器侧边栏添加的,但在 SP1 或 SP2 之前它不能被第三方代码使用。
猜你喜欢
  • 2021-05-08
  • 1970-01-01
  • 2011-05-26
  • 2015-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
相关资源
最近更新 更多