Access violation when using IShellFolder2
FreeSlave
freeslave93 at gmail.com
Thu Sep 10 13:30:15 UTC 2020
On Thursday, 10 September 2020 at 06:43:35 UTC, John Chapman
wrote:
> On Wednesday, 9 September 2020 at 22:44:50 UTC, FreeSlave wrote:
>> Btw do you know how to parse a date returned by GetDetailsOf?
>> Couldn't find any examples in C++. I actually can see digits
>> representing date and time as a part of the string, but I
>> would prefer to use some winapi function to translate it into
>> some time type instead of manually parsing the result.
>
> You could look at passing the str.pOleStr field in the
> SHELLDETAILS you got from GetDetailsOf to VarDateFromStr. It
> will give you a DATE value that VariantTimeToSystemTime will
> convert to a SYSTEMTIME from which you can get the years,
> months, days etc.
>
> For example:
>
> SHELLDETAILS details;
> GetDetailsOf(pidl, 3, &details);
> DATE date;
> VarDateFromStr(details.str.pOleStr, LOCALE_USER_DEFAULT, 0,
> &date);
> SYSTEMTIME st;
> VariantTimeToSystemTime(date, &st);
> auto year = st.wYear;
> auto month = st.wMonth;
>
> You can convert that into a more D-friendly SysTime object
> using SYSTEMTIMEToSysTime from the std.datetime package.
Thanks. I tried this, but VarDateFromStr does not succeed for me.
Here's the updated example. Note that I use a column 2 to
retrieve the date because that's the deletion date column for
recycle bin folder.
import core.sys.windows.windows;
import core.sys.windows.shlobj;
import core.sys.windows.wtypes;
import core.sys.windows.oaidl;
import std.exception;
import std.datetime;
pragma(lib, "Ole32");
pragma(lib, "OleAut32");
interface IShellFolder2 : IShellFolder {
HRESULT GetDefaultSearchGUID(GUID*);
HRESULT EnumSearches(IEnumExtraSearch*);
HRESULT GetDefaultColumn(DWORD, ULONG*, ULONG*);
HRESULT GetDefaultColumnState(UINT, SHCOLSTATEF*);
HRESULT GetDetailsEx(LPCITEMIDLIST, const(SHCOLUMNID)*,
VARIANT*);
HRESULT GetDetailsOf(LPCITEMIDLIST, UINT, SHELLDETAILS*);
HRESULT MapColumnToSCID(UINT, SHCOLUMNID*);
}
import std.stdio;
static @trusted string StrRetToString(ref scope STRRET strRet)
{
import std.string : fromStringz;
switch (strRet.uType)
{
case STRRET_CSTR:
return fromStringz(strRet.cStr.ptr).idup;
case STRRET_OFFSET:
writeln("STRRET_OFFSET!");
return string.init;
case STRRET_WSTR:
char[MAX_PATH] szTemp;
auto len = WideCharToMultiByte (CP_UTF8, 0,
strRet.pOleStr, -1, szTemp.ptr, szTemp.sizeof, null, null);
scope(exit) CoTaskMemFree(strRet.pOleStr);
if (len)
return szTemp[0..len-1].idup;
else
return string.init;
default:
return string.init;
}
}
static @trusted SysTime StrRetToSysTime(ref scope STRRET strRet)
{
enforce(strRet.uType == STRRET_WSTR, "Expected STRRET_WSTR");
DATE date;
enforce(SUCCEEDED(VarDateFromStr(strRet.pOleStr,
LOCALE_USER_DEFAULT, 0, &date)), "Failed to convert string to
date value");
SYSTEMTIME sysTime;
VariantTimeToSystemTime(date, &sysTime);
return SYSTEMTIMEToSysTime(&sysTime);
}
void main()
{
OleInitialize(null);
scope(exit) OleUninitialize();
IShellFolder desktop;
LPITEMIDLIST pidlRecycleBin;
enforce(SUCCEEDED(SHGetDesktopFolder(&desktop)), "Failed to
get desktop shell folder");
assert(desktop);
scope(exit) desktop.Release();
enforce(SUCCEEDED(SHGetSpecialFolderLocation(null,
CSIDL_BITBUCKET, &pidlRecycleBin)), "Failed to get recycle bin
location");
assert(pidlRecycleBin);
scope(exit) ILFree(pidlRecycleBin);
IShellFolder2 recycleBin;
enforce(SUCCEEDED(desktop.BindToObject(pidlRecycleBin, null,
&IID_IShellFolder2, cast(LPVOID *)&recycleBin)), "Failed to get
recycle bin shell folder");
assert(recycleBin);
scope(exit) recycleBin.Release();
IEnumIDList enumFiles;
with(SHCONTF) enforce(SUCCEEDED(recycleBin.EnumObjects(null,
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN,
&enumFiles)), "Failed to enumerate objects in recycle bin");
scope(exit) enumFiles.Release();
LPITEMIDLIST pidl;
while (enumFiles.Next(1, &pidl, null) != S_FALSE) {
string name;
string originalLocation;
SysTime deletionTime;
SHELLDETAILS details;
if(SUCCEEDED(recycleBin.GetDetailsOf(pidl,0,&details)))
{
name = StrRetToString(details.str);
}
if(SUCCEEDED(recycleBin.GetDetailsOf(pidl,1,&details)))
{
originalLocation = StrRetToString(details.str);
}
if(SUCCEEDED(recycleBin.GetDetailsOf(pidl,2,&details)))
{
deletionTime = StrRetToSysTime(details.str);
}
writefln("Name: %s, original location: %s, datetime: %s",
name, originalLocation, deletionTime);
CoTaskMemFree(pidl);
}
}
More information about the Digitalmars-d-learn
mailing list