using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace Framework.Support {
/// Helper methods for invoking the Windows shell API
public static class ShellApiHelper {
/// Special folder id of the user's 'My Documents' folder
public const int CSIDL_PERSONAL = 0x0005;
/// ID of the 'Saved Games' folder in the known folder manager
public static readonly Guid FOLDERID_SavedGames = new Guid(
0x4c5c32ff, 0xbb9d, 0x43b0, 0xb5, 0xb4, 0x2d, 0x72, 0xe5, 0x4e, 0xaa, 0xa4
);
/// Maximum buffer size most Win32 API functions expect
private const int MAX_PATH = 260;
/// COM ClassID of the KnownFolderManager proxy coclass
private const string CLSID_KnownFolderManager = "4df0c730-df9d-4ae3-9153-aa6b82e9795a";
/// COM InterfaceID of the IKnownFolder interface
private const string IID_IKnownFolder = "3aa7af7e-9b36-420c-a8e3-f77d4674a488";
/// COM InterfaceID of the IKnownFolderManager interface
private const string IID_IKnownFolderManager = "8be2d872-86aa-4d47-b776-32cca40c7018";
/// Retrieves the path of a special folder, identified by its CSIDL
/// Not used, always set to IntPtr.Zero
/// Received the drive and path o the specified folder
///
/// CSIDL that identifies that folder whose path will be retrieved
///
///
/// Whether the folder should be created if it doesn't exist
///
/// Any nonzero value if successful, otherwise 0
[DllImport("Shell32", CharSet = CharSet.Unicode)]
private static extern int SHGetSpecialFolderPath(
IntPtr ownerWindowHandle,
StringBuilder path,
int folderId,
int createFlag
);
#region interface IKnownFolder
/// Accesses informations about a known folder, including its path
[
ComImport,
Guid(IID_IKnownFolder),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
private interface IKnownFolder {
/// GetId() is not provided
void GetId_Stub();
/// GetCategory() is not provided
void GetCategory_Stub();
/// GetShellItem() is not provided
void GetShellItem_Stub();
/// Retrieves the path of a known folder as a string
///
/// Flags that specify special retrieval options. This value can be 0;
/// otherwise, one or more of the KNOWN_FOLDER_FLAG values
///
///
/// Receives a pointer to a null-terminated buffer that contains the path
///
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetPath([In] uint flags, [MarshalAs(UnmanagedType.LPWStr)] out string path);
/// SetPath() is not provided
void SetPath_Stub();
/// GetLocation() is not provided
void GetLocation_Stub();
/// GetFolderType() is not provided
void GetFolderType_Stub();
/// GetRedirectionCapabilities() is not provided
void GetRedirectionCapabilities_Stub();
/// GetFolderDefinition() is not provided
void GetFolderDefinition_Stub();
}
#endregion // interface IKnownFolder
#region interface IKnownFolderManager
/// Enumerates, creates and manages known folders
[
ComImport,
Guid(IID_IKnownFolderManager),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
private interface IKnownFolderManager {
/// FolderIdFromCsidl() is not provided
void FolderIdFromCsidl_Stub();
/// FolderIdToCsidl() is not provided
void FolderIdToCsidl_Stub();
/// GetFolderIds() is not provided
void GetFolderIds_Stub();
/// Retrieves informations about a known folder by its id
///
/// Id of the known folder whose informations will be retrieved
///
/// Receives the known folder information instance
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFolder(
[In] ref Guid folderId,
[MarshalAs(UnmanagedType.Interface)] out IKnownFolder knownFolder
);
/// GetFolderByName() is not provided
void GetFolderByName_Stub();
/// RegisterFolder() is not provided
void RegisterFolder_Stub();
/// UnregisterFolder() is not provided
void UnregisterFolder_Stub();
/// FindFolderFromPath() is not provided
void FindFolderFromPath_Stub();
/// FindFolderFromIDList() is not provided
void FindFolderFromIDList_Stub();
/// Redirect() is not provided
void Redirect_Stub();
}
#endregion // interface IKnownFolderManager
#region class KnownFolderManagerImpl
/// KnownFolderManager proxy coclass
[ComImport, Guid(CLSID_KnownFolderManager)]
internal class KnownFolderManagerImpl { }
#endregion // class KnownFolderManagerImpl
/// Retrieves the path of a special folder by its CSIDL
///
/// CSIDL of the special folder whose path will be retrieved
///
/// The path of the special folder with the specified CSIDL
public static string GetSpecialFolder(int folderId) {
var path = new StringBuilder(MAX_PATH);
int result = SHGetSpecialFolderPath(IntPtr.Zero, path, folderId, 1);
if(result == 0) {
throw new Win32Exception("Could not query special folder path");
}
return path.ToString();
}
/// Retrieves the path of a known folder
/// GUID of the known folderparam>
/// The path of the known folder with the specified GUID
public static string GetKnownFolder(Guid knownFolderId) {
var instance = new KnownFolderManagerImpl();
if(instance == null) {
throw new COMException("Could not create instance of known folder manager coclass");
}
IKnownFolderManager knownFolderManager = (IKnownFolderManager)instance as IKnownFolderManager;
if(knownFolderManager == null) {
throw new COMException("Could not query known folder manager interface");
}
IKnownFolder knownFolder;
knownFolderManager.GetFolder(ref knownFolderId, out knownFolder);
if(knownFolder == null) {
throw new COMException("Could not query known folder");
}
string path;
knownFolder.GetPath(0, out path);
return path;
}
}
} // namespace Framework.Support