예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        private string LoadIconResourceId()
        {
            lock (resolvePropsLock)
            {
                if (_KnownFolderIsInitialized == false)
                {
                    _KnownFolderIsInitialized = true;
                    _KnownFolder = LoadKnownFolder();
                }
            }

            if (KnownFolder == null)
            {
                return(null);
            }

            bool isKFIconResourceIdValid = false;

            if (KnownFolder != null)
            {
                isKFIconResourceIdValid = KnownFolder.IsIconResourceIdValid();
            }

            if (isKFIconResourceIdValid == false)
            {
                IdList pidl = null;
                LoadPidls();

                if (ChildIdList != null || ParentIdList != null)
                {
                    pidl = PidlManager.CombineParentChild(ParentIdList, ChildIdList);
                }
                else
                {
                    pidl = IdList.Create();
                }

                string filename;
                int    index;

                if (IconHelper.GetIconResourceId(pidl, out filename, out index))
                {
                    // Store filename and index for Desktop Root ResourceId
                    return(string.Format("{0},{1}", filename, index));
                }
            }
            else
            {
                return(KnownFolder.IconResourceId);
            }

            return(null);
        }
        /// <summary>
        /// Retrieves the specified number of item identifiers in the
        /// enumeration sequence and advances the current position by
        /// the number of items retrieved.
        /// </summary>
        /// <param name="celt">Number of elements in the array pointed to by the rgelt parameter.</param>
        /// <param name="rgelt">Address of an array of ITEMIDLIST pointers that receives the item identifiers. The implementation must allocate these item identifiers
        /// using the Shell's allocator (retrieved by the SHGetMalloc function). The calling application is responsible for freeing the item
        /// identifiers using the Shell's allocator.</param>
        /// <param name="pceltFetched">Address of a value that receives a count of the item identifiers actually returned in rgelt. The count can be smaller than the value
        /// specified in the celt parameter. This parameter can be NULL only if celt is one.</param>
        /// <returns></returns>
        public int Next(uint celt, IntPtr rgelt, out uint pceltFetched)
        {
            //  Request the children from the extension. As this is an abstract call, we always
            //  use an exception handler.
            var items = new List <IShellNamespaceItem>();

            try
            {
                //  TODO: We may want to improve on the public api here so that we don't have to enumerate
                //  everything to get certain items.

                //  Enumerate the children, adding them to the items collection and moving the index forwards
                //  by the number of items we've enumerated.
                items.AddRange(
                    shellNamespaceFolder
                    .GetChildren(_shellNamespaceEnumerationFlags)
                    .Skip((int)currentIndex)
                    .Take((int)celt));
                currentIndex += (uint)items.Count;
            }
            catch (Exception exception)
            {
                //  Log the exception, but continue as if we've enumerated nothing.
                Diagnostics.Logging.Error(string.Format("An unhandled exception occured enumerating {0} items from the {1} namespace extension.", celt, shellNamespaceFolder.GetDisplayName(DisplayNameContext.Normal)),
                                          exception);
            }

            //  If we've not enumerated anything, we can return now.
            if (items.Any() == false && celt > 0)
            {
                pceltFetched = 0;
                return(WinError.S_FALSE);
            }

            //  For every item enumerated, use the PIDL manager to create a shell allocated PIDL.
            //  These PIDLs must not be relative, so using the value returned by the GetShellId
            //  function is enough.
            var pidlArray = items.Select(
                iid => PidlManager.IdListToPidl(IdList.Create(new List <ShellId> {
                iid.GetShellId()
            }))).ToArray();

            //  Copy the data to the provided array.
            Marshal.Copy(pidlArray, 0, rgelt, pidlArray.Length);
            pceltFetched = (uint)items.Count;

            //  We're done. We return OK if we've got more to enumerate and false otherwise.
            return(pceltFetched == celt ? WinError.S_OK : WinError.S_FALSE);
        }
예제 #5
0
        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);
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Calls the GetIDList method in the wrapped IKnownFolder interface to retrieve the ItemIdList
        /// for this KnownFolderItem.
        /// </summary>
        /// <returns>Type: PIDLIST_ABSOLUTE*
        /// When this method returns, contains the address of an absolute PIDL
        /// in its equivalent ItemIdList form.</returns>
        public IdList KnownFolderToIdList()
        {
            if (Obj == null)
            {
                throw new System.ArgumentException("Native IKnownFolder cannot be null.");
            }

            IntPtr ptrFullPidl = default(IntPtr);

            try
            {
                ptrFullPidl = KnownFolderToPIDL();

                // Convert PIDL into list of shellids and remove last id
                var shellListIds = PidlManager.Decode(ptrFullPidl);

                return(IdList.Create(shellListIds));
            }
            finally
            {
                ptrFullPidl = PidlManager.ILFree(ptrFullPidl);
            }
        }
예제 #7
0
        /// <summary>
        /// Gets an icons reource id if available in the format:
        /// "filename, index"
        /// where the first part is a string and the 2nd part is a negativ integer number).
        ///
        /// This format is usally used by the Windows Shell libraries so we use it here
        /// to add missing ResourceIds.
        /// </summary>
        /// <param name="parentIdList"></param>
        /// <param name="filename"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        internal static bool GetIconResourceId(IdList parentIdList,
                                               out string filename,
                                               out int index)
        {
            filename = null;
            index    = -1;

            IntPtr parentPtr      = default(IntPtr);
            IntPtr relChildPtr    = default(IntPtr);
            IntPtr ptrShellFolder = default(IntPtr);
            IntPtr ptrExtractIcon = default(IntPtr);
            IntPtr smallHicon     = default(IntPtr);
            IntPtr largeHicon     = default(IntPtr);

            try
            {
                if (parentIdList.Size == 0)
                {
                    parentPtr   = PidlManager.IdListToPidl(parentIdList);
                    relChildPtr = PidlManager.IdListToPidl(IdList.Create());
                }
                else
                {
                    IdList parIdList = null, relChildIdList = null;
                    PidlManager.GetParentChildIdList(parentIdList, out parIdList, out relChildIdList);

                    parentPtr   = PidlManager.IdListToPidl(parIdList);
                    relChildPtr = PidlManager.IdListToPidl(relChildIdList);
                }

                if (parentPtr == default(IntPtr) || relChildPtr == default(IntPtr))
                {
                    return(false);
                }

                Guid    guid = typeof(IShellFolder2).GUID;
                HRESULT hr   = NativeMethods.SHBindToParent(parentPtr, guid,
                                                            out ptrShellFolder, ref relChildPtr);

                if (hr != HRESULT.S_OK)
                {
                    return(false);
                }

                using (var shellFolder = new ShellFolder(ptrShellFolder))
                {
                    if (shellFolder == null)
                    {
                        return(false);
                    }

                    guid = typeof(IExtractIcon).GUID;
                    var pidls = new IntPtr[] { relChildPtr };
                    hr = shellFolder.Obj.GetUIObjectOf(IntPtr.Zero, 1, pidls, guid,
                                                       IntPtr.Zero, out ptrExtractIcon);

                    if (hr != HRESULT.S_OK)
                    {
                        return(false);
                    }

                    using (var extractIcon = new GenericCOMFolder <IExtractIcon>(ptrExtractIcon))
                    {
                        if (extractIcon == null)
                        {
                            return(false);
                        }

                        var  iconFile = new StringBuilder(NativeMethods.MAX_PATH);
                        uint pwFlags  = 0;

                        hr = extractIcon.Obj.GetIconLocation(0, iconFile,
                                                             (uint)iconFile.Capacity,
                                                             ref index, ref pwFlags);

                        if (hr != HRESULT.S_OK)
                        {
                            return(false);
                        }

                        if (string.IsNullOrEmpty(iconFile.ToString()))
                        {
                            return(false);
                        }

                        filename = iconFile.ToString();

                        return(true);
                    }
                }
            }
            finally
            {
                if (parentPtr != default(IntPtr))
                {
                    NativeMethods.ILFree(parentPtr);
                }

                ////if (relChildPtr != default(IntPtr))
                ////    Shell32.ILFree(relChildPtr);

                if (smallHicon != default(IntPtr))
                {
                    NativeMethods.DestroyIcon(smallHicon);
                }

                if (largeHicon != default(IntPtr))
                {
                    NativeMethods.DestroyIcon(largeHicon);
                }
            }
        }