internal ShellItem(ShellBrowser browser, IntPtr pidl, IntPtr shellFolderPtr) { this.browser = browser; this.shellFolderPtr = shellFolderPtr; this.shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder)); subFiles = new ShellItemCollection(this); subFolders = new ShellItemCollection(this); pidlRel = new PIDL(pidl, false); text = "Desktop"; path = "Desktop"; SetAttributesDesktop(this); ShellAPI.SHFILEINFO info = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(pidlRel.Ptr, 0, ref info, ShellAPI.cbFileInfo, ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.TYPENAME | ShellAPI.SHGFI.SYSICONINDEX); type = info.szTypeName; ShellImageList.SetIconIndex(this, info.iIcon, false); ShellImageList.SetIconIndex(this, info.iIcon, true); sortFlag = 1; }
internal FileInfoEx(DirectoryInfoEx parentDir, PIDL relPIDL) { Parent = parentDir; //0.15: Fixed ShellFolder not freed. using (ShellFolder2 parentShellFolder = parentDir.ShellFolder) init(parentShellFolder, parentDir.PIDLRel, relPIDL); }
public bool MoveNext() { if (clonePidl != IntPtr.Zero) { Marshal.FreeCoTaskMem(clonePidl); clonePidl = IntPtr.Zero; } if (start) { start = false; return(true); } else { IntPtr newPidl = ILGetNext(currentPidl); if (!PIDL.IsEmpty(newPidl)) { currentPidl = newPidl; return(true); } else { return(false); } } }
public PIDL(PIDL pidl, bool clone) { if (clone) this.pidl = ILClone(pidl.Ptr); else this.pidl = pidl.Ptr; }
internal ShellItem GetShellItem(PIDL pidlFull) { ShellItem current = DesktopItem; if (pidlFull.Ptr == IntPtr.Zero) { return(current); } foreach (IntPtr pidlRel in pidlFull) { int index; if ((index = current.IndexOf(pidlRel)) > -1) { current = current[index]; } else { current = null; break; } } return(current); }
internal FileInfoEx(PIDL fullPIDL, bool freeFullPIDL) { init(fullPIDL); checkProperties(); if (freeFullPIDL) fullPIDL.Free(); }
public PIDL(PIDL pidl, bool clone) { if (clone) { this.pidl = ILClone(pidl.Ptr); } else { this.pidl = pidl.Ptr; } }
public PIDL(PIDL pidl, bool clone) { if (clone) { this.pidl = ILClone(pidl.Ptr); System.Threading.Interlocked.Increment(ref Counter); } else { this.pidl = pidl.Ptr; } }
internal FileInfoEx(IShellFolder2 parentShellFolder, DirectoryInfoEx parentDir, PIDL relPIDL) { Parent = parentDir; PIDL parentPIDL = parentDir.PIDL; try { init(parentShellFolder, parentPIDL, relPIDL); } finally { if (parentPIDL != null) parentPIDL.Free(); parentPIDL = null; } }
public static KnownFolder FromPidl(PIDL pidl) { IKnownFolder knowFolderInterface; try { KnownFolder.FolderManager.FindFolderFromIDList(pidl.Ptr, out knowFolderInterface); return(new KnownFolder(knowFolderInterface)); } catch { return(null); } }
public ShellItem(ShellBrowser browser, ShellItem parentItem, IntPtr pidl) { this.Browser = browser; this.ParentItem = parentItem; PIDLRel = new PIDL(pidl, false); SetText(this); SetPath(this); SetAttributesFile(this); SetInfo(this); SortFlag = MakeSortFlag(this); }
internal ShellItem(ShellBrowser browser, ShellItem parentItem, IntPtr pidl) { this.browser = browser; this.parentItem = parentItem; pidlRel = new PIDL(pidl, false); SetText(this); SetPath(this); SetAttributesFile(this); SetInfo(this); sortFlag = MakeSortFlag(this); }
internal ShellItem(ShellBrowser browser, ShellItem parentItem, IntPtr pidl, IntPtr shellFolderPtr) { this.browser = browser; this.parentItem = parentItem; this.shellFolderPtr = shellFolderPtr; this.shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder)); subFiles = new ShellItemCollection(this); subFolders = new ShellItemCollection(this); pidlRel = new PIDL(pidl, false); SetText(this); SetPath(this); SetAttributesFolder(this); SetInfo(this); sortFlag = MakeSortFlag(this); }
public static KnownFolder FromPidl(PIDL pidl) { IKnownFolder knowFolderInterface; try { int hr = KnownFolder.FolderManager.FindFolderFromIDList(pidl.Ptr, out knowFolderInterface); if (knowFolderInterface != null && hr == ShellAPI.S_OK) { return(new KnownFolder(knowFolderInterface)); } else { return(null); } } catch { return(null); } }
/// <summary> /// Convert CSIDL to PIDL /// </summary> internal static PIDL CSIDLtoPIDL(ShellDll.ShellAPI.CSIDL csidl) { IntPtr ptrAddr; PIDL pidl; if (csidl == ShellAPI.CSIDL.MYDOCUMENTS) return PathtoPIDL(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); { int RetVal = ShellAPI.SHGetSpecialFolderLocation(IntPtr.Zero, csidl, out ptrAddr); if (ptrAddr != IntPtr.Zero) { pidl = new PIDL(ptrAddr, false); return pidl; } else throw new ArgumentException("Invalid csidl " + RetVal); } //return null; }
//0.17: Added DirectoryInfoEx.EnumerateFiles/EnumerateDirectories/EnumerateFileSystemInfos() methods which work similar as the one in .Net4 public IEnumerable<FileInfoEx> EnumerateFiles(String searchPattern, SearchOption searchOption, CancelDelegate cancel) { IntPtr ptrEnum = IntPtr.Zero; IEnumIDList IEnum = null; PIDL parentPIDL = this.PIDL; using (ShellFolder2 sf = this.ShellFolder) try { if (sf.EnumObjects(IntPtr.Zero, flag, out ptrEnum) == ShellAPI.S_OK) { IEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(ptrEnum, typeof(IEnumIDList)); IntPtr pidlSubItem; int celtFetched; while (!IOTools.IsCancelTriggered(cancel) && IEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1) { ShellAPI.SFGAO attribs = ShellAPI.SFGAO.FOLDER | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.STREAM; sf.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs); //http://www.eggheadcafe.com/aspnet_answers/platformsdkshell/Mar2006/post26165601.asp bool isZip = ((attribs & ShellAPI.SFGAO.FOLDER) != 0 && (attribs & ShellAPI.SFGAO.STREAM) != 0); bool isDir = ((attribs & ShellAPI.SFGAO.FOLDER) != 0); if (isZip || !isDir) { PIDL subRelPidl = new PIDL(pidlSubItem, false); //FileInfoEx fi = new FileInfoEx(sf, this, subRelPidl); FileInfoEx fi = new FileInfoEx(sf, parentPIDL, subRelPidl); if (IOTools.MatchFileMask(fi.Name, searchPattern)) yield return fi; //0.18: Fixed DirectoryInfoEx.EnumerateFiles, SearchPattern is ignored. } } if (searchOption == SearchOption.AllDirectories) { IEnumerator<DirectoryInfoEx> dirEnumerator = EnumerateDirectories("*", SearchOption.TopDirectoryOnly, cancel).GetEnumerator(); while (!IOTools.IsCancelTriggered(cancel) && dirEnumerator.MoveNext()) { IEnumerator<FileInfoEx> fileEnumerator = dirEnumerator.Current.EnumerateFiles(searchPattern, searchOption, cancel).GetEnumerator(); while (fileEnumerator.MoveNext()) { //Debug.Assert(!fileEnumerator.Current.IsFolder); yield return fileEnumerator.Current; } } } } } finally { if (parentPIDL != null) { parentPIDL.Free(); parentPIDL = null; } if (IEnum != null) { Marshal.ReleaseComObject(IEnum); Marshal.Release(ptrEnum); } } }
internal static void SetIconIndex(ShellItem item, int index, bool SelectedIcon) { bool HasOverlay = false; //true if it's an overlay int rVal = 0; //The returned Index ShellAPI.SHGFI dwflag = ShellAPI.SHGFI.SYSICONINDEX | ShellAPI.SHGFI.PIDL | ShellAPI.SHGFI.ICON; ShellAPI.FILE_ATTRIBUTE dwAttr = 0; //build Key into HashTable for this Item int Key = index * 256; if (item.IsLink) { Key = Key | 1; dwflag = dwflag | ShellAPI.SHGFI.LINKOVERLAY; HasOverlay = true; } if (item.IsShared) { Key = Key | 2; dwflag = dwflag | ShellAPI.SHGFI.ADDOVERLAYS; HasOverlay = true; } if (SelectedIcon) { Key = Key | 4; dwflag = dwflag | ShellAPI.SHGFI.OPENICON; HasOverlay = true; //not really an overlay, but handled the same } if (imageTable.ContainsKey(Key)) { rVal = (int)imageTable[Key]; } else if (!HasOverlay && !item.IsHidden) //for non-overlay icons, we already have { rVal = (int)System.Math.Floor((double)Key / 256); // the right index -- put in table imageTable[Key] = rVal; } else //don't have iconindex for an overlay, get it. { if (item.IsFileSystem & !item.IsDisk & !item.IsFolder) { dwflag = dwflag | ShellAPI.SHGFI.USEFILEATTRIBUTES; dwAttr = dwAttr | ShellAPI.FILE_ATTRIBUTE.NORMAL; } PIDL pidlFull = item.PIDLFull; ShellAPI.SHFILEINFO shfiSmall = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(pidlFull.Ptr, dwAttr, ref shfiSmall, ShellAPI.cbFileInfo, dwflag | ShellAPI.SHGFI.SMALLICON); ShellAPI.SHFILEINFO shfiLarge = new ShellAPI.SHFILEINFO(); ShellAPI.SHGetFileInfo(pidlFull.Ptr, dwAttr, ref shfiLarge, ShellAPI.cbFileInfo, dwflag | ShellAPI.SHGFI.LARGEICON); Marshal.FreeCoTaskMem(pidlFull.Ptr); lock (imageTable) { rVal = ShellAPI.ImageList_ReplaceIcon(smallImageListHandle, -1, shfiSmall.hIcon); ShellAPI.ImageList_ReplaceIcon(largeImageListHandle, -1, shfiLarge.hIcon); } ShellAPI.DestroyIcon(shfiSmall.hIcon); ShellAPI.DestroyIcon(shfiLarge.hIcon); imageTable[Key] = rVal; } if (SelectedIcon) { item.SelectedImageIndex = rVal; } else { item.ImageIndex = rVal; } }
protected override void refresh(IShellFolder2 parentShellFolder, PIDL relPIDL, PIDL fullPIDL) { base.refresh(parentShellFolder, relPIDL, fullPIDL); if (parentShellFolder != null && relPIDL != null && fullPIDL != null) { ShellAPI.SFGAO attribute = shGetFileAttribute(fullPIDL, ShellAPI.SFGAO.BROWSABLE | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.HASSUBFOLDER); IsBrowsable = (attribute & ShellAPI.SFGAO.BROWSABLE) != 0 || (attribute & ShellAPI.SFGAO.CONTENTSMASK) != 0; IsFileSystem = (attribute & ShellAPI.SFGAO.FILESYSTEM) != 0; HasSubFolder = (attribute & ShellAPI.SFGAO.HASSUBFOLDER) != 0; if (Directory.Exists(FullName)) try { DirectoryInfo di = new DirectoryInfo(FullName); Attributes = di.Attributes; LastAccessTime = di.LastAccessTime; LastWriteTime = di.LastWriteTime; CreationTime = di.CreationTime; } catch { } initDirectoryType(); } }
/// <summary> /// Extract IntPtr for the specified item(s), the result pointer is still owned by the input PIDL, thus dont needed to be freed. /// </summary> /// <param name="item"></param> /// <returns></returns> public static IntPtr[] GetPIDLPtr(PIDL item) { return GetPIDLPtr(new PIDL[] { item }); }
internal ShellItem GetShellItem(PIDL pidlFull) { ShellItem current = DesktopItem; if (pidlFull.Ptr == IntPtr.Zero) return current; foreach (IntPtr pidlRel in pidlFull) { int index; if ((index = current.IndexOf(pidlRel)) > -1) { current = current[index]; } else { current = null; break; } } return current; }
/// <summary> /// Convert a Parsable path to PIDL /// </summary> private static PIDL PathtoPIDL(string path) { IntPtr pidlPtr; uint pchEaten = 0; ShellAPI.SFGAO pdwAttributes = 0; using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder()) _desktopShellFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, path, ref pchEaten, out pidlPtr, ref pdwAttributes); PIDL pidl = new PIDL(pidlPtr, false); return pidl; }
public IEnumerable<DirectoryInfoEx> EnumerateDirectories(String searchPattern, SearchOption searchOption, CancelDelegate cancel) { IntPtr ptrEnum = IntPtr.Zero; IEnumIDList IEnum = null; PIDL parentPIDL = this.PIDL; using (ShellFolder2 sf = this.ShellFolder) try { if (sf.EnumObjects(IntPtr.Zero, flag, out ptrEnum) == ShellAPI.S_OK) { IEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(ptrEnum, typeof(IEnumIDList)); IntPtr pidlSubItem; int celtFetched; while (!IOTools.IsCancelTriggered(cancel) && IEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1) { ShellAPI.SFGAO attribs = ShellAPI.SFGAO.FOLDER | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.STREAM | ShellAPI.SFGAO.FILESYSANCESTOR | ShellAPI.SFGAO.NONENUMERATED; sf.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs); bool isZip = ((attribs & ShellAPI.SFGAO.FOLDER) != 0 && (attribs & ShellAPI.SFGAO.STREAM) != 0); bool isDir = ((attribs & ShellAPI.SFGAO.FOLDER) != 0); //0.18 Added a check for NonEnumerated items so DirectoryInfoEx.EnumerateDirectories wont return some system directories (e.g. C:\MSOCache) //bool isNonEnumerated = ((attribs & ShellAPI.SFGAO.NONENUMERATED) != 0); bool isFileAncestor = ((attribs & ShellAPI.SFGAO.FILESYSANCESTOR) != 0); bool includedFolder = false; if (!isZip && !isFileAncestor) //0.14 : Added allowed folder list so Non-FileAncestor directory (e.g. recycle-bin) is listed. { string[] allowedPaths = new string[] { "::{645FF040-5081-101B-9F08-00AA002F954E}" }; string path = PIDLToPath(new PIDL(pidlSubItem, false)); foreach (string allowedPath in allowedPaths) if (allowedPath == path) includedFolder = true; if (!includedFolder) if (IOTools.HasParent(this, NetworkDirectory)) includedFolder = true; } if (isDir && !isZip /*&& !isNonEnumerated*/ && (isFileAncestor || includedFolder)) { PIDL subPidl = new PIDL(pidlSubItem, false); //DirectoryInfoEx di = new DirectoryInfoEx(this, subPidl); DirectoryInfoEx di = new DirectoryInfoEx(sf, parentPIDL, subPidl); if (IOTools.MatchFileMask(di.Name, searchPattern)) yield return di; if (searchOption == SearchOption.AllDirectories) { IEnumerator<DirectoryInfoEx> dirEnumerator = di.EnumerateDirectories(searchPattern, searchOption, cancel).GetEnumerator(); while (dirEnumerator.MoveNext()) { //Debug.Assert(dirEnumerator.Current.IsFolder); yield return dirEnumerator.Current; } } } } } } finally { if (parentPIDL != null) { parentPIDL.Free(); parentPIDL = null; } if (IEnum != null) { Marshal.ReleaseComObject(IEnum); Marshal.Release(ptrEnum); } } }
internal DirectoryInfoEx(IShellFolder2 parentShellFolder, PIDL fullPIDL) { init(parentShellFolder, fullPIDL); }
protected override void refresh(IShellFolder2 parentShellFolder, PIDL relPIDL, PIDL fullPIDL) { base.refresh(parentShellFolder, relPIDL, fullPIDL); if (parentShellFolder != null && relPIDL != null && fullPIDL != null) { if (!FullName.StartsWith("::") && File.Exists(FullName)) try { FileInfo fi = new FileInfo(FullName); IsReadOnly = fi.IsReadOnly; Attributes = fi.Attributes; Length = fi.Length; LastAccessTime = fi.LastAccessTime; LastWriteTime = fi.LastWriteTime; CreationTime = fi.CreationTime; } catch { } else //0.18: Uses File to return FileInfo by default { ShellAPI.SFGAO attribute = shGetFileAttribute(fullPIDL, ShellAPI.SFGAO.READONLY); IsReadOnly = (attribute & ShellAPI.SFGAO.READONLY) != 0; Length = 0; } } }
protected override void WndProc(ref Message m) { if (m.Msg == (int)ShellAPI.WM.SH_NOTIFY) { ShellAPI.SHNOTIFYSTRUCT shNotify = (ShellAPI.SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(ShellAPI.SHNOTIFYSTRUCT)); //Console.Out.WriteLine("Event: {0}", (ShellAPI.SHCNE)m.LParam); //if (shNotify.dwItem1 != IntPtr.Zero) //PIDL.Write(shNotify.dwItem1); //if (shNotify.dwItem2 != IntPtr.Zero) //PIDL.Write(shNotify.dwItem2); switch ((ShellAPI.SHCNE)m.LParam) { #region File Changes case ShellAPI.SHCNE.CREATE: #region Create Item { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child, relative; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.FilesExpanded && !parentItem.SubFiles.Contains(child)) { ShellAPI.SHGetRealIDL( parentItem.ShellFolder, child, out relative); parentItem.AddItem(new ShellItem(br, parentItem, relative)); } Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.RENAMEITEM: #region Rename Item { if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed); } } #endregion break; case ShellAPI.SHCNE.DELETE: #region Delete Item { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.SubFiles.Contains(child)) parentItem.RemoveItem(parentItem.SubFiles[child]); Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.UPDATEITEM: #region Update Item { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { Console.Out.WriteLine("Item: {0}", item); item.Update(IntPtr.Zero, ShellItemUpdateType.Updated); item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange); } } } #endregion break; #endregion #region Folder Changes case ShellAPI.SHCNE.MKDIR: case ShellAPI.SHCNE.DRIVEADD: case ShellAPI.SHCNE.DRIVEADDGUI: #region Make Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child, relative; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.FoldersExpanded && !parentItem.SubFolders.Contains(child)) { ShellAPI.SHGetRealIDL( parentItem.ShellFolder, child, out relative); IntPtr shellFolderPtr; if (parentItem.ShellFolder.BindToObject( relative, IntPtr.Zero, ref ShellAPI.IID_IShellFolder, out shellFolderPtr) == ShellAPI.S_OK) { parentItem.AddItem(new ShellItem(br, parentItem, relative, shellFolderPtr)); } else Marshal.FreeCoTaskMem(relative); } Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.RENAMEFOLDER: #region Rename Directory { if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, false)); if (item != null) { //Console.Out.WriteLine("Update: {0}", item); item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed); } } } #endregion break; case ShellAPI.SHCNE.RMDIR: case ShellAPI.SHCNE.DRIVEREMOVED: #region Remove Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.SubFolders.Contains(child)) parentItem.RemoveItem(parentItem.SubFolders[child]); Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.UPDATEDIR: case ShellAPI.SHCNE.ATTRIBUTES: #region Update Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { item.Update(IntPtr.Zero, ShellItemUpdateType.Updated); item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange); } } } #endregion break; case ShellAPI.SHCNE.MEDIAINSERTED: case ShellAPI.SHCNE.MEDIAREMOVED: #region Media Change { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) item.Update(IntPtr.Zero, ShellItemUpdateType.MediaChange); } } #endregion break; #endregion #region Other Changes case ShellAPI.SHCNE.ASSOCCHANGED: #region Update Images { } #endregion break; case ShellAPI.SHCNE.NETSHARE: case ShellAPI.SHCNE.NETUNSHARE: break; case ShellAPI.SHCNE.UPDATEIMAGE: UpdateRecycleBin(); break; #endregion } } base.WndProc(ref m); }
/// <summary> /// Rename a file or folder in an directory. /// </summary> public static void Rename(string source, string destName) { //DirectoryInfoEx srcDir = new DirectoryInfoEx(Path.GetDirectoryName(source)); FileSystemInfoEx srcElement = new FileSystemInfoEx(source); string srcName = Path.GetFileName(source); if (!srcElement.Exists || srcElement.Parent == null) throw new IOException("Source not exists"); //0.15: Fixed ShellFolder not freed. using (ShellFolder2 srcParentShellFolder = srcElement.Parent.ShellFolder) { if (srcParentShellFolder == null) throw new IOException("Source directory does not support IShellFolder"); IntPtr tmpPtr; int hr = srcParentShellFolder.SetNameOf(IntPtr.Zero, srcElement.PIDLRel.Ptr, destName, ShellAPI.SHGNO.FORPARSING, out tmpPtr); PIDL tmpPIDL = new PIDL(tmpPtr, false); //consume the IntPtr, and free it. tmpPIDL.Free(); if (hr != ShellAPI.S_OK) Marshal.ThrowExceptionForHR(hr); } }
/// <summary> /// Return whether PIDL match fileMask ( * and ? supported) /// </summary> /// <param name="pidl"></param> /// <param name="fileMask"></param> /// <returns></returns> public static bool MatchFileMask(PIDL pidl, string fileMask) { string path = FileSystemInfoEx.PIDLToPath(pidl); string name = PathEx.GetFileName(path); return MatchFileMask(name, fileMask); }
protected override void WndProc(ref Message m) { if (m.Msg == (int)ShellAPI.WM.SH_NOTIFY) { ShellAPI.SHNOTIFYSTRUCT shNotify = (ShellAPI.SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(ShellAPI.SHNOTIFYSTRUCT)); //Console.Out.WriteLine("Event: {0}", (ShellAPI.SHCNE)m.LParam); //if (shNotify.dwItem1 != IntPtr.Zero) //PIDL.Write(shNotify.dwItem1); //if (shNotify.dwItem2 != IntPtr.Zero) //PIDL.Write(shNotify.dwItem2); try { switch ((ShellAPI.SHCNE)m.LParam) { #region File Changes case ShellAPI.SHCNE.CREATE: #region Create Item { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child, relative; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.FilesExpanded && !parentItem.SubFiles.Contains(child)) { ShellAPI.SHGetRealIDL( parentItem.ShellFolder, child, out relative); parentItem.AddItem(new ShellItem(br, parentItem, relative)); } Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.RENAMEITEM: #region Rename Item { if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed); } } } #endregion break; case ShellAPI.SHCNE.DELETE: #region Delete Item { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.SubFiles.Contains(child)) { parentItem.RemoveItem(parentItem.SubFiles[child]); } Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.UPDATEITEM: #region Update Item { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { Console.Out.WriteLine("Item: {0}", item); item.Update(IntPtr.Zero, ShellItemUpdateType.Updated); item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange); } } } #endregion break; #endregion #region Folder Changes case ShellAPI.SHCNE.MKDIR: case ShellAPI.SHCNE.DRIVEADD: case ShellAPI.SHCNE.DRIVEADDGUI: #region Make Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child, relative; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.FoldersExpanded && !parentItem.SubFolders.Contains(child)) { ShellAPI.SHGetRealIDL( parentItem.ShellFolder, child, out relative); IntPtr shellFolderPtr; if (parentItem.ShellFolder.BindToObject( relative, IntPtr.Zero, ref ShellAPI.IID_IShellFolder, out shellFolderPtr) == ShellAPI.S_OK) { parentItem.AddItem(new ShellItem(br, parentItem, relative, shellFolderPtr)); } else { Marshal.FreeCoTaskMem(relative); } } Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.RENAMEFOLDER: #region Rename Directory { if (!PIDL.IsEmpty(shNotify.dwItem1) && !PIDL.IsEmpty(shNotify.dwItem2)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, false)); if (item != null) { //Console.Out.WriteLine("Update: {0}", item); item.Update(shNotify.dwItem2, ShellItemUpdateType.Renamed); } } } #endregion break; case ShellAPI.SHCNE.RMDIR: case ShellAPI.SHCNE.DRIVEREMOVED: #region Remove Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); ShellItem parentItem = br.GetShellItem(parentPIDL); if (parentItem != null && parentItem.SubFolders.Contains(child)) { parentItem.RemoveItem(parentItem.SubFolders[child]); } Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.UPDATEDIR: case ShellAPI.SHCNE.ATTRIBUTES: #region Update Directory { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { item.Update(IntPtr.Zero, ShellItemUpdateType.Updated); item.Update(IntPtr.Zero, ShellItemUpdateType.IconChange); } } } #endregion break; case ShellAPI.SHCNE.MEDIAINSERTED: case ShellAPI.SHCNE.MEDIAREMOVED: #region Media Change { if (!PIDL.IsEmpty(shNotify.dwItem1)) { ShellItem item = br.GetShellItem(new PIDL(shNotify.dwItem1, true)); if (item != null) { item.Update(IntPtr.Zero, ShellItemUpdateType.MediaChange); } } } #endregion break; #endregion #region Other Changes case ShellAPI.SHCNE.ASSOCCHANGED: #region Update Images { } #endregion break; case ShellAPI.SHCNE.NETSHARE: case ShellAPI.SHCNE.NETUNSHARE: break; case ShellAPI.SHCNE.UPDATEIMAGE: UpdateRecycleBin(); break; #endregion } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } base.WndProc(ref m); }
/// <summary> /// Free up a PIDL IntPtr List. /// </summary> /// <param name="pidls"></param> public static void FreePIDL(PIDL[] pidls) { foreach (PIDL pidl in pidls) pidl.Free(); }
internal void Update(IntPtr newPidlFull, ShellItemUpdateType changeType) { browser.UpdateCondition.ContinueUpdate = false; lock(browser) { #region Change Pidl and ShellFolder if(newPidlFull != IntPtr.Zero) { IntPtr tempPidl = PIDL.ILClone(PIDL.ILFindLastID(newPidlFull)), newPidlRel, newShellFolderPtr; ShellAPI.SHGetRealIDL(ParentItem.ShellFolder, tempPidl, out newPidlRel); if(IsFolder && ParentItem.ShellFolder.BindToObject( newPidlRel, IntPtr.Zero, ref ShellAPI.IID_IShellFolder, out newShellFolderPtr) == ShellAPI.S_OK) { Marshal.ReleaseComObject(shellFolder); Marshal.Release(shellFolderPtr); pidlRel.Free(); shellFolderPtr = newShellFolderPtr; shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder)); pidlRel = new PIDL(newPidlRel, false); foreach(ShellItem child in SubFolders) UpdateShellFolders(child); } else { pidlRel.Free(); pidlRel = new PIDL(newPidlRel, false); } Marshal.FreeCoTaskMem(tempPidl); Marshal.FreeCoTaskMem(newPidlFull); } #endregion #region Make Other Changes switch(changeType) { case ShellItemUpdateType.Renamed: SetText(this); SetPath(this); break; case ShellItemUpdateType.Updated: if(IsFolder) SetAttributesFolder(this); else SetAttributesFile(this); break; case ShellItemUpdateType.MediaChange: SetInfo(this); Clear(true, true); break; case ShellItemUpdateType.IconChange: SetInfo(this); break; } #endregion } Browser.OnShellItemUpdate(ParentItem, new ShellItemUpdateEventArgs(this, this, changeType)); }
internal DirectoryInfoEx(DirectoryInfoEx parentDir, PIDL relPIDL) { Parent = parentDir; PIDL parentPIDL = parentDir.PIDL; try { //0.15: Fixed ShellFolder not freed. using (ShellFolder2 parentShellFolder = parentDir.ShellFolder) init(parentShellFolder, parentPIDL, relPIDL); } finally { if (parentPIDL != null) parentPIDL.Free(); parentPIDL = null; } }
internal FileInfoEx(IShellFolder2 parentShellFolder, PIDL fullPIDL) { init(parentShellFolder, fullPIDL); }
/// <summary> /// Extract IntPtr for the specified item(s), the result pointer is still owned by the input PIDL, thus dont needed to be freed. /// </summary> public static IntPtr[] GetPIDLPtr(PIDL[] items) { List<IntPtr> retVal = new List<IntPtr>(); foreach (PIDL pidl in items) retVal.Add(pidl.Ptr); return retVal.ToArray(); }
internal FileInfoEx(IShellFolder2 parentShellFolder, PIDL parentPIDL, PIDL relPIDL) { init(parentShellFolder, parentPIDL, relPIDL); }
private static void listRemove(List<FileSystemInfoEx> list, PIDL pidl) { for (int i = list.Count - 1; i >= 0; i--) if (list[i].PIDLRel.Equals(pidl)) { list.RemoveAt(i); return; } }
internal DirectoryInfoEx(IShellFolder2 parentShellFolder, PIDL parentPIDL, PIDL relPIDL) { init(parentShellFolder, parentPIDL, relPIDL); }
//private List<FileSystemInfoEx> _cachedFileList = new List<FileSystemInfoEx>(); private static bool listContains(List<FileSystemInfoEx> list, PIDL pidl) { foreach (FileSystemInfoEx item in list) if (item.PIDLRel.Equals(pidl)) return true; return false; }
//private static Bitmap loadJumbo(string lookup, bool forceLoadFromDisk, IconSize size) //{ // SysImageList _imgList = isVistaUp() && ((size == IconSize.thumbnail) || (size == IconSize.jumbo)) ? _imgListJumbo : _imgListXL; // try // { // Icon icon = _imgList.Icon(_imgList.IconIndex(lookup, forceLoadFromDisk)); // Bitmap bitmap = icon.ToBitmap(); // icon.Dispose(); // System.Drawing.Color empty = System.Drawing.Color.FromArgb(0, 0, 0, 0); // if (bitmap.Width < 256) // bitmap = resizeImage(bitmap, new System.Drawing.Size(256, 256), 0); // else if (bitmap.GetPixel(100, 100) == empty && bitmap.GetPixel(200, 200) == empty && bitmap.GetPixel(200, 200) == empty) // { // _imgList.ImageListSize = SysImageListSize.largeIcons; // bitmap = resizeJumbo(_imgList.Icon(_imgList.IconIndex(lookup)).ToBitmap(), new System.Drawing.Size(200, 200), 5); // } // return bitmap; // } // catch // { // return GetFileIcon(lookup, IconSize.large); // } //} protected override Bitmap KeyToBitmap(string key, IconSize size) { try { bool isDiskFolder = key.EndsWith(":\\"); bool isTemp = key.Equals(tempPath); string ext = PathEx.GetExtension(key).ToLower(); if (!ext.StartsWith(".")) { if (specialExtFilter.Split(',').Contains(key)) { switch (ext) { case ".exe": ShellDll.PIDL pidlLookup = FileSystemInfoEx.FromString(key).PIDL; try { return(GetFileIcon(pidlLookup.Ptr, size)); } finally { if (pidlLookup != null) { pidlLookup.Free(); } } case ".lnk": using (ShellLink sl = new ShellLink(key)) switch (size) { case IconSize.small: return(sl.SmallIcon.ToBitmap()); default: return(sl.LargeIcon.ToBitmap()); } } } } if (fileBasedFSFilter.Split(',').Contains(key)) { return(GetFileBasedFSBitmap(key, size)); } else if (key == "" || key.StartsWith(".")) //Extension { return(GetFileIcon(key, size)); } else if (IsSpecialFolder(key)) { ShellDll.PIDL pidlLookup = FileSystemInfoEx.FromString(key).PIDL; try { return(GetFileIcon(pidlLookup.Ptr, size)); } finally { if (pidlLookup != null) { pidlLookup.Free(); } } } else { switch (size) { case IconSize.thumbnail: return(loadThumbnail(key, isDiskFolder || isTemp)); //case IconSize.jumbo: //case IconSize.extraLarge: // return loadJumbo(key, isDiskFolder || isTemp, size); //case IconSize.large : // _imgList.ImageListSize = SysImageListSize.largeIcons; // return _imgList.Icon(_imgList.IconIndex(key, isDiskFolder)).ToBitmap(); //case IconSize.small : // _imgList.ImageListSize = SysImageListSize.smallIcons; // return _imgList.Icon(_imgList.IconIndex(key, isDiskFolder)).ToBitmap(); default: try { return(GetFileIcon(key, size)); } catch { return(KeyToBitmap(UCUtils.GetProgramPath(), size)); } } } } catch { return(new Bitmap(1, 1)); } }
protected override void WndProc(ref Message m) { if(m.Msg == (int)ShellAPI.WM.SH_NOTIFY) { ShellAPI.SHNOTIFYSTRUCT shNotify = (ShellAPI.SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(ShellAPI.SHNOTIFYSTRUCT)); //Console.Out.WriteLine("Event: {0}", (ShellAPI.SHCNE)m.LParam); //if (shNotify.dwItem1 != IntPtr.Zero) //PIDL.Write(shNotify.dwItem1); //if (shNotify.dwItem2 != IntPtr.Zero) //PIDL.Write(shNotify.dwItem2); switch((ShellAPI.SHCNE)m.LParam) { #region File Changes case ShellAPI.SHCNE.CREATE: #region Create Item { if(!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.RENAMEITEM: break; case ShellAPI.SHCNE.DELETE: #region Delete Item { if(!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.UPDATEITEM: break; #endregion #region Folder Changes case ShellAPI.SHCNE.MKDIR: case ShellAPI.SHCNE.DRIVEADD: case ShellAPI.SHCNE.DRIVEADDGUI: #region Make Directory { if(!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.RENAMEFOLDER: break; case ShellAPI.SHCNE.RMDIR: case ShellAPI.SHCNE.DRIVEREMOVED: #region Remove Directory { if(!PIDL.IsEmpty(shNotify.dwItem1)) { IntPtr parent, child; PIDL.SplitPidl(shNotify.dwItem1, out parent, out child); PIDL parentPIDL = new PIDL(parent, false); Marshal.FreeCoTaskMem(child); parentPIDL.Free(); } } #endregion break; case ShellAPI.SHCNE.UPDATEDIR: case ShellAPI.SHCNE.ATTRIBUTES: break; case ShellAPI.SHCNE.MEDIAINSERTED: case ShellAPI.SHCNE.MEDIAREMOVED: break; #endregion #region Other Changes case ShellAPI.SHCNE.ASSOCCHANGED: #region Update Images { } #endregion break; case ShellAPI.SHCNE.NETSHARE: case ShellAPI.SHCNE.NETUNSHARE: break; case ShellAPI.SHCNE.UPDATEIMAGE: UpdateRecycleBin(); break; #endregion } } base.WndProc(ref m); }