/// <summary> /// Populates a structure that contains /// this known folder's properties. /// </summary> private void GetFolderProperties(IKnownFolderNative knownFolderNative) { Debug.Assert(knownFolderNative != null); KnownFoldersSafeNativeMethods.NativeFolderDefinition nativeFolderDefinition; knownFolderNative.GetFolderDefinition(out nativeFolderDefinition); try { knownFolderProperties.category = nativeFolderDefinition.category; knownFolderProperties.canonicalName = Marshal.PtrToStringUni(nativeFolderDefinition.name); knownFolderProperties.description = Marshal.PtrToStringUni(nativeFolderDefinition.description); knownFolderProperties.parentId = nativeFolderDefinition.parentId; knownFolderProperties.relativePath = Marshal.PtrToStringUni(nativeFolderDefinition.relativePath); knownFolderProperties.parsingName = Marshal.PtrToStringUni(nativeFolderDefinition.parsingName); knownFolderProperties.tooltipResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.tooltip); knownFolderProperties.localizedNameResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.localizedName); knownFolderProperties.iconResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.icon); knownFolderProperties.security = Marshal.PtrToStringUni(nativeFolderDefinition.security); knownFolderProperties.fileAttributes = (System.IO.FileAttributes)nativeFolderDefinition.attributes; knownFolderProperties.definitionOptions = nativeFolderDefinition.definitionOptions; knownFolderProperties.folderTypeId = nativeFolderDefinition.folderTypeId; knownFolderProperties.folderType = FolderTypes.GetFolderType(knownFolderProperties.folderTypeId); bool pathExists; knownFolderProperties.path = GetPath(out pathExists, knownFolderNative); knownFolderProperties.pathExists = pathExists; /* try { knownFolderProperties.redirection = knownFolderNative.GetRedirectionCapabilities(); } catch { } */ // Turn tooltip, localized name and icon resource IDs // into the actual resources. knownFolderProperties.tooltip = CoreHelpers.GetStringResource(knownFolderProperties.tooltipResourceId); knownFolderProperties.localizedName = CoreHelpers.GetStringResource(knownFolderProperties.localizedNameResourceId); knownFolderProperties.folderId = knownFolderNative.GetId(); } finally { // Clean up memory. Marshal.FreeCoTaskMem(nativeFolderDefinition.name); Marshal.FreeCoTaskMem(nativeFolderDefinition.description); Marshal.FreeCoTaskMem(nativeFolderDefinition.relativePath); Marshal.FreeCoTaskMem(nativeFolderDefinition.parsingName); Marshal.FreeCoTaskMem(nativeFolderDefinition.tooltip); Marshal.FreeCoTaskMem(nativeFolderDefinition.localizedName); Marshal.FreeCoTaskMem(nativeFolderDefinition.icon); Marshal.FreeCoTaskMem(nativeFolderDefinition.security); } }
/// <summary> /// Populates a structure that contains /// this known folder's properties. /// </summary> private void GetFolderProperties(IKnownFolderNative knownFolderNative) { Debug.Assert(knownFolderNative != null); KnownFoldersSafeNativeMethods.NativeFolderDefinition nativeFolderDefinition; knownFolderNative.GetFolderDefinition(out nativeFolderDefinition); try { knownFolderProperties.category = nativeFolderDefinition.category; knownFolderProperties.canonicalName = Marshal.PtrToStringUni(nativeFolderDefinition.name); knownFolderProperties.description = Marshal.PtrToStringUni(nativeFolderDefinition.description); knownFolderProperties.parentId = nativeFolderDefinition.parentId; knownFolderProperties.relativePath = Marshal.PtrToStringUni(nativeFolderDefinition.relativePath); knownFolderProperties.parsingName = Marshal.PtrToStringUni(nativeFolderDefinition.parsingName); knownFolderProperties.tooltipResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.tooltip); knownFolderProperties.localizedNameResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.localizedName); knownFolderProperties.iconResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.icon); knownFolderProperties.security = Marshal.PtrToStringUni(nativeFolderDefinition.security); knownFolderProperties.fileAttributes = (System.IO.FileAttributes)nativeFolderDefinition.attributes; knownFolderProperties.definitionOptions = nativeFolderDefinition.definitionOptions; knownFolderProperties.folderTypeId = nativeFolderDefinition.folderTypeId; knownFolderProperties.folderType = FolderTypes.GetFolderType(knownFolderProperties.folderTypeId); bool pathExists; knownFolderProperties.path = GetPath(out pathExists, knownFolderNative); knownFolderProperties.pathExists = pathExists; /* * try * { * knownFolderProperties.redirection = knownFolderNative.GetRedirectionCapabilities(); * } * catch * { * * } */ // Turn tooltip, localized name and icon resource IDs // into the actual resources. knownFolderProperties.tooltip = CoreHelpers.GetStringResource(knownFolderProperties.tooltipResourceId); knownFolderProperties.localizedName = CoreHelpers.GetStringResource(knownFolderProperties.localizedNameResourceId); knownFolderProperties.folderId = knownFolderNative.GetId(); } finally { // Clean up memory. Marshal.FreeCoTaskMem(nativeFolderDefinition.name); Marshal.FreeCoTaskMem(nativeFolderDefinition.description); Marshal.FreeCoTaskMem(nativeFolderDefinition.relativePath); Marshal.FreeCoTaskMem(nativeFolderDefinition.parsingName); Marshal.FreeCoTaskMem(nativeFolderDefinition.tooltip); Marshal.FreeCoTaskMem(nativeFolderDefinition.localizedName); Marshal.FreeCoTaskMem(nativeFolderDefinition.icon); Marshal.FreeCoTaskMem(nativeFolderDefinition.security); } }
// 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; KnownFoldersSafeNativeMethods.NativeFolderDefinition 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); if (nativeFolder != null) { nativeFolder.GetFolderDefinition(out definition); } Monitor.Pulse(padlock); } }); Monitor.Wait(padlock); } return(nativeFolder != null && definition.category == FolderCategory.Virtual); } finally { ShellNativeMethods.ILFree(pidl); } }
private static IKnownFolderNative GetNativeKnownFolder(IShellItem nativeShellItem, out bool isVirtual) { IntPtr pidl = IntPtr.Zero; try { // Get the PIDL for the ShellItem pidl = ShellHelper.PidlFromShellItem(nativeShellItem); if (pidl == IntPtr.Zero) { isVirtual = false; return(null); } IKnownFolderNative knownFolderNative = KnownFolderHelper.FromPIDL(pidl); if (knownFolderNative != null) { // If we have a valid IKnownFolder, try to get its category KnownFoldersSafeNativeMethods.NativeFolderDefinition nativeFolderDefinition; knownFolderNative.GetFolderDefinition(out nativeFolderDefinition); // Get the category type and see if it's virtual if (nativeFolderDefinition.category == FolderCategory.Virtual) { isVirtual = true; } else { isVirtual = false; } return(knownFolderNative); } else { // KnownFolderHelper.FromPIDL could not create a valid KnownFolder from the given PIDL. // Return null to indicate the given IShellItem is not a KnownFolder. Also set our out parameter // to default value. isVirtual = false; return(null); } } finally { ShellNativeMethods.ILFree(pidl); } }
/// <summary> /// Populates an object that contains a known folder's properties. /// </summary> public static IKnownFolderProperties GetFolderProperties(IKnownFolderNative knownFolderNative) { Debug.Assert(knownFolderNative != null); NativeFolderDefinition nativeFolderDefinition = default(NativeFolderDefinition); try { knownFolderNative.GetFolderDefinition(out nativeFolderDefinition); KnownFolderProperties knownFolderProperties = new KnownFolderProperties(knownFolderNative, nativeFolderDefinition); // Error handling - Empty Pidl indicates non-existing local folder // Let's not worry about non-exisitng local 'known' folders if (knownFolderProperties.PidlIdList.Size == 0 && knownFolderProperties.FolderId != new Guid(KF_ID.ID_FOLDERID_Desktop)) { return(default(KnownFolderProperties)); } return(knownFolderProperties); } catch { return(default(KnownFolderProperties)); } finally { // Clean up memory. ////FolderCategory category Marshal.FreeCoTaskMem(nativeFolderDefinition.name); Marshal.FreeCoTaskMem(nativeFolderDefinition.description); ////Guid parentId; Marshal.FreeCoTaskMem(nativeFolderDefinition.relativePath); Marshal.FreeCoTaskMem(nativeFolderDefinition.parsingName); Marshal.FreeCoTaskMem(nativeFolderDefinition.tooltip); Marshal.FreeCoTaskMem(nativeFolderDefinition.localizedName); Marshal.FreeCoTaskMem(nativeFolderDefinition.icon); Marshal.FreeCoTaskMem(nativeFolderDefinition.security); ////UInt32 attributes; ////DefinitionOptions definitionOptions; ////Guid folderTypeId; } }
/// <summary> /// Populates a structure that contains /// this known folder's properties. /// </summary> private void GetFolderProperties(IKnownFolderNative knownFolderNative) { Debug.Assert(knownFolderNative != null); KnownFoldersSafeNativeMethods.NativeFolderDefinition nativeFolderDefinition; knownFolderNative.GetFolderDefinition(out nativeFolderDefinition); try { knownFolderProperties.category = nativeFolderDefinition.category; knownFolderProperties.canonicalName = Marshal.PtrToStringUni(nativeFolderDefinition.name); knownFolderProperties.description = Marshal.PtrToStringUni(nativeFolderDefinition.description); knownFolderProperties.parentId = nativeFolderDefinition.parentId; knownFolderProperties.relativePath = Marshal.PtrToStringUni(nativeFolderDefinition.relativePath); knownFolderProperties.parsingName = Marshal.PtrToStringUni(nativeFolderDefinition.parsingName); knownFolderProperties.tooltipResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.tooltip); knownFolderProperties.localizedNameResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.localizedName); knownFolderProperties.iconResourceId = Marshal.PtrToStringUni(nativeFolderDefinition.icon); knownFolderProperties.security = Marshal.PtrToStringUni(nativeFolderDefinition.security); knownFolderProperties.fileAttributes = (System.IO.FileAttributes)nativeFolderDefinition.attributes; knownFolderProperties.definitionOptions = nativeFolderDefinition.definitionOptions; knownFolderProperties.folderTypeId = nativeFolderDefinition.folderTypeId; knownFolderProperties.folderType = FolderTypes.GetFolderType(knownFolderProperties.folderTypeId); bool pathExists; knownFolderProperties.path = GetPath(out pathExists, knownFolderNative); knownFolderProperties.pathExists = pathExists; knownFolderProperties.redirection = knownFolderNative.GetRedirectionCapabilities(); // Turn tooltip, localized name and icon resource IDs // into the actual resources. try { knownFolderProperties.tooltip = CoreHelpers.GetStringResource(knownFolderProperties.tooltipResourceId); } catch(Win32Exception) { // The resource ID isn't valid. This is most likely because there is no resource // defined for this KnownFolder. We should keep the default value (i.e. empty string) // and not throw an exception or set it to null. } try { knownFolderProperties.localizedName = CoreHelpers.GetStringResource(knownFolderProperties.localizedNameResourceId); } catch(Win32Exception) { // The resource ID isn't valid. This is most likely because there is no resource // defined for this KnownFolder. We should keep the default value (i.e. empty string) // and not throw an exception or set it to null. } knownFolderProperties.folderId = knownFolderNative.GetId(); } finally { // Clean up memory. Marshal.FreeCoTaskMem(nativeFolderDefinition.name); Marshal.FreeCoTaskMem(nativeFolderDefinition.description); Marshal.FreeCoTaskMem(nativeFolderDefinition.relativePath); Marshal.FreeCoTaskMem(nativeFolderDefinition.parsingName); Marshal.FreeCoTaskMem(nativeFolderDefinition.tooltip); Marshal.FreeCoTaskMem(nativeFolderDefinition.localizedName); Marshal.FreeCoTaskMem(nativeFolderDefinition.icon); Marshal.FreeCoTaskMem(nativeFolderDefinition.security); } }