public void GetPidlForSpecialFolderPath() { string originalPath = null; IntPtr pidl = default(IntPtr), ptrPath = default(IntPtr); try { using (var kfn = KnownFolderHelper.FromKnownFolderGuid(new Guid(KF_ID.ID_FOLDERID_Windows))) { pidl = kfn.KnownFolderToPIDL(); kfn.Obj.GetPath(0, out ptrPath); Assert.IsTrue(ptrPath != default(IntPtr)); originalPath = Marshal.PtrToStringUni(ptrPath); } Assert.IsFalse(string.IsNullOrEmpty(originalPath)); string logicalPath = PidlManager.GetPathFromPIDL(pidl); string physStorePath = PidlManager.GetPathFromPIDL(pidl, TypOfPath.PhysicalStoragePath); Assert.IsTrue(string.Equals(originalPath, physStorePath, StringComparison.InvariantCultureIgnoreCase)); Assert.IsFalse(string.Equals(logicalPath, physStorePath)); ////Console.WriteLine("Path Retrieval via PIDL:'{0}' ->\nLogical Path: '{1}', Physical Path: '{2}'", //// originalPath, logicalPath, physStorePath); } finally { pidl = PidlManager.ILFree(pidl); ptrPath = PidlManager.FreeCoTaskMem(ptrPath); } }
/// <summary> /// Retrieves the physical path of a known folder as a string or null /// if the special folder has no physical representation in the file system. /// /// https://msdn.microsoft.com/en-us/library/windows/desktop/bb761762(v=vs.85).aspx /// </summary> public string GetPath() { if (Obj == null) { throw new System.ArgumentException("Native IKnownFolder cannot be null."); } IntPtr ptrPath = default(IntPtr); try { Obj.GetPath(0, out ptrPath); return(Marshal.PtrToStringUni(ptrPath)); } catch { // Some special folders may not have a file system path return(null); } finally { ptrPath = PidlManager.FreeCoTaskMem(ptrPath); } }
public void GetLogicalLocationForDesktopParentOf() { var testitem = KF_IID.ID_FOLDERID_ComputerFolder; IdList parentIdList = null, relativeChild = null; var retVal = PidlManager.GetParentIdListFromPath(testitem, out parentIdList, out relativeChild); Assert.IsTrue(relativeChild != null); Assert.IsTrue(relativeChild.Size == 1); Assert.IsTrue(retVal == true); Assert.IsFalse(parentIdList == null); Assert.IsTrue(parentIdList.Size == 0); // An empty list represents the desktop IntPtr parentPIDL = PidlManager.IdListToPidl(IdList.Create(parentIdList.Ids)); try { Assert.IsFalse(parentPIDL == default(IntPtr)); string path = PidlManager.GetPathFromPIDL(parentPIDL); Assert.IsFalse(string.IsNullOrEmpty(path)); Assert.IsFalse(testitem.Equals(path, StringComparison.InvariantCultureIgnoreCase)); // The expected parent of 'This PC' is the 'Desktop' Assert.IsTrue(path.Equals(KF_IID.ID_FOLDERID_Desktop, StringComparison.InvariantCultureIgnoreCase)); // this works for display name return PidlManager.GetPidlDisplayName(parentPIDL); } finally { parentPIDL = PidlManager.FreeCoTaskMem(parentPIDL); } }
public void GetStorageLocationForSpecialFolderParent() { string originalPath = null; IntPtr ptrPath = default(IntPtr); try { using (var kfn = KnownFolderHelper.FromKnownFolderGuid(new Guid(KF_ID.ID_FOLDERID_Windows))) { kfn.Obj.GetPath(0, out ptrPath); Assert.IsTrue(ptrPath != default(IntPtr)); originalPath = Marshal.PtrToStringUni(ptrPath); } Assert.IsFalse(string.IsNullOrEmpty(originalPath)); string testFolder = System.IO.Path.Combine(originalPath, "System32"); Assert.IsTrue(System.IO.Directory.Exists(testFolder)); IdList parentIdList = null, relativeChild = null; var retVal = PidlManager.GetParentIdListFromPath(testFolder, out parentIdList, out relativeChild); Assert.IsTrue(relativeChild != null); Assert.IsTrue(relativeChild.Size == 1); IntPtr parentPIDL = PidlManager.IdListToPidl(IdList.Create(parentIdList.Ids)); try { Assert.IsFalse(parentPIDL == default(IntPtr)); string path = PidlManager.GetPathFromPIDL(parentPIDL); Assert.IsTrue(retVal == true); Assert.IsFalse(parentIdList == null); // Expectation: Should display a path like 'C:\' or special folder path Assert.IsFalse(string.IsNullOrEmpty(testFolder)); Assert.IsFalse(testFolder.Equals(path, StringComparison.InvariantCultureIgnoreCase)); // The expected parent of a drive is 'This PC' Assert.IsTrue(path.Equals(KF_IID.ID_FOLDERID_Windows, StringComparison.InvariantCultureIgnoreCase)); } finally { parentPIDL = PidlManager.FreeCoTaskMem(parentPIDL); } } finally { ptrPath = PidlManager.FreeCoTaskMem(ptrPath); } }
public void GetLogicalLocationForThisPCParentOf() { // Get the default drive's path var drive = new DirectoryInfo(Environment.SystemDirectory).Root.Name; Assert.IsFalse(string.IsNullOrEmpty(drive)); var list = new List <string>(); list.Add(drive); list.Add(KF_IID.ID_FOLDERID_Documents); list.Add(KF_IID.ID_FOLDERID_Music); list.Add(KF_IID.ID_FOLDERID_Downloads); list.Add(KF_IID.ID_FOLDERID_Pictures); list.Add(KF_IID.ID_FOLDERID_Videos); foreach (var testFolder in list) { IdList parentIdList = null, relativeChild = null; var retVal = PidlManager.GetParentIdListFromPath(testFolder, out parentIdList, out relativeChild); Assert.IsTrue(relativeChild != null); Assert.IsTrue(relativeChild.Size == 1); Assert.IsTrue(retVal == true); Assert.IsFalse(parentIdList == null); IntPtr parentPIDL = PidlManager.IdListToPidl(IdList.Create(parentIdList.Ids)); try { Assert.IsFalse(parentPIDL == default(IntPtr)); string path = PidlManager.GetPathFromPIDL(parentPIDL); // Expectation: Should display a path like 'C:\' or special folder path Assert.IsFalse(string.IsNullOrEmpty(path)); Assert.IsFalse(testFolder.Equals(path, StringComparison.InvariantCultureIgnoreCase)); // The expected parent of a drive is 'This PC' Assert.IsTrue(path.Equals(KF_IID.ID_FOLDERID_ComputerFolder, StringComparison.InvariantCultureIgnoreCase)); // this works for display name return PidlManager.GetPidlDisplayName(parentPIDL); } finally { parentPIDL = PidlManager.FreeCoTaskMem(parentPIDL); } } }
public void CanEnumerateDesktopFolders() { // Defines the type of items that we want to retieve below the desktop root item const SHCONTF flags = SHCONTF.NONFOLDERS | SHCONTF.FOLDERS | SHCONTF.INCLUDEHIDDEN; // Get the desktop root folder. IntPtr ptrDesktopFolder = default(IntPtr); IntPtr enumerator = default(IntPtr); IShellFolder2 iDesktopFolder = null; // Enumerate over children of given shell folder item using this interface // https://msdn.microsoft.com/en-us/library/windows/desktop/bb761983(v=vs.85).aspx IEnumIDList enumIDs = null; try { HRESULT hr = NativeMethods.SHGetDesktopFolder(out ptrDesktopFolder); Assert.IsTrue(hr == HRESULT.S_OK); if (ptrDesktopFolder != IntPtr.Zero) { iDesktopFolder = (IShellFolder2)Marshal.GetTypedObjectForIUnknown(ptrDesktopFolder, typeof(IShellFolder2)); } Assert.IsTrue(iDesktopFolder != null); // Create an enumerator and enumerate over each item. hr = iDesktopFolder.EnumObjects(IntPtr.Zero, flags, out enumerator); Assert.IsTrue(hr == HRESULT.S_OK); // Convert enum IntPtr to interface enumIDs = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(enumerator, typeof(IEnumIDList)); Assert.IsTrue(enumIDs != null); uint fetched, count = 0; IntPtr apidl = default(IntPtr); // Get one item below desktop root at a time and process by getting its display name for (; enumIDs.Next(1, out apidl, out fetched) == HRESULT.S_OK; count++) { if (fetched <= 0) // End this loop if no more items are available { break; } IntPtr ptrStr = default(IntPtr); // get strings for this item try { string displayName = null, parseName = null; ptrStr = Marshal.AllocCoTaskMem(NativeMethods.MAX_PATH * 2 + 4); Marshal.WriteInt32(ptrStr, 0, 0); StringBuilder buf = new StringBuilder(NativeMethods.MAX_PATH); // The apidl ITEMIDLIST structures returned in the array are relative to // the IShellFolder being enumerated. if (iDesktopFolder.GetDisplayNameOf(apidl, SHGDNF.SHGDN_NORMAL, ptrStr) == HRESULT.S_OK) { NativeMethods.StrRetToBuf(ptrStr, ptrDesktopFolder, buf, NativeMethods.MAX_PATH); displayName = buf.ToString(); } if (iDesktopFolder.GetDisplayNameOf(apidl, SHGDNF.SHGDN_FORPARSING, ptrStr) == HRESULT.S_OK) { NativeMethods.StrRetToBuf(ptrStr, ptrDesktopFolder, buf, NativeMethods.MAX_PATH); parseName = buf.ToString(); } Assert.IsFalse(string.IsNullOrEmpty(displayName)); Assert.IsFalse(string.IsNullOrEmpty(parseName)); } finally { ptrStr = PidlManager.FreeCoTaskMem(ptrStr); apidl = PidlManager.FreeCoTaskMem(apidl); } } // There should be more than one item below the desktop root item // 'My PC', 'Recycle Bin', and 'Network' are already three Assert.IsTrue(count > 2); } finally { if (enumerator != default(IntPtr)) { Marshal.Release(enumerator); } if (iDesktopFolder != null) { Marshal.ReleaseComObject(iDesktopFolder); } if (ptrDesktopFolder != default(IntPtr)) { Marshal.Release(ptrDesktopFolder); } } }