/// <summary> /// Returns a known folder given a globally unique identifier. /// </summary> /// <param name="knownFolderId">A GUID for the requested known folder.</param> /// <returns>A known folder representing the specified name. Returns null if Known Folder is not found or could not be created.</returns> public static IKnownFolder FromKnownFolderIdInternal(Guid knownFolderId) { IKnownFolderManager knownFolderManager = new KnownFolderManagerClass(); HResult hr = knownFolderManager.GetFolder(knownFolderId, out var knownFolderNative); return((hr == HResult.Ok) ? GetKnownFolder(knownFolderNative) : null); }
/// <summary> /// Returns the native known folder (IKnownFolderNative) given a PID list /// </summary> /// <param name="pidl"></param> /// <returns></returns> public static IKnownFolderNative FromPIDL(IntPtr pidl) { KnownFolderManagerClass knownFolderManager = new KnownFolderManagerClass(); HResult hr = knownFolderManager.FindFolderFromIDList(pidl, out var knownFolder); return((hr == HResult.Ok) ? knownFolder : null); }
/// <summary> /// Returns the native known folder (IKnownFolderNative) given a PID list /// </summary> /// <param name="pidl"></param> /// <returns></returns> internal static IKnownFolderNative FromPIDL(IntPtr pidl) { KnownFolderManagerClass knownFolderManager = new KnownFolderManagerClass(); IKnownFolderNative knownFolder; HResult hr = knownFolderManager.FindFolderFromIDList(pidl, out knownFolder); return (hr == HResult.Ok) ? knownFolder : null; }
/// <summary> /// Returns the known folder given its canonical name. /// </summary> /// <param name="canonicalName">A non-localized canonical name for the known folder, such as MyComputer.</param> /// <returns>A known folder representing the specified name.</returns> /// <exception cref="System.ArgumentException">Thrown if the given canonical name is invalid or if the KnownFolder could not be created.</exception> public static IKnownFolder FromCanonicalName(string canonicalName) { IKnownFolderManager knownFolderManager = new KnownFolderManagerClass(); knownFolderManager.GetFolderByName(canonicalName, out var knownFolderNative); IKnownFolder kf = KnownFolderHelper.GetKnownFolder(knownFolderNative); if (kf == null) { throw new ArgumentException(LocalizedMessages.ShellInvalidCanonicalName, nameof(canonicalName)); } return(kf); }
// This is a work around for the STA thread bug. This will execute the call on a non-sta thread, then return the result private static bool IsVirtualKnownFolder(IShellItem2 nativeShellItem2) { IntPtr pidl = IntPtr.Zero; try { IKnownFolderNative nativeFolder = null; var definition = new KnownFoldersSafeNativeMethods.NativeFolderDefinition(); // We found a bug where the enumeration of shell folders was // not reliable when called from a STA thread - it would return // different results the first time vs the other times. // // This is a work around. We call FindFolderFromIDList on a // worker MTA thread instead of the main STA thread. // // Ultimately, it would be a very good idea to replace the 'getting shell object' logic // to get a list of pidl's in 1 step, then look up their information in a 2nd, rather than // looking them up as we get them. This would replace the need for the work around. object padlock = new object(); lock (padlock) { IntPtr unknown = Marshal.GetIUnknownForObject(nativeShellItem2); _ = ThreadPool.QueueUserWorkItem(obj => { lock (padlock) { pidl = ShellHelper.PidlFromUnknown(unknown); _ = new KnownFolderManagerClass().FindFolderFromIDList(pidl, out nativeFolder); nativeFolder?.GetFolderDefinition(out definition); Monitor.Pulse(padlock); } }); _ = Monitor.Wait(padlock); } return(nativeFolder != null && definition.category == FolderCategory.Virtual); } finally { Win32Native.Shell.Shell.ILFree(pidl); } }
/// <summary> /// Returns a known folder given a globally unique identifier. /// </summary> /// <param name="knownFolderId">A GUID for the requested known folder.</param> /// <returns>A known folder representing the specified name.</returns> /// <exception cref="System.ArgumentException">Thrown if the given Known Folder ID is invalid.</exception> public static IKnownFolder FromKnownFolderId(Guid knownFolderId) { IKnownFolderNative knownFolderNative; KnownFolderManagerClass knownFolderManager = new KnownFolderManagerClass(); HResult hr = knownFolderManager.GetFolder(knownFolderId, out knownFolderNative); if (hr != HResult.Ok) { throw new ShellException(hr); } IKnownFolder kf = GetKnownFolder(knownFolderNative); if (kf == null) { throw new ArgumentException(LocalizedMessages.KnownFolderInvalidGuid, "knownFolderId"); } return kf; }
private static ReadOnlyCollection <IKnownFolder> GetAllFolders() { // Should this method be thread-safe?? (It'll take a while // to get a list of all the known folders, create the managed wrapper // and return the read-only collection. IList <IKnownFolder> foldersList = new List <IKnownFolder>(); uint count; IntPtr folders = IntPtr.Zero; try { KnownFolderManagerClass knownFolderManager = new KnownFolderManagerClass(); knownFolderManager.GetFolderIds(out folders, out count); if (count > 0 && folders != IntPtr.Zero) { // Loop through all the KnownFolderID elements for (int i = 0; i < count; i++) { // Read the current pointer IntPtr current = new IntPtr(folders.ToInt64() + (Marshal.SizeOf(typeof(Guid)) * i)); // Convert to Guid Guid knownFolderID = (Guid)Marshal.PtrToStructure(current, typeof(Guid)); IKnownFolder kf = KnownFolderHelper.FromKnownFolderIdInternal(knownFolderID); // Add to our collection if it's not null (some folders might not exist on the system // or we could have an exception that resulted in the null return from above method call if (kf != null) { foldersList.Add(kf); } } } } finally { if (folders != IntPtr.Zero) { Marshal.FreeCoTaskMem(folders); } } return(new ReadOnlyCollection <IKnownFolder>(foldersList)); }
/// <summary> /// Returns a known folder given a globally unique identifier. /// </summary> /// <param name="knownFolderId">A GUID for the requested known folder.</param> /// <returns>A known folder representing the specified name.</returns> /// <exception cref="System.ArgumentException">Thrown if the given Known Folder ID is invalid.</exception> public static IKnownFolder FromKnownFolderId(Guid knownFolderId) { KnownFolderManagerClass knownFolderManager = new KnownFolderManagerClass(); HResult hr = knownFolderManager.GetFolder(knownFolderId, out var knownFolderNative); if (hr != HResult.Ok) { throw new ShellException(hr); } IKnownFolder kf = GetKnownFolder(knownFolderNative); if (kf == null) { throw new ArgumentException(LocalizedMessages.KnownFolderInvalidGuid, nameof(knownFolderId)); } return(kf); }
private static ReadOnlyCollection<IKnownFolder> GetAllFolders() { // Should this method be thread-safe?? (It'll take a while // to get a list of all the known folders, create the managed wrapper // and return the read-only collection. IList<IKnownFolder> foldersList = new List<IKnownFolder>(); uint count; IntPtr folders = IntPtr.Zero; try { KnownFolderManagerClass knownFolderManager = new KnownFolderManagerClass(); knownFolderManager.GetFolderIds(out folders, out count); if (count > 0 && folders != IntPtr.Zero) { // Loop through all the KnownFolderID elements for (int i = 0; i < count; i++) { // Read the current pointer IntPtr current = new IntPtr(folders.ToInt64() + (Marshal.SizeOf(typeof(Guid)) * i)); // Convert to Guid Guid knownFolderID = (Guid)Marshal.PtrToStructure(current, typeof(Guid)); IKnownFolder kf = KnownFolderHelper.FromKnownFolderIdInternal(knownFolderID); // Add to our collection if it's not null (some folders might not exist on the system // or we could have an exception that resulted in the null return from above method call if (kf != null) { foldersList.Add(kf); } } } } finally { if (folders != IntPtr.Zero) { Marshal.FreeCoTaskMem(folders); } } return new ReadOnlyCollection<IKnownFolder>(foldersList); }