diff --git a/PInvoke/Shell32/KnownFolderIdExt.cs b/PInvoke/Shell32/KnownFolderIdExt.cs
index f527735b..41b8a543 100644
--- a/PInvoke/Shell32/KnownFolderIdExt.cs
+++ b/PInvoke/Shell32/KnownFolderIdExt.cs
@@ -42,6 +42,14 @@ public static class KnownFolderIdExt
/// The instance.
public static IShellItem? GetIShellItem(this KNOWNFOLDERID id) => SHGetKnownFolderItem(id);
+ /// Returns the corresponding to the provided value.
+ /// The unique identifier representing a known folder.
+ /// A corresponding , if found. If not, an exception is thrown.
+ /// guid - Provided GUID value does not correspond to a known folder.
+ public static KNOWNFOLDERID KnownFolderId(this Guid guid) =>
+ AssociateAttribute.TryEnumLookup(guid, out var kf) ? kf :
+ throw new ArgumentOutOfRangeException(nameof(guid), "Provided GUID value does not correspond to a known folder.");
+
/// Gets a registry property associated with this known folder.
/// Return type.
/// The known folder.
diff --git a/PInvoke/Shell32/ShObjIdl.IKnownFolder.cs b/PInvoke/Shell32/ShObjIdl.IKnownFolder.cs
index 3df53425..28a870f8 100644
--- a/PInvoke/Shell32/ShObjIdl.IKnownFolder.cs
+++ b/PInvoke/Shell32/ShObjIdl.IKnownFolder.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
namespace Vanara.PInvoke;
@@ -1773,11 +1774,12 @@ public static partial class Shell32
// https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nf-shobjidl_core-freeknownfolderdefinitionfields void
// FreeKnownFolderDefinitionFields( KNOWNFOLDER_DEFINITION *pKFD );
[PInvokeData("shobjidl_core.h", MSDNShortId = "0ad17dd3-e612-403a-b8c3-e93d5f259c1f")]
- public static void FreeKnownFolderDefinitionFields(in KNOWNFOLDER_DEFINITION pKFD)
- {
- foreach (var fi in pKFD.GetType().GetFields().Where(f => f.FieldType == typeof(StrPtrUni)))
- Marshal.FreeCoTaskMem((IntPtr)(StrPtrUni)fi.GetValue(pKFD)!);
- }
+ [Obsolete("Unnecessary when using PInvoke since values are freed when converting to System.String. This method does nothing.")]
+ public static void FreeKnownFolderDefinitionFields(in KNOWNFOLDER_DEFINITION pKFD) { }
+ //{
+ // foreach (var fi in pKFD.GetType().GetFields().Where(f => f.FieldType == typeof(StrPtrUni)))
+ // Marshal.FreeCoTaskMem((IntPtr)(StrPtrUni)fi.GetValue(pKFD)!);
+ //}
/// Gets an array of all registered known folder IDs. This can be used in enumerating all known folders.
/// The instance.
@@ -1826,13 +1828,15 @@ public static partial class Shell32
/// settings. This name is meant to be a unique, human-readable name. Third parties are recommended to follow the format
/// Company.Application.Name. The name given here should not be confused with the display name.
///
- public StrPtrUni pszName;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string pszName;
///
/// A pointer to a short description of the known folder, stored as a null-terminated Unicode string. This description should
/// include the folder's purpose and usage.
///
- public StrPtrUni pszDescription;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string pszDescription;
///
/// A KNOWNFOLDERID value that names another known folder to serve as the parent folder. Applies to common and per-user folders
@@ -1841,18 +1845,32 @@ public static partial class Shell32
///
public Guid fidParent;
+ ///
+ /// A KNOWNFOLDERID enumeration value that names another known folder to serve as the parent folder. Applies to common and per-user
+ /// folders only. This value is used in conjunction with pszRelativePath. See Remarks for more details. This value is optional if no
+ /// value is provided for pszRelativePath. On retrieval, if the value does not map to an enuumeration value, a
+ /// is returned. If a is provided when setting, it maps to .
+ ///
+ public KNOWNFOLDERID? fidParentEnum
+ {
+ readonly get => AssociateAttribute.TryEnumLookup(fidParent, out KNOWNFOLDERID kf) ? kf : null;
+ set => fidParent = value.HasValue ? value.Value.Guid() : Guid.Empty;
+ }
+
///
/// Optional. A pointer to a path relative to the parent folder specified in fidParent. This is a null-terminated Unicode
/// string, refers to the physical file system path, and is not localized. Applies to common and per-user folders only. See
/// Remarks for more details.
///
- public StrPtrUni pszRelativePath;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string? pszRelativePath;
///
/// A pointer to the Shell namespace folder path of the folder, stored as a null-terminated Unicode string. Applies to virtual
/// folders only. For example, Control Panel has a parsing name of ::%CLSID_MyComputer%\::%CLSID_ControlPanel%.
///
- public StrPtrUni pszParsingName;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string pszParsingName;
///
/// Optional. A pointer to the default tooltip resource used for this known folder when it is created. This is a null-terminated
@@ -1864,7 +1882,8 @@ public static partial class Shell32
///
/// This information is not required for virtual folders.
///
- public StrPtrUni pszTooltip;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string? pszTooltip;
///
/// Optional. A pointer to the default localized name resource used when the folder is created. This is a null-terminated
@@ -1876,7 +1895,8 @@ public static partial class Shell32
///
/// This information is not required for virtual folders.
///
- public StrPtrUni pszLocalizedName;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string? pszLocalizedName;
///
/// Optional. A pointer to the default icon resource used when the folder is created. This is a null-terminated Unicode string
@@ -1888,7 +1908,8 @@ public static partial class Shell32
///
/// This information is not required for virtual folders.
///
- public StrPtrUni pszIcon;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string? pszIcon;
///
/// Optional. A pointer to a Security Descriptor Definition Language format string. This is a null-terminated Unicode string
@@ -1896,7 +1917,8 @@ public static partial class Shell32
/// new folder inherits the security descriptor of its parent. This is particularly useful for common folders that are accessed
/// by all users.
///
- public StrPtrUni pszSecurity;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string? pszSecurity;
///
/// Optional. Default file system attributes given to the folder when it is created. For example, the file could be hidden and
@@ -1917,24 +1939,15 @@ public static partial class Shell32
///
public Guid ftidType;
- /// Frees the allocated fields in the result from IKnownFolder::GetFolderDefinition.
- ///
- /// This is an inline helper function that calls CoTaskMemFree on the fields in the structure that need to be freed. Its
- /// implementation can be seen in the header file.
- ///
- // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-freeknownfolderdefinitionfields void
- // FreeKnownFolderDefinitionFields( KNOWNFOLDER_DEFINITION *pKFD );
- [PInvokeData("shobjidl_core.h", MSDNShortId = "NF:shobjidl_core.FreeKnownFolderDefinitionFields")]
- public void FreeKnownFolderDefinitionFields()
+ ///
+ /// One of the FOLDERTYPEID enumeration values that identifies the known folder type based on its contents (such as documents, music,
+ /// or photographs). On retrieval, if the value does not map to an enuumeration value, a is returned. If a
+ /// is provided when setting, it maps to .
+ ///
+ public FOLDERTYPEID? ftidTypeEnum
{
- Marshal.FreeCoTaskMem((IntPtr)pszName);
- Marshal.FreeCoTaskMem((IntPtr)pszDescription);
- Marshal.FreeCoTaskMem((IntPtr)pszRelativePath);
- Marshal.FreeCoTaskMem((IntPtr)pszParsingName);
- Marshal.FreeCoTaskMem((IntPtr)pszTooltip);
- Marshal.FreeCoTaskMem((IntPtr)pszLocalizedName);
- Marshal.FreeCoTaskMem((IntPtr)pszIcon);
- Marshal.FreeCoTaskMem((IntPtr)pszSecurity);
+ readonly get => AssociateAttribute.TryEnumLookup(ftidType, out FOLDERTYPEID kf) ? kf : null;
+ set => ftidType = value.HasValue ? value.Value.Guid() : Guid.Empty;
}
}
@@ -1951,6 +1964,14 @@ public static partial class Shell32
/// Initializes a new instance of the class with a GUID for the .
/// The GUID for the .
- public KnownFolderDetailAttribute(string knownFolderGuid) : base(knownFolderGuid) { }
+ public KnownFolderDetailAttribute(string knownFolderGuid) : base(knownFolderGuid)
+ {
+ if (TryEnumLookup(Guid, out var kf))
+ {
+ var sf = kf.SpecialFolder();
+ if (sf.HasValue)
+ Equivalent = sf.Value;
+ }
+ }
}
}
\ No newline at end of file