Original Post
I'm trying to use shell32.dll in my app to navigate through the "My Computer" and "Desktop" folders and others, but I can't seem to figure out what's causing the error. I get an access violation when I call the BindToObject function and another one when I try to use this to get the SHITEMID struct: Here's what I was trying to copy: http://www.swissdelphicenter.ch/en/showcode.php?id=1598
Object obj0 = Marshal.GetTypedObjectForIUnknown(pidl, SHITEMIDtype);
SHITEMID itemStruct = obj0; I assume it's because it's not an object, but I don't know how to convert an intptr to a struct. Does anyone have any experience with this? I can send the code where I import the dll, but it seemed like was a lot to post at once. Also, I'd been trying to only include the functions I make use of. I don't know if that would make any difference. // Folder list stuff:
System.Type tShellFolderType = System.Type.GetType("AMF.IShellFolder");
IntPtr pDeskTopFolder;
Shell32.SHGetDesktopFolder(out pDeskTopFolder);
Object obj1 = Marshal.GetTypedObjectForIUnknown(pDeskTopFolder, tShellFolderType);
IShellFolder DeskTopFolder = (IShellFolder)obj1;
IntPtr pidl;
Shell32.SHGetSpecialFolderLocation(IntPtr.Zero, (short)Shell32.CSIDL.CSIDL_DRIVES, out pidl);
// Shell32.SHGetFolderLocation(IntPtr.Zero, (short)Shell32.CSIDL.CSIDL_WINDOWS, IntPtr.Zero, 0, out pidl);
IMalloc pMalloc = ShellFunctions.GetMalloc();
System.Type SHITEMIDtype = System.Type.GetType("AMF.SHITEMID");
// Get the parent of the desktop?
IntPtr pMyComputerFolder;
Guid IID_IShellFolder = new Guid("000214E6-0000-0000-C000-000000000046");
// ACCESS VIOLATION HERE
DeskTopFolder.BindToObject(pidl, IntPtr.Zero, IID_IShellFolder, out pMyComputerFolder);
Object obj2 = Marshal.GetTypedObjectForIUnknown(pMyComputerFolder, tShellFolderType);
IShellFolder MyComputerFolder = (IShellFolder)obj2;
System.Type tEnumIDListType = System.Type.GetType("AMF.IEnumIDList");
IntPtr pEnumIdList;
MyComputerFolder.EnumObjects(IntPtr.Zero, (int) Shell32.SHCONTF.SHCONTF_FOLDERS, out pEnumIdList);
Object obj3 = Marshal.GetTypedObjectForIUnknown(pEnumIdList, tEnumIDListType);
IEnumIDList EnumIDList = (IEnumIDList)obj3;
uint pceltFetched = 0xFFFFFFFF;
Shell32.STRRET lpName;
String name = "";
// Object obj0 = Marshal.GetTypedObjectForIUnknown(pidl, SHITEMIDtype);
SHITEMID itemStruct = new SHITEMID(); // (SHITEMID)obj0;
do
{
EnumIDList.Next(1, ref itemStruct, ref pceltFetched);
if (pceltFetched == 0) continue;
MyComputerFolder.GetDisplayNameOf(pidl, (uint)Shell32.SHGNO.SHGDN_FORPARSING, out lpName);
name = (string) Marshal.GetTypedObjectForIUnknown(lpName.pOleStr, name.GetType());
}
while (pceltFetched != 0);
// Get the path from a PIDL
// System.Text.StringBuilder path2 = new System.Text.StringBuilder(256);
// Shell32.SHGetPathFromIDList(pidl, path2);
// MessageBox.Show(path2.ToString());
// Get the special folder path directly (without getting its PIDL)
// System.Text.StringBuilder path = new System.Text.StringBuilder(256);
// Shell32.SHGetFolderPath(IntPtr.Zero, (short)Shell32.CSIDL.CSIDL_WINDOWS, IntPtr.Zero, (uint)Shell32.SHGFP_TYPE.SHGFP_TYPE_CURRENT, path);
// MessageBox.Show(path.ToString());
if (pidl != IntPtr.Zero)
{
pMalloc.Free(pidl);
}
if (pDeskTopFolder != IntPtr.Zero)
{
pMalloc.Free(pDeskTopFolder);
}
/*if (pMyComputerFolder != IntPtr.Zero)
{
pMalloc.Free(pMyComputerFolder);
}*/
System.Runtime.InteropServices.Marshal.ReleaseComObject(pMalloc);