create a setup builder impl from MicaSetup

This commit is contained in:
ema
2023-12-04 01:36:02 +08:00
parent edc597a19a
commit a6891e29dc
465 changed files with 34946 additions and 75 deletions

View File

@@ -0,0 +1,8 @@
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
internal static class IntPtrExtensions
{
public static T MarshalAs<T>(this nint ptr) => (T)Marshal.PtrToStructure(ptr, typeof(T));
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
[ComImport,
Guid(ShellIIDGuid.IShellLibrary),
CoClass(typeof(ShellLibraryCoClass))]
internal interface INativeShellLibrary : IShellLibrary
{
}
[ComImport,
ClassInterface(ClassInterfaceType.None),
TypeLibType(TypeLibTypeFlags.FCanCreate),
Guid(ShellCLSIDGuid.ShellLibrary)]
internal class ShellLibraryCoClass
{
}

View File

@@ -0,0 +1,72 @@
namespace MicaSetup.Shell.Dialogs;
internal static class ShellBHIDGuid
{
internal const string ShellFolderObject = "3981e224-f559-11d3-8e3a-00c04f6837d5";
}
internal static class ShellCLSIDGuid
{
internal const string ConditionFactory = "E03E85B0-7BE3-4000-BA98-6C13DE9FA486";
internal const string FileOpenDialog = "DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7";
internal const string FileSaveDialog = "C0B4E2F3-BA21-4773-8DBA-335EC946EB8B";
internal const string KnownFolderManager = "4DF0C730-DF9D-4AE3-9153-AA6B82E9795A";
internal const string QueryParserManager = "5088B39A-29B4-4d9d-8245-4EE289222F66";
internal const string SearchFolderItemFactory = "14010e02-bbbd-41f0-88e3-eda371216584";
internal const string ShellLibrary = "D9B3211D-E57F-4426-AAEF-30A806ADD397";
}
internal static class ShellIIDGuid
{
internal const string CShellLink = "00021401-0000-0000-C000-000000000046";
internal const string ICondition = "0FC988D4-C935-4b97-A973-46282EA175C8";
internal const string IConditionFactory = "A5EFE073-B16F-474f-9F3E-9F8B497A3E08";
internal const string IEnumIDList = "000214F2-0000-0000-C000-000000000046";
internal const string IEnumUnknown = "00000100-0000-0000-C000-000000000046";
internal const string IFileDialog = "42F85136-DB7E-439C-85F1-E4075D135FC8";
internal const string IFileDialogControlEvents = "36116642-D713-4B97-9B83-7484A9D00433";
internal const string IFileDialogCustomize = "E6FDD21A-163F-4975-9C8C-A69F1BA37034";
internal const string IFileDialogEvents = "973510DB-7D7F-452B-8975-74A85828D354";
internal const string IFileOpenDialog = "D57C7288-D4AD-4768-BE02-9D969532D960";
internal const string IFileSaveDialog = "84BCCD23-5FDE-4CDB-AEA4-AF64B83D78AB";
internal const string IModalWindow = "B4DB1657-70D7-485E-8E3E-6FCB5A5C1802";
internal const string IPersist = "0000010c-0000-0000-C000-000000000046";
internal const string IPersistStream = "00000109-0000-0000-C000-000000000046";
internal const string IPropertyDescription = "6F79D558-3E96-4549-A1D1-7D75D2288814";
internal const string IPropertyDescription2 = "57D2EDED-5062-400E-B107-5DAE79FE57A6";
internal const string IPropertyDescriptionList = "1F9FC1D0-C39B-4B26-817F-011967D3440E";
internal const string IPropertyEnumType = "11E1FBF9-2D56-4A6B-8DB3-7CD193A471F2";
internal const string IPropertyEnumType2 = "9B6E051C-5DDD-4321-9070-FE2ACB55E794";
internal const string IPropertyEnumTypeList = "A99400F4-3D84-4557-94BA-1242FB2CC9A6";
internal const string IPropertyStore = "886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99";
internal const string IPropertyStoreCache = "3017056d-9a91-4e90-937d-746c72abbf4f";
internal const string IPropertyStoreCapabilities = "c8e2d566-186e-4d49-bf41-6909ead56acc";
internal const string IQueryParser = "2EBDEE67-3505-43f8-9946-EA44ABC8E5B0";
internal const string IQueryParserManager = "A879E3C4-AF77-44fb-8F37-EBD1487CF920";
internal const string IQuerySolution = "D6EBC66B-8921-4193-AFDD-A1789FB7FF57";
internal const string IRichChunk = "4FDEF69C-DBC9-454e-9910-B34F3C64B510";
internal const string ISearchFolderItemFactory = "a0ffbc28-5482-4366-be27-3e81e78e06c2";
internal const string ISharedBitmap = "091162a4-bc96-411f-aae8-c5122cd03363";
internal const string IShellFolder = "000214E6-0000-0000-C000-000000000046";
internal const string IShellFolder2 = "93F2F68C-1D1B-11D3-A30E-00C04F79ABD1";
internal const string IShellItem = "43826D1E-E718-42EE-BC55-A1E261C37BFE";
internal const string IShellItem2 = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
internal const string IShellItemArray = "B63EA76D-1F85-456F-A19C-48159EFA858B";
internal const string IShellLibrary = "11A66EFA-382E-451A-9234-1E0E12EF3085";
internal const string IShellLinkW = "000214F9-0000-0000-C000-000000000046";
internal const string IThumbnailCache = "F676C15D-596A-4ce2-8234-33996F445DB1";
}
internal static class ShellKFIDGuid
{
internal const string ComputerFolder = "0AC0837C-BBF8-452A-850D-79D08E667CA7";
internal const string Documents = "FDD39AD0-238F-46AF-ADB4-6C85480369C7";
internal const string DocumentsLibrary = "7d49d726-3c21-4f05-99aa-fdc2c9474656";
internal const string Favorites = "1777F761-68AD-4D8A-87BD-30B759FA33DD";
internal const string GenericLibrary = "5c4f28b5-f869-4e84-8e60-f11db97c5cc7";
internal const string Libraries = "1B3EA5DC-B587-4786-B4EF-BD1DC332AEAE";
internal const string MusicLibrary = "94d6ddcc-4a68-4175-a374-bd584a510b78";
internal const string PicturesLibrary = "b3690e58-e961-423b-b687-386ebfd83239";
internal const string Profile = "5E6C858F-0E22-4760-9AFE-EA3317B67173";
internal const string VideosLibrary = "5fa96407-7e77-483c-ac93-691d05850de8";
}

View File

@@ -0,0 +1,774 @@
using MicaSetup.Natives;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
namespace MicaSetup.Shell.Dialogs;
#pragma warning disable CS0108
public enum SICHINTF
{
SICHINT_DISPLAY = 0x00000000,
SICHINT_CANONICAL = 0x10000000,
SICHINT_TEST_FILESYSPATH_IF_NOT_EQUAL = 0x20000000,
SICHINT_ALLFIELDS = unchecked((int)0x80000000)
}
[ComImport(),
Guid(ShellIIDGuid.ICondition),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICondition : IPersistStream
{
[PreserveSig]
void GetClassID(out Guid pClassID);
[PreserveSig]
HResult IsDirty();
[PreserveSig]
HResult Load([In, MarshalAs(UnmanagedType.Interface)] IStream stm);
[PreserveSig]
HResult Save([In, MarshalAs(UnmanagedType.Interface)] IStream stm, bool fRemember);
[PreserveSig]
HResult GetSizeMax(out ulong cbSize);
[PreserveSig]
HResult GetConditionType([Out()] out SearchConditionType pNodeType);
[PreserveSig]
HResult GetSubConditions([In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppv);
[PreserveSig]
HResult GetComparisonInfo(
[Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszPropertyName,
[Out] out SearchConditionOperation pcop,
[Out] PropVariant ppropvar);
[PreserveSig]
HResult GetValueType([Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszValueTypeName);
[PreserveSig]
HResult GetValueNormalization([Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszNormalization);
[PreserveSig]
HResult GetInputTerms([Out] out IRichChunk ppPropertyTerm, [Out] out IRichChunk ppOperationTerm, [Out] out IRichChunk ppValueTerm);
[PreserveSig]
HResult Clone([Out()] out ICondition ppc);
};
[ComImport,
Guid(ShellIIDGuid.IConditionFactory),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IConditionFactory
{
[PreserveSig]
HResult MakeNot([In] ICondition pcSub, [In] bool fSimplify, [Out] out ICondition ppcResult);
[PreserveSig]
HResult MakeAndOr([In] SearchConditionType ct, [In] IEnumUnknown peuSubs, [In] bool fSimplify, [Out] out ICondition ppcResult);
[PreserveSig]
HResult MakeLeaf(
[In, MarshalAs(UnmanagedType.LPWStr)] string pszPropertyName,
[In] SearchConditionOperation cop,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszValueType,
[In] PropVariant ppropvar,
IRichChunk richChunk1,
IRichChunk richChunk2,
IRichChunk richChunk3,
[In] bool fExpand,
[Out] out ICondition ppcResult);
[PreserveSig]
HResult Resolve();
};
[ComImport,
Guid("24264891-E80B-4fd3-B7CE-4FF2FAE8931F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEntity
{
}
[ComImport,
Guid(ShellIIDGuid.IEnumIDList),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumIDList
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Next(uint celt, out nint rgelt, out uint pceltFetched);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Skip([In] uint celt);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Reset();
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Clone([MarshalAs(UnmanagedType.Interface)] out IEnumIDList ppenum);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid(ShellIIDGuid.IEnumUnknown)]
public interface IEnumUnknown
{
[PreserveSig]
HResult Next(uint requestedNumber, ref nint buffer, ref uint fetchedNumber);
[PreserveSig]
HResult Skip(uint number);
[PreserveSig]
HResult Reset();
[PreserveSig]
HResult Clone(out IEnumUnknown result);
}
[ComImport(),
Guid(ShellIIDGuid.IModalWindow),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IModalWindow
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime),
PreserveSig]
int Show([In] nint parent);
}
[ComImport,
Guid(ShellIIDGuid.IConditionFactory),
CoClass(typeof(ConditionFactoryCoClass))]
public interface INativeConditionFactory : IConditionFactory
{
}
[ComImport,
Guid(ShellIIDGuid.IQueryParserManager),
CoClass(typeof(QueryParserManagerCoClass))]
public interface INativeQueryParserManager : IQueryParserManager
{
}
[ComImport,
Guid(ShellIIDGuid.ISearchFolderItemFactory),
CoClass(typeof(SearchFolderItemFactoryCoClass))]
public interface INativeSearchFolderItemFactory : ISearchFolderItemFactory
{
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("00000109-0000-0000-C000-000000000046")]
public interface IPersistStream
{
[PreserveSig]
void GetClassID(out Guid pClassID);
[PreserveSig]
HResult IsDirty();
[PreserveSig]
HResult Load([In, MarshalAs(UnmanagedType.Interface)] IStream stm);
[PreserveSig]
HResult Save([In, MarshalAs(UnmanagedType.Interface)] IStream stm, bool fRemember);
[PreserveSig]
HResult GetSizeMax(out ulong cbSize);
}
[ComImport,
Guid(ShellIIDGuid.IQueryParser),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IQueryParser
{
[PreserveSig]
HResult Parse([In, MarshalAs(UnmanagedType.LPWStr)] string pszInputString, [In] IEnumUnknown pCustomProperties, [Out] out IQuerySolution ppSolution);
[PreserveSig]
HResult SetOption([In] StructuredQuerySingleOption option, [In] PropVariant pOptionValue);
[PreserveSig]
HResult GetOption([In] StructuredQuerySingleOption option, [Out] PropVariant pOptionValue);
[PreserveSig]
HResult SetMultiOption([In] StructuredQueryMultipleOption option, [In, MarshalAs(UnmanagedType.LPWStr)] string pszOptionKey, [In] PropVariant pOptionValue);
[PreserveSig]
HResult GetSchemaProvider([Out] out nint ppSchemaProvider);
[PreserveSig]
HResult RestateToString([In] ICondition pCondition, [In] bool fUseEnglish, [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszQueryString);
[PreserveSig]
HResult ParsePropertyValue([In, MarshalAs(UnmanagedType.LPWStr)] string pszPropertyName, [In, MarshalAs(UnmanagedType.LPWStr)] string pszInputString, [Out] out IQuerySolution ppSolution);
[PreserveSig]
HResult RestatePropertyValueToString([In] ICondition pCondition, [In] bool fUseEnglish, [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszPropertyName, [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszQueryString);
}
[ComImport,
Guid(ShellIIDGuid.IQueryParserManager),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IQueryParserManager
{
[PreserveSig]
HResult CreateLoadedParser([In, MarshalAs(UnmanagedType.LPWStr)] string pszCatalog, [In] ushort langidForKeywords, [In] ref Guid riid, [Out] out IQueryParser ppQueryParser);
[PreserveSig]
HResult InitializeOptions([In] bool fUnderstandNQS, [In] bool fAutoWildCard, [In] IQueryParser pQueryParser);
[PreserveSig]
HResult SetOption([In] QueryParserManagerOption option, [In] PropVariant pOptionValue);
};
[ComImport,
Guid(ShellIIDGuid.IQuerySolution),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IQuerySolution : IConditionFactory
{
[PreserveSig]
HResult MakeNot([In] ICondition pcSub, [In] bool fSimplify, [Out] out ICondition ppcResult);
[PreserveSig]
HResult MakeAndOr([In] SearchConditionType ct, [In] IEnumUnknown peuSubs, [In] bool fSimplify, [Out] out ICondition ppcResult);
[PreserveSig]
HResult MakeLeaf(
[In, MarshalAs(UnmanagedType.LPWStr)] string pszPropertyName,
[In] SearchConditionOperation cop,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszValueType,
[In] PropVariant ppropvar,
IRichChunk richChunk1,
IRichChunk richChunk2,
IRichChunk richChunk3,
[In] bool fExpand,
[Out] out ICondition ppcResult);
[PreserveSig]
HResult Resolve();
[PreserveSig]
HResult GetQuery([Out, MarshalAs(UnmanagedType.Interface)] out ICondition ppQueryNode, [Out, MarshalAs(UnmanagedType.Interface)] out IEntity ppMainType);
[PreserveSig]
HResult GetErrors([In] ref Guid riid, [Out] out nint ppParseErrors);
[PreserveSig]
HResult GetLexicalData([MarshalAs(UnmanagedType.LPWStr)] out string ppszInputString, [Out] out nint ppTokens, [Out] out uint plcid, [Out] /* IUnknown** */ out nint ppWordBreaker);
}
[ComImport,
Guid(ShellIIDGuid.IRichChunk),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRichChunk
{
[PreserveSig]
HResult GetData();
}
[ComImport,
Guid(ShellIIDGuid.ISearchFolderItemFactory),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISearchFolderItemFactory
{
[PreserveSig]
HResult SetScope([In, MarshalAs(UnmanagedType.Interface)] IShellItemArray ppv);
[PreserveSig]
HResult SetCondition([In] ICondition pCondition);
[PreserveSig]
int GetShellItem(ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);
};
[ComImport,
Guid(ShellIIDGuid.ISharedBitmap),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISharedBitmap
{
void GetSharedBitmap([Out] out nint phbm);
void GetSize([Out] out SIZE pSize);
void GetFormat([Out] out ThumbnailAlphaType pat);
void InitializeBitmap([In] nint hbm, [In] ThumbnailAlphaType wtsAT);
void Detach([Out] out nint phbm);
}
[ComImport,
Guid(ShellIIDGuid.IShellFolder),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComConversionLoss]
public interface IShellFolder
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ParseDisplayName(nint hwnd, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In, MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName, [In, Out] ref uint pchEaten, [Out] nint ppidl, [In, Out] ref uint pdwAttributes);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult EnumObjects([In] nint hwnd, [In] ShellFolderEnumerationOptions grfFlags, [MarshalAs(UnmanagedType.Interface)] out IEnumIDList ppenumIDList);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult BindToObject([In] nint pidl, nint pbc, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IShellFolder ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void BindToStorage([In] ref nint pidl, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In] ref Guid riid, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void CompareIDs([In] nint lParam, [In] ref nint pidl1, [In] ref nint pidl2);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void CreateViewObject([In] nint hwndOwner, [In] ref Guid riid, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAttributesOf([In] uint cidl, [In] nint apidl, [In, Out] ref uint rgfInOut);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetUIObjectOf([In] nint hwndOwner, [In] uint cidl, [In] nint apidl, [In] ref Guid riid, [In, Out] ref uint rgfReserved, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDisplayNameOf([In] ref nint pidl, [In] uint uFlags, out nint pName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetNameOf([In] nint hwnd, [In] ref nint pidl, [In, MarshalAs(UnmanagedType.LPWStr)] string pszName, [In] uint uFlags, [Out] nint ppidlOut);
}
[ComImport,
Guid(ShellIIDGuid.IShellFolder2),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComConversionLoss]
public interface IShellFolder2 : IShellFolder
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ParseDisplayName([In] nint hwnd, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In, MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName, [In, Out] ref uint pchEaten, [Out] nint ppidl, [In, Out] ref uint pdwAttributes);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void EnumObjects([In] nint hwnd, [In] ShellFolderEnumerationOptions grfFlags, [MarshalAs(UnmanagedType.Interface)] out IEnumIDList ppenumIDList);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void BindToObject([In] nint pidl, nint pbc, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IShellFolder ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void BindToStorage([In] ref nint pidl, [In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc, [In] ref Guid riid, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void CompareIDs([In] nint lParam, [In] ref nint pidl1, [In] ref nint pidl2);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void CreateViewObject([In] nint hwndOwner, [In] ref Guid riid, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAttributesOf([In] uint cidl, [In] nint apidl, [In, Out] ref uint rgfInOut);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetUIObjectOf([In] nint hwndOwner, [In] uint cidl, [In] nint apidl, [In] ref Guid riid, [In, Out] ref uint rgfReserved, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDisplayNameOf([In] ref nint pidl, [In] uint uFlags, out nint pName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetNameOf([In] nint hwnd, [In] ref nint pidl, [In, MarshalAs(UnmanagedType.LPWStr)] string pszName, [In] uint uFlags, [Out] nint ppidlOut);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDefaultSearchGUID(out Guid pguid);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void EnumSearches([Out] out nint ppenum);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDefaultColumn([In] uint dwRes, out uint pSort, out uint pDisplay);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDefaultColumnState([In] uint iColumn, out uint pcsFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDetailsEx([In] ref nint pidl, [In] ref PropertyKey pscid, [MarshalAs(UnmanagedType.Struct)] out object pv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDetailsOf([In] ref nint pidl, [In] uint iColumn, out nint psd);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void MapColumnToSCID([In] uint iColumn, out PropertyKey pscid);
}
[ComImport,
Guid(ShellIIDGuid.IShellItem),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItem
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult BindToHandler(
[In] nint pbc,
[In] ref Guid bhid,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out IShellFolder ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetDisplayName(
[In] ShellItemDesignNameOptions sigdnName,
out nint ppszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAttributes([In] ShellFileGetAttributesOptions sfgaoMask, out ShellFileGetAttributesOptions psfgaoAttribs);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Compare(
[In, MarshalAs(UnmanagedType.Interface)] IShellItem psi,
[In] SICHINTF hint,
out int piOrder);
}
[ComImport,
Guid(ShellIIDGuid.IShellItem2),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItem2 : IShellItem
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult BindToHandler(
[In] nint pbc,
[In] ref Guid bhid,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out IShellFolder ppv);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetDisplayName(
[In] ShellItemDesignNameOptions sigdnName,
[MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAttributes([In] ShellFileGetAttributesOptions sfgaoMask, out ShellFileGetAttributesOptions psfgaoAttribs);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Compare(
[In, MarshalAs(UnmanagedType.Interface)] IShellItem psi,
[In] uint hint,
out int piOrder);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
int GetPropertyStore(
[In] GetPropertyStoreOptions Flags,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out IPropertyStore ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetPropertyStoreWithCreateObject([In] GetPropertyStoreOptions Flags, [In, MarshalAs(UnmanagedType.IUnknown)] object punkCreateObject, [In] ref Guid riid, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetPropertyStoreForKeys([In] ref PropertyKey rgKeys, [In] uint cKeys, [In] GetPropertyStoreOptions Flags, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out IPropertyStore ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetPropertyDescriptionList([In] ref PropertyKey keyType, [In] ref Guid riid, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Update([In, MarshalAs(UnmanagedType.Interface)] IBindCtx pbc);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetProperty([In] ref PropertyKey key, [Out] PropVariant ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCLSID([In] ref PropertyKey key, out Guid pclsid);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFileTime([In] ref PropertyKey key, out System.Runtime.InteropServices.ComTypes.FILETIME pft);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetInt32([In] ref PropertyKey key, out int pi);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetString([In] ref PropertyKey key, [MarshalAs(UnmanagedType.LPWStr)] out string ppsz);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetUInt32([In] ref PropertyKey key, out uint pui);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetUInt64([In] ref PropertyKey key, out ulong pull);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetBool([In] ref PropertyKey key, out int pf);
}
[ComImport,
Guid(ShellIIDGuid.IShellItemArray),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItemArray
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult BindToHandler(
[In, MarshalAs(UnmanagedType.Interface)] nint pbc,
[In] ref Guid rbhid,
[In] ref Guid riid,
out nint ppvOut);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetPropertyStore(
[In] int Flags,
[In] ref Guid riid,
out nint ppv);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetPropertyDescriptionList(
[In] ref PropertyKey keyType,
[In] ref Guid riid,
out nint ppv);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetAttributes(
[In] ShellItemAttributeOptions dwAttribFlags,
[In] ShellFileGetAttributesOptions sfgaoMask,
out ShellFileGetAttributesOptions psfgaoAttribs);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetCount(out uint pdwNumItems);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetItemAt(
[In] uint dwIndex,
[MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult EnumItems([MarshalAs(UnmanagedType.Interface)] out nint ppenumShellItems);
}
[ComImportAttribute()]
[GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItemImageFactory
{
[PreserveSig]
HResult GetImage(
[In, MarshalAs(UnmanagedType.Struct)] SIZE size,
[In] SIIGBF flags,
[Out] out nint phbm);
}
[ComImport,
Guid(ShellIIDGuid.IShellLibrary),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellLibrary
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult LoadLibraryFromItem(
[In, MarshalAs(UnmanagedType.Interface)] IShellItem library,
[In] AccessModes grfMode);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void LoadLibraryFromKnownFolder(
[In] ref Guid knownfidLibrary,
[In] AccessModes grfMode);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem location);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void RemoveFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem location);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetFolders(
[In] LibraryFolderFilter lff,
[In] ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ResolveFolder(
[In, MarshalAs(UnmanagedType.Interface)] IShellItem folderToResolve,
[In] uint timeout,
[In] ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDefaultSaveFolder(
[In] DefaultSaveFolderType dsft,
[In] ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetDefaultSaveFolder(
[In] DefaultSaveFolderType dsft,
[In, MarshalAs(UnmanagedType.Interface)] IShellItem si);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetOptions(
out LibraryOptions lofOptions);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetOptions(
[In] LibraryOptions lofMask,
[In] LibraryOptions lofOptions);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFolderType(out Guid ftid);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFolderType([In] ref Guid ftid);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetIcon([MarshalAs(UnmanagedType.LPWStr)] out string icon);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetIcon([In, MarshalAs(UnmanagedType.LPWStr)] string icon);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Commit();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Save(
[In, MarshalAs(UnmanagedType.Interface)] IShellItem folderToSaveIn,
[In, MarshalAs(UnmanagedType.LPWStr)] string libraryName,
[In] LibrarySaveOptions lsf,
[MarshalAs(UnmanagedType.Interface)] out IShellItem2 savedTo);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SaveInKnownFolder(
[In] ref Guid kfidToSaveIn,
[In, MarshalAs(UnmanagedType.LPWStr)] string libraryName,
[In] LibrarySaveOptions lsf,
[MarshalAs(UnmanagedType.Interface)] out IShellItem2 savedTo);
};
[ComImport,
Guid(ShellIIDGuid.IShellLinkW),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellLinkW
{
void GetPath(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,
int cchMaxPath,
nint pfd,
uint fFlags);
void GetIDList(out nint ppidl);
void SetIDList(nint pidl);
void GetDescription(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,
int cchMaxName);
void SetDescription(
[MarshalAs(UnmanagedType.LPWStr)] string pszName);
void GetWorkingDirectory(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir,
int cchMaxPath
);
void SetWorkingDirectory(
[MarshalAs(UnmanagedType.LPWStr)] string pszDir);
void GetArguments(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs,
int cchMaxPath);
void SetArguments(
[MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
void GetHotKey(out short wHotKey);
void SetHotKey(short wHotKey);
void GetShowCmd(out uint iShowCmd);
void SetShowCmd(uint iShowCmd);
void GetIconLocation(
[Out(), MarshalAs(UnmanagedType.LPWStr)] out StringBuilder pszIconPath,
int cchIconPath,
out int iIcon);
void SetIconLocation(
[MarshalAs(UnmanagedType.LPWStr)] string pszIconPath,
int iIcon);
void SetRelativePath(
[MarshalAs(UnmanagedType.LPWStr)] string pszPathRel,
uint dwReserved);
void Resolve(nint hwnd, uint fFlags);
void SetPath(
[MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
[ComImport,
Guid(ShellIIDGuid.IThumbnailCache),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IThumbnailCache
{
void GetThumbnail([In] IShellItem pShellItem,
[In] uint cxyRequestedThumbSize,
[In] ThumbnailOptions flags,
[Out] out ISharedBitmap ppvThumb,
[Out] out ThumbnailCacheOptions pOutFlags,
[Out] ThumbnailId pThumbnailID);
void GetThumbnailByID([In] ThumbnailId thumbnailID,
[In] uint cxyRequestedThumbSize,
[Out] out ISharedBitmap ppvThumb,
[Out] out ThumbnailCacheOptions pOutFlags);
}
[ComImport,
ClassInterface(ClassInterfaceType.None),
TypeLibType(TypeLibTypeFlags.FCanCreate),
Guid(ShellCLSIDGuid.ConditionFactory)]
public class ConditionFactoryCoClass
{
}
[ComImport,
Guid(ShellIIDGuid.CShellLink),
ClassInterface(ClassInterfaceType.None)]
public class CShellLink { }
[ComImport,
ClassInterface(ClassInterfaceType.None),
TypeLibType(TypeLibTypeFlags.FCanCreate),
Guid(ShellCLSIDGuid.QueryParserManager)]
public class QueryParserManagerCoClass
{
}
[ComImport,
ClassInterface(ClassInterfaceType.None),
TypeLibType(TypeLibTypeFlags.FCanCreate),
Guid(ShellCLSIDGuid.SearchFolderItemFactory)]
public class SearchFolderItemFactoryCoClass
{
}

View File

@@ -0,0 +1,399 @@
using MicaSetup.Natives;
using System;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
internal static class ShellNativeMethods
{
internal const int CommandLink = 0x0000000E;
internal const uint GetNote = 0x0000160A;
internal const uint GetNoteLength = 0x0000160B;
internal const int InPlaceStringTruncated = 0x00401A0;
internal const int MaxPath = 260;
internal const uint SetNote = 0x00001609;
internal const uint SetShield = 0x0000160C;
}
public static partial class Shell32
{
[DllImport(Lib.Shell32, CharSet = CharSet.None)]
public static extern void ILFree(nint pidl);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint ILGetSize(nint pidl);
[DllImport(Lib.Shell32)]
public static extern nint SHChangeNotification_Lock(nint windowHandle, int processId, out nint pidl, out uint lEvent);
[DllImport(Lib.Shell32)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SHChangeNotification_Unlock(nint hLock);
[DllImport(Lib.Shell32)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SHChangeNotifyDeregister(uint hNotify);
[DllImport(Lib.Shell32)]
public static extern uint SHChangeNotifyRegister(
nint windowHandle,
ShellChangeNotifyEventSource sources,
ShellObjectChangeTypes events,
uint message,
int entries,
ref SHChangeNotifyEntry changeNotifyEntry);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHCreateItemFromIDList(
nint pidl,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItem2 ppv);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHCreateItemFromParsingName(
[MarshalAs(UnmanagedType.LPWStr)] string path,
nint pbc,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItem2 shellItem);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHCreateItemFromParsingName(
[MarshalAs(UnmanagedType.LPWStr)] string path,
nint pbc,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHCreateShellItem(
nint pidlParent,
[In, MarshalAs(UnmanagedType.Interface)] IShellFolder psfParent,
nint pidl,
[MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi
);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHCreateShellItemArrayFromDataObject(
System.Runtime.InteropServices.ComTypes.IDataObject pdo,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItemArray iShellItemArray);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHGetDesktopFolder(
[MarshalAs(UnmanagedType.Interface)] out IShellFolder ppshf
);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHGetIDListFromObject(nint iUnknown,
out nint ppidl
);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHParseDisplayName(
[MarshalAs(UnmanagedType.LPWStr)] string pszName,
nint pbc,
out nint ppidl,
ShellFileGetAttributesOptions sfgaoIn,
out ShellFileGetAttributesOptions psfgaoOut
);
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
public static extern int SHShowManageLibraryUI(
[In, MarshalAs(UnmanagedType.Interface)] IShellItem library,
[In] nint hwndOwner,
[In] string title,
[In] string instruction,
[In] LibraryManageDialogOptions lmdOptions);
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct FilterSpec
{
[MarshalAs(UnmanagedType.LPWStr)]
public string Name;
[MarshalAs(UnmanagedType.LPWStr)]
public string Spec;
public FilterSpec(string name, string spec)
{
Name = name;
Spec = spec;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SHChangeNotifyEntry
{
public nint pIdl;
[MarshalAs(UnmanagedType.Bool)]
public bool recursively;
}
[StructLayout(LayoutKind.Sequential)]
public struct ShellNotifyStruct
{
public nint item1;
public nint item2;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct ThumbnailId
{
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 16)]
private readonly byte rgbKey;
}
[Flags]
public enum ShellObjectChangeTypes
{
None = 0,
ItemRename = 0x00000001,
ItemCreate = 0x00000002,
ItemDelete = 0x00000004,
DirectoryCreate = 0x00000008,
DirectoryDelete = 0x00000010,
MediaInsert = 0x00000020,
MediaRemove = 0x00000040,
DriveRemove = 0x00000080,
DriveAdd = 0x00000100,
NetShare = 0x00000200,
NetUnshare = 0x00000400,
AttributesChange = 0x00000800,
DirectoryContentsUpdate = 0x00001000,
Update = 0x00002000,
ServerDisconnect = 0x00004000,
SystemImageUpdate = 0x00008000,
DirectoryRename = 0x00020000,
FreeSpace = 0x00040000,
AssociationChange = 0x08000000,
DiskEventsMask = 0x0002381F,
GlobalEventsMask = 0x0C0581E0,
AllEventsMask = 0x7FFFFFFF,
FromInterrupt = unchecked((int)0x80000000),
}
public enum ControlState
{
Inactive = 0x00000000,
Enable = 0x00000001,
Visible = 0x00000002,
}
public enum DefaultSaveFolderType
{
Detect = 1,
Private = 2,
Public = 3,
};
public enum FileDialogAddPlacement
{
Bottom = 0x00000000,
Top = 0x00000001,
}
public enum FileDialogEventOverwriteResponse
{
Default = 0x00000000,
Accept = 0x00000001,
Refuse = 0x00000002,
}
public enum FileDialogEventShareViolationResponse
{
Default = 0x00000000,
Accept = 0x00000001,
Refuse = 0x00000002,
}
[Flags]
public enum FileOpenOptions
{
OverwritePrompt = 0x00000002,
StrictFileTypes = 0x00000004,
NoChangeDirectory = 0x00000008,
PickFolders = 0x00000020,
ForceFilesystem = 0x00000040,
AllNonStorageItems = 0x00000080,
NoValidate = 0x00000100,
AllowMultiSelect = 0x00000200,
PathMustExist = 0x00000800,
FileMustExist = 0x00001000,
CreatePrompt = 0x00002000,
ShareAware = 0x00004000,
NoReadOnlyReturn = 0x00008000,
NoTestFileCreate = 0x00010000,
HideMruPlaces = 0x00020000,
HidePinnedPlaces = 0x00040000,
NoDereferenceLinks = 0x00100000,
DontAddToRecent = 0x02000000,
ForceShowHidden = 0x10000000,
DefaultNoMiniMode = 0x20000000,
}
[Flags]
public enum GetPropertyStoreOptions
{
Default = 0,
HandlePropertiesOnly = 0x1,
ReadWrite = 0x2,
Temporary = 0x4,
FastPropertiesOnly = 0x8,
OpensLowItem = 0x10,
DelayCreation = 0x20,
BestEffort = 0x40,
MaskValid = 0xff,
}
public enum LibraryFolderFilter
{
ForceFileSystem = 1,
StorageItems = 2,
AllItems = 3,
};
public enum LibraryManageDialogOptions
{
Default = 0,
NonIndexableLocationWarning = 1,
};
[Flags]
public enum LibraryOptions
{
Default = 0,
PinnedToNavigationPane = 0x1,
MaskAll = 0x1,
};
public enum LibrarySaveOptions
{
FailIfThere = 0,
OverrideExisting = 1,
MakeUniqueName = 2,
};
[Flags]
public enum ShellChangeNotifyEventSource
{
InterruptLevel = 0x0001,
ShellLevel = 0x0002,
RecursiveInterrupt = 0x1000,
NewDelivery = 0x8000,
}
[Flags]
public enum ShellFileGetAttributesOptions
{
CanCopy = 0x00000001,
CanMove = 0x00000002,
CanLink = 0x00000004,
Storage = 0x00000008,
CanRename = 0x00000010,
CanDelete = 0x00000020,
HasPropertySheet = 0x00000040,
DropTarget = 0x00000100,
CapabilityMask = 0x00000177,
System = 0x00001000,
Encrypted = 0x00002000,
IsSlow = 0x00004000,
Ghosted = 0x00008000,
Link = 0x00010000,
Share = 0x00020000,
ReadOnly = 0x00040000,
Hidden = 0x00080000,
DisplayAttributeMask = 0x000FC000,
FileSystemAncestor = 0x10000000,
Folder = 0x20000000,
FileSystem = 0x40000000,
HasSubFolder = unchecked((int)0x80000000),
ContentsMask = unchecked((int)0x80000000),
Validate = 0x01000000,
Removable = 0x02000000,
Compressed = 0x04000000,
Browsable = 0x08000000,
Nonenumerated = 0x00100000,
NewContent = 0x00200000,
CanMoniker = 0x00400000,
HasStorage = 0x00400000,
Stream = 0x00400000,
StorageAncestor = 0x00800000,
StorageCapabilityMask = 0x70C50008,
PkeyMask = unchecked((int)0x81044000),
}
[Flags]
public enum ShellFolderEnumerationOptions : ushort
{
CheckingForChildren = 0x0010,
Folders = 0x0020,
NonFolders = 0x0040,
IncludeHidden = 0x0080,
InitializeOnFirstNext = 0x0100,
NetPrinterSearch = 0x0200,
Shareable = 0x0400,
Storage = 0x0800,
NavigationEnum = 0x1000,
FastItems = 0x2000,
FlatList = 0x4000,
EnableAsync = 0x8000,
}
public enum ShellItemAttributeOptions
{
And = 0x00000001,
Or = 0x00000002,
AppCompat = 0x00000003,
Mask = 0x00000003,
AllItems = 0x00004000,
}
public enum ShellItemDesignNameOptions
{
Normal = 0x00000000,
ParentRelativeParsing = unchecked((int)0x80018001),
DesktopAbsoluteParsing = unchecked((int)0x80028000),
ParentRelativeEditing = unchecked((int)0x80031001),
DesktopAbsoluteEditing = unchecked((int)0x8004c000),
FileSystemPath = unchecked((int)0x80058000),
Url = unchecked((int)0x80068000),
ParentRelativeForAddressBar = unchecked((int)0x8007c001),
ParentRelative = unchecked((int)0x80080001),
}
[Flags]
public enum SIIGBF
{
ResizeToFit = 0x00,
BiggerSizeOk = 0x01,
MemoryOnly = 0x02,
IconOnly = 0x04,
ThumbnailOnly = 0x08,
InCacheOnly = 0x10,
}
[Flags]
public enum ThumbnailCacheOptions
{
Default = 0x00000000,
LowQuality = 0x00000001,
Cached = 0x00000002,
}
[Flags]
public enum ThumbnailOptions
{
Extract = 0x00000000,
InCacheOnly = 0x00000001,
FastExtract = 0x00000002,
ForceExtraction = 0x00000004,
SlowReclaim = 0x00000008,
ExtractDoNotCache = 0x00000020
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace MicaSetup.Shell.Dialogs;
[Flags]
[SuppressMessage("Microsoft.Design", "CA1008:")]
public enum AccessModes
{
Direct = 0x00000000,
Transacted = 0x00010000,
Simple = 0x08000000,
Read = 0x00000000,
Write = 0x00000001,
ReadWrite = 0x00000002,
ShareDenyNone = 0x00000040,
ShareDenyRead = 0x00000030,
ShareDenyWrite = 0x00000020,
ShareExclusive = 0x00000010,
Priority = 0x00040000,
DeleteOnRelease = 0x04000000,
NoScratch = 0x00100000,
Create = 0x00001000,
Convert = 0x00020000,
FailIfThere = 0x00000000,
NoSnapshot = 0x00200000,
DirectSingleWriterMultipleReader = 0x00400000,
};

View File

@@ -0,0 +1,45 @@
namespace MicaSetup.Shell.Dialogs;
public enum HResult
{
Ok = 0x0000,
False = 0x0001,
InvalidArguments = unchecked((int)0x80070057),
OutOfMemory = unchecked((int)0x8007000E),
NoInterface = unchecked((int)0x80004002),
Fail = unchecked((int)0x80004005),
ElementNotFound = unchecked((int)0x80070490),
TypeElementNotFound = unchecked((int)0x8002802B),
NoObject = unchecked((int)0x800401E5),
Win32ErrorCanceled = 1223,
Canceled = unchecked((int)0x800704C7),
ResourceInUse = unchecked((int)0x800700AA),
AccessDenied = unchecked((int)0x80030005)
}
internal static class CoreErrorHelper
{
public const int Ignored = (int)HResult.Ok;
private const int FacilityWin32 = 7;
public static bool Failed(HResult result) => !Succeeded(result);
public static bool Failed(int result) => !Succeeded(result);
public static int HResultFromWin32(int win32ErrorCode)
{
if (win32ErrorCode > 0)
{
win32ErrorCode =
(int)(((uint)win32ErrorCode & 0x0000FFFF) | (FacilityWin32 << 16) | 0x80000000);
}
return win32ErrorCode;
}
public static bool Matches(int result, int win32ErrorCode) => (result == HResultFromWin32(win32ErrorCode));
public static bool Succeeded(int result) => result >= 0;
public static bool Succeeded(HResult result) => Succeeded((int)result);
}

View File

@@ -0,0 +1,9 @@
namespace MicaSetup.Shell.Dialogs;
public enum DialogShowState
{
PreShow,
Showing,
Closing,
Closed,
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
internal interface NativeCommonFileDialog
{
}
[ComImport,
Guid(ShellIIDGuid.IFileOpenDialog),
CoClass(typeof(FileOpenDialogRCW))]
internal interface NativeFileOpenDialog : IFileOpenDialog
{
}
[ComImport,
Guid(ShellIIDGuid.IFileSaveDialog),
CoClass(typeof(FileSaveDialogRCW))]
internal interface NativeFileSaveDialog : IFileSaveDialog
{
}
[ComImport,
ClassInterface(ClassInterfaceType.None),
TypeLibType(TypeLibTypeFlags.FCanCreate),
Guid(ShellCLSIDGuid.FileOpenDialog)]
internal class FileOpenDialogRCW
{
}
[ComImport,
ClassInterface(ClassInterfaceType.None),
TypeLibType(TypeLibTypeFlags.FCanCreate),
Guid(ShellCLSIDGuid.FileSaveDialog)]
internal class FileSaveDialogRCW
{
}

View File

@@ -0,0 +1,477 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
#pragma warning disable CS0108
[ComImport(),
Guid(ShellIIDGuid.IFileDialog),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IFileDialog : IModalWindow
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime),
PreserveSig]
int Show([In] nint parent);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileTypes(
[In] uint cFileTypes,
[In, MarshalAs(UnmanagedType.LPArray)] FilterSpec[] rgFilterSpec);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileTypeIndex([In] uint iFileType);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFileTypeIndex(out uint piFileType);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Advise(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialogEvents pfde,
out uint pdwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Unadvise([In] uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetOptions([In] FileOpenOptions fos);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetOptions(out FileOpenOptions pfos);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, FileDialogAddPlacement fdap);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Close([MarshalAs(UnmanagedType.Error)] int hr);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetClientGuid([In] ref Guid guid);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ClearClientData();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFilter([MarshalAs(UnmanagedType.Interface)] nint pFilter);
}
[ComImport,
Guid(ShellIIDGuid.IFileDialogControlEvents),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IFileDialogControlEvents
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnItemSelected(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialogCustomize pfdc,
[In] int dwIDCtl,
[In] int dwIDItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnButtonClicked(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialogCustomize pfdc,
[In] int dwIDCtl);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnCheckButtonToggled(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialogCustomize pfdc,
[In] int dwIDCtl,
[In] bool bChecked);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnControlActivating(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialogCustomize pfdc,
[In] int dwIDCtl);
}
[ComImport,
Guid(ShellIIDGuid.IFileDialogCustomize),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IFileDialogCustomize
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void EnableOpenDropDown([In] int dwIDCtl);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddMenu(
[In] int dwIDCtl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddPushButton(
[In] int dwIDCtl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddComboBox([In] int dwIDCtl);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddRadioButtonList([In] int dwIDCtl);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddCheckButton(
[In] int dwIDCtl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel,
[In] bool bChecked);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddEditBox(
[In] int dwIDCtl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszText);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddSeparator([In] int dwIDCtl);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddText(
[In] int dwIDCtl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszText);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetControlLabel(
[In] int dwIDCtl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetControlState(
[In] int dwIDCtl,
[Out] out ControlState pdwState);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetControlState(
[In] int dwIDCtl,
[In] ControlState dwState);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetEditBoxText(
[In] int dwIDCtl,
[MarshalAs(UnmanagedType.LPWStr)] out string ppszText);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetEditBoxText(
[In] int dwIDCtl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszText);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCheckButtonState(
[In] int dwIDCtl,
[Out] out bool pbChecked);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetCheckButtonState(
[In] int dwIDCtl,
[In] bool bChecked);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddControlItem(
[In] int dwIDCtl,
[In] int dwIDItem,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void RemoveControlItem(
[In] int dwIDCtl,
[In] int dwIDItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void RemoveAllControlItems([In] int dwIDCtl);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetControlItemState(
[In] int dwIDCtl,
[In] int dwIDItem,
[Out] out ControlState pdwState);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetControlItemState(
[In] int dwIDCtl,
[In] int dwIDItem,
[In] ControlState dwState);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSelectedControlItem(
[In] int dwIDCtl,
[Out] out int pdwIDItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetSelectedControlItem(
[In] int dwIDCtl,
[In] int dwIDItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void StartVisualGroup(
[In] int dwIDCtl,
[In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void EndVisualGroup();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void MakeProminent([In] int dwIDCtl);
}
[ComImport,
Guid(ShellIIDGuid.IFileDialogEvents),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IFileDialogEvents
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime),
PreserveSig]
HResult OnFileOk([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime),
PreserveSig]
HResult OnFolderChanging(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd,
[In, MarshalAs(UnmanagedType.Interface)] IShellItem psiFolder);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnFolderChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnSelectionChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnShareViolation(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd,
[In, MarshalAs(UnmanagedType.Interface)] IShellItem psi,
out FileDialogEventShareViolationResponse pResponse);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnTypeChange([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void OnOverwrite([In, MarshalAs(UnmanagedType.Interface)] IFileDialog pfd,
[In, MarshalAs(UnmanagedType.Interface)] IShellItem psi,
out FileDialogEventOverwriteResponse pResponse);
}
[ComImport(),
Guid(ShellIIDGuid.IFileOpenDialog),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IFileOpenDialog : IFileDialog
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime),
PreserveSig]
int Show([In] nint parent);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileTypes([In] uint cFileTypes, [In] ref FilterSpec rgFilterSpec);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileTypeIndex([In] uint iFileType);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFileTypeIndex(out uint piFileType);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Advise(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialogEvents pfde,
out uint pdwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Unadvise([In] uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetOptions([In] FileOpenOptions fos);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetOptions(out FileOpenOptions pfos);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, FileDialogAddPlacement fdap);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Close([MarshalAs(UnmanagedType.Error)] int hr);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetClientGuid([In] ref Guid guid);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ClearClientData();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFilter([MarshalAs(UnmanagedType.Interface)] nint pFilter);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetResults([MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppenum);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSelectedItems([MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppsai);
}
[ComImport(),
Guid(ShellIIDGuid.IFileSaveDialog),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IFileSaveDialog : IFileDialog
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime),
PreserveSig]
int Show([In] nint parent);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileTypes(
[In] uint cFileTypes,
[In] ref FilterSpec rgFilterSpec);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileTypeIndex([In] uint iFileType);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFileTypeIndex(out uint piFileType);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Advise(
[In, MarshalAs(UnmanagedType.Interface)] IFileDialogEvents pfde,
out uint pdwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Unadvise([In] uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetOptions([In] FileOpenOptions fos);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetOptions(out FileOpenOptions pfos);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void AddPlace(
[In, MarshalAs(UnmanagedType.Interface)] IShellItem psi,
FileDialogAddPlacement fdap);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Close([MarshalAs(UnmanagedType.Error)] int hr);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetClientGuid([In] ref Guid guid);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ClearClientData();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetFilter([MarshalAs(UnmanagedType.Interface)] nint pFilter);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetSaveAsItem([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetProperties([In, MarshalAs(UnmanagedType.Interface)] nint pStore);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
int SetCollectedProperties(
[In] IPropertyDescriptionList pList,
[In] bool fAppendDefault);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[PreserveSig]
HResult GetProperties(out IPropertyStore ppStore);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ApplyProperties(
[In, MarshalAs(UnmanagedType.Interface)] IShellItem psi,
[In, MarshalAs(UnmanagedType.Interface)] nint pStore,
[In, ComAliasName("ShellObjects.wireHWND")] ref nint hwnd,
[In, MarshalAs(UnmanagedType.Interface)] nint pSink);
}
#pragma warning restore 0108

View File

@@ -0,0 +1,44 @@
namespace MicaSetup.Shell.Dialogs;
internal static class ExplorerBrowserCLSIDGuid
{
internal const string ExplorerBrowser = "71F96385-DDD6-48D3-A0C1-AE06E8B055FB";
}
internal static class ExplorerBrowserIIDGuid
{
internal const string DShellFolderViewEvents = "62112AA2-EBE4-11cf-A5FB-0020AFE7292D";
internal const string ICommDlgBrowser = "000214F1-0000-0000-C000-000000000046";
internal const string ICommDlgBrowser2 = "10339516-2894-11d2-9039-00C04F8EEB3E";
internal const string ICommDlgBrowser3 = "c8ad25a1-3294-41ee-8165-71174bd01c57";
internal const string IDispatch = "00020400-0000-0000-C000-000000000046";
internal const string IExplorerBrowser = "DFD3B6B5-C10C-4BE9-85F6-A66969F402F6";
internal const string IExplorerBrowserEvents = "361bbdc7-e6ee-4e13-be58-58e2240c810f";
internal const string IExplorerPaneVisibility = "e07010ec-bc17-44c0-97b0-46c7c95b9edc";
internal const string IFolderView = "cde725b0-ccc9-4519-917e-325d72fab4ce";
internal const string IFolderView2 = "1af3a467-214f-4298-908e-06b03e0b39f9";
internal const string IInputObject = "68284fAA-6A48-11D0-8c78-00C04fd918b4";
internal const string IKnownFolderManager = "8BE2D872-86AA-4d47-B776-32CCA40C7018";
internal const string IServiceProvider = "6d5140c1-7436-11ce-8034-00aa006009fa";
internal const string IShellView = "000214E3-0000-0000-C000-000000000046";
}
internal static class ExplorerBrowserViewDispatchIds
{
internal const int ContentsChanged = 207;
internal const int FileListEnumDone = 201;
internal const int SelectedItemChanged = 220;
internal const int SelectionChanged = 200;
}
internal static class ExplorerBrowserViewPanes
{
internal const string AdvancedQuery = "b4e9db8b-34ba-4c39-b5cc-16a1bd2c411c";
internal const string Commands = "d9745868-ca5f-4a76-91cd-f5a129fbb076";
internal const string CommandsOrganize = "72e81700-e3ec-4660-bf24-3c3b7b648806";
internal const string CommandsView = "21f7c32d-eeaa-439b-bb51-37b96fd6a943";
internal const string Details = "43abf98b-89b8-472d-b9ce-e69b8229f019";
internal const string Navigation = "cb316b22-25f7-42b8-8a09-540d23a43c2f";
internal const string Preview = "893c63d1-45c8-4d17-be19-223be71be365";
internal const string Query = "65bcde4f-4f07-4f27-83a7-1afca4df7ddd";
}

View File

@@ -0,0 +1,607 @@
using MicaSetup.Natives;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
#pragma warning disable CS0108
namespace MicaSetup.Shell.Dialogs;
internal enum CommDlgBrowser2ViewFlags
{
ShowAllFiles = 0x00000001,
IsFileSave = 0x00000002,
AllowPreviewPane = 0x00000004,
NoSelectVerb = 0x00000008,
NoIncludeItem = 0x00000010,
IsFolderPicker = 0x00000020
}
internal enum CommDlgBrowserNotifyType
{
Done = 1,
Start = 2
}
internal enum CommDlgBrowserStateChange
{
SetFocus = 0,
KillFocus = 1,
SelectionChange = 2,
Rename = 3,
StateChange = 4
}
[Flags]
internal enum ExplorerBrowserOptions
{
NavigateOnce = 0x00000001,
ShowFrames = 0x00000002,
AlwaysNavigate = 0x00000004,
NoTravelLog = 0x00000008,
NoWrapperWindow = 0x00000010,
HtmlSharepointView = 0x00000020,
NoBorder = 0x00000040,
NoPersistViewState = 0x00000080,
}
internal enum ExplorerPaneState
{
DoNotCare = 0x00000000,
DefaultOn = 0x00000001,
DefaultOff = 0x00000002,
StateMask = 0x0000ffff,
InitialState = 0x00010000,
Force = 0x00020000
}
[Flags]
internal enum FolderOptions
{
AutoArrange = 0x00000001,
AbbreviatedNames = 0x00000002,
SnapToGrid = 0x00000004,
OwnerData = 0x00000008,
BestFitWindow = 0x00000010,
Desktop = 0x00000020,
SingleSelection = 0x00000040,
NoSubfolders = 0x00000080,
Transparent = 0x00000100,
NoClientEdge = 0x00000200,
NoScroll = 0x00000400,
AlignLeft = 0x00000800,
NoIcons = 0x00001000,
ShowSelectionAlways = 0x00002000,
NoVisible = 0x00004000,
SingleClickActivate = 0x00008000,
NoWebView = 0x00010000,
HideFilenames = 0x00020000,
CheckSelect = 0x00040000,
NoEnumRefresh = 0x00080000,
NoGrouping = 0x00100000,
FullRowSelect = 0x00200000,
NoFilters = 0x00400000,
NoColumnHeaders = 0x00800000,
NoHeaderInAllViews = 0x01000000,
ExtendedTiles = 0x02000000,
TriCheckSelect = 0x04000000,
AutoCheckSelect = 0x08000000,
NoBrowserViewState = 0x10000000,
SubsetGroups = 0x20000000,
UseSearchFolders = 0x40000000,
AllowRightToLeftReading = unchecked((int)0x80000000)
}
internal enum FolderViewMode
{
Auto = -1,
First = 1,
Icon = 1,
SmallIcon = 2,
List = 3,
Details = 4,
Thumbnail = 5,
Tile = 6,
Thumbstrip = 7,
Content = 8,
Last = 8
}
internal enum ShellViewGetItemObject
{
Background = 0x00000000,
Selection = 0x00000001,
AllView = 0x00000002,
Checked = 0x00000003,
TypeMask = 0x0000000F,
ViewOrderFlag = unchecked((int)0x80000000)
}
[ComImport,
Guid(ExplorerBrowserIIDGuid.ICommDlgBrowser3),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ICommDlgBrowser3
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult OnDefaultCommand(nint ppshv);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult OnStateChange(
nint ppshv,
CommDlgBrowserStateChange uChange);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult IncludeObject(
nint ppshv,
nint pidl);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetDefaultMenuText(
IShellView shellView,
nint buffer,
int bufferMaxLength);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetViewFlags(
[Out] out uint pdwFlags);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Notify(
nint pshv, CommDlgBrowserNotifyType notifyType);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetCurrentFilter(
StringBuilder pszFileSpec,
int cchFileSpec);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult OnColumnClicked(
IShellView ppshv,
int iColumn);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult OnPreViewCreated(IShellView ppshv);
}
[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(ExplorerBrowserIIDGuid.IExplorerBrowser)]
internal interface IExplorerBrowser
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Initialize(nint hwndParent, [In] ref RECT prc, [In] FolderSettings pfs);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Destroy();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetRect([In, Out] ref nint phdwp, RECT rcBrowser);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetPropertyBag([MarshalAs(UnmanagedType.LPWStr)] string pszPropertyBag);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetEmptyText([MarshalAs(UnmanagedType.LPWStr)] string pszEmptyText);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult SetFolderSettings(FolderSettings pfs);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Advise(nint psbe, out uint pdwCookie);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Unadvise([In] uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetOptions([In] ExplorerBrowserOptions dwFlag);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetOptions(out ExplorerBrowserOptions pdwFlag);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void BrowseToIDList(nint pidl, uint uFlags);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult BrowseToObject([MarshalAs(UnmanagedType.IUnknown)] object punk, uint uFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void FillFromObject([MarshalAs(UnmanagedType.IUnknown)] object punk, int dwFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void RemoveAll();
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetCurrentView(ref Guid riid, out nint ppv);
}
[ComImport,
Guid(ExplorerBrowserIIDGuid.IExplorerBrowserEvents),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IExplorerBrowserEvents
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult OnNavigationPending(nint pidlFolder);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult OnViewCreated([MarshalAs(UnmanagedType.IUnknown)] object psv);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult OnNavigationComplete(nint pidlFolder);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult OnNavigationFailed(nint pidlFolder);
}
[ComImport,
Guid(ExplorerBrowserIIDGuid.IExplorerPaneVisibility),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IExplorerPaneVisibility
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetPaneState(ref Guid explorerPane, out ExplorerPaneState peps);
};
[ComImport,
Guid(ExplorerBrowserIIDGuid.IFolderView),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IFolderView
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCurrentViewMode([Out] out uint pViewMode);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetCurrentViewMode(uint ViewMode);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFolder(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Item(int iItemIndex, out nint ppidl);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ItemCount(uint uFlags, out int pcItems);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Items(uint uFlags, ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSelectionMarkedItem(out int piItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFocusedItem(out int piItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetItemPosition(nint pidl, out POINT ppt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSpacing([Out] out POINT ppt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDefaultSpacing(out POINT ppt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAutoArrange();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SelectItem(int iItem, uint dwFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SelectAndPositionItems(uint cidl, nint apidl, ref POINT apt, uint dwFlags);
}
[ComImport,
Guid(ExplorerBrowserIIDGuid.IFolderView2),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IFolderView2 : IFolderView
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetCurrentViewMode(out uint pViewMode);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetCurrentViewMode(uint ViewMode);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFolder(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Item(int iItemIndex, out nint ppidl);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult ItemCount(uint uFlags, out int pcItems);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Items(uint uFlags, ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out object ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSelectionMarkedItem(out int piItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetFocusedItem(out int piItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetItemPosition(nint pidl, out POINT ppt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSpacing([Out] out POINT ppt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDefaultSpacing(out POINT ppt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAutoArrange();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SelectItem(int iItem, uint dwFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SelectAndPositionItems(uint cidl, nint apidl, ref POINT apt, uint dwFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetGroupBy(nint key, bool fAscending);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetGroupBy(ref nint pkey, ref bool pfAscending);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetViewProperty(nint pidl, nint propkey, object propvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetViewProperty(nint pidl, nint propkey, out object ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetTileViewProperties(nint pidl, [MarshalAs(UnmanagedType.LPWStr)] string pszPropList);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetExtendedTileViewProperties(nint pidl, [MarshalAs(UnmanagedType.LPWStr)] string pszPropList);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetText(int iType, [MarshalAs(UnmanagedType.LPWStr)] string pwszText);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetCurrentFolderFlags(uint dwMask, uint dwFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCurrentFolderFlags(out uint pdwFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSortColumnCount(out int pcColumns);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetSortColumns(nint rgSortColumns, int cColumns);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSortColumns(out nint rgSortColumns, int cColumns);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetItem(int iItem, ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetVisibleItem(int iStart, bool fPrevious, out int piItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSelectedItem(int iStart, out int piItem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSelection(bool fNoneImpliesFolder, out IShellItemArray ppsia);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSelectionState(nint pidl, out uint pdwFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void InvokeVerbOnSelection([In, MarshalAs(UnmanagedType.LPWStr)] string pszVerb);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult SetViewModeAndIconSize(int uViewMode, int iImageSize);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetViewModeAndIconSize(out int puViewMode, out int piImageSize);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetGroupSubsetCount(uint cVisibleRows);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetGroupSubsetCount(out uint pcVisibleRows);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetRedraw(bool fRedrawOn);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void IsMoveInSameFolder();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void DoRename();
}
[ComImport,
Guid(ExplorerBrowserIIDGuid.IInputObject),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IInputObject
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult UIActivateIO(bool fActivate, ref System.Windows.Forms.Message pMsg);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult HasFocusIO();
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult TranslateAcceleratorIO(ref System.Windows.Forms.Message pMsg);
};
[ComImport,
Guid(ExplorerBrowserIIDGuid.IServiceProvider),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IServiceProvider
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall)]
HResult QueryService(ref Guid guidService, ref Guid riid, out nint ppvObject);
};
[ComImport,
Guid(ExplorerBrowserIIDGuid.IShellView),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IShellView
{
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetWindow(
out nint phwnd);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult ContextSensitiveHelp(
bool fEnterMode);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult TranslateAccelerator(
nint pmsg);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult EnableModeless(
bool fEnable);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult UIActivate(
uint uState);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Refresh();
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult CreateViewWindow(
[MarshalAs(UnmanagedType.IUnknown)] object psvPrevious,
nint pfs,
[MarshalAs(UnmanagedType.IUnknown)] object psb,
nint prcView,
out nint phWnd);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult DestroyViewWindow();
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetCurrentInfo(
out nint pfs);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult AddPropertySheetPages(
uint dwReserved,
nint pfn,
uint lparam);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult SaveViewState();
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult SelectItem(
nint pidlItem,
uint uFlags);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetItemObject(
ShellViewGetItemObject uItem,
ref Guid riid,
[MarshalAs(UnmanagedType.IUnknown)] out object ppv);
}
[ComImport,
TypeLibType(TypeLibTypeFlags.FCanCreate),
ClassInterface(ClassInterfaceType.None),
Guid(ExplorerBrowserCLSIDGuid.ExplorerBrowser)]
internal class ExplorerBrowserClass : IExplorerBrowser
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void Initialize(nint hwndParent, [In] ref RECT prc, [In] FolderSettings pfs);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void Destroy();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void SetRect([In, Out] ref nint phdwp, RECT rcBrowser);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void SetPropertyBag([MarshalAs(UnmanagedType.LPWStr)] string pszPropertyBag);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void SetEmptyText([MarshalAs(UnmanagedType.LPWStr)] string pszEmptyText);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual HResult SetFolderSettings(FolderSettings pfs);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual HResult Advise(nint psbe, out uint pdwCookie);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual HResult Unadvise(uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void SetOptions([In] ExplorerBrowserOptions dwFlag);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void GetOptions(out ExplorerBrowserOptions pdwFlag);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void BrowseToIDList(nint pidl, uint uFlags);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual HResult BrowseToObject([MarshalAs(UnmanagedType.IUnknown)] object punk, uint uFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void FillFromObject([MarshalAs(UnmanagedType.IUnknown)] object punk, int dwFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void RemoveAll();
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern virtual HResult GetCurrentView(ref Guid riid, out nint ppv);
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal class FolderSettings
{
public FolderViewMode ViewMode;
public FolderOptions Options;
}

View File

@@ -0,0 +1,20 @@
namespace MicaSetup.Shell.Dialogs;
internal static class KnownFoldersCLSIDGuid
{
internal const string KnownFolderManager = "4df0c730-df9d-4ae3-9153-aa6b82e9795a";
}
internal static class KnownFoldersIIDGuid
{
internal const string IKnownFolder = "3AA7AF7E-9B36-420c-A8E3-F77D4674A488";
internal const string IKnownFolderManager = "8BE2D872-86AA-4d47-B776-32CCA40C7018";
}
internal static class KnownFoldersKFIDGuid
{
internal const string ComputerFolder = "0AC0837C-BBF8-452A-850D-79D08E667CA7";
internal const string Documents = "FDD39AD0-238F-46AF-ADB4-6C85480369C7";
internal const string Favorites = "1777F761-68AD-4D8A-87BD-30B759FA33DD";
internal const string Profile = "5E6C858F-0E22-4760-9AFE-EA3317B67173";
}

View File

@@ -0,0 +1,176 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
#pragma warning disable CS0108
[ComImport,
Guid(KnownFoldersIIDGuid.IKnownFolderManager),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IKnownFolderManager
{
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void FolderIdFromCsidl(int csidl,
[Out] out Guid knownFolderID);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void FolderIdToCsidl([In, MarshalAs(UnmanagedType.LPStruct)] Guid id,
[Out] out int csidl);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void GetFolderIds([Out] out nint folders,
[Out] out uint count);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
HResult GetFolder([In, MarshalAs(UnmanagedType.LPStruct)] Guid id,
[Out, MarshalAs(UnmanagedType.Interface)] out IKnownFolderNative knownFolder);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void GetFolderByName(string canonicalName,
[Out, MarshalAs(UnmanagedType.Interface)] out IKnownFolderNative knownFolder);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void RegisterFolder(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid knownFolderGuid,
[In] ref KnownFoldersSafeNativeMethods.NativeFolderDefinition knownFolderDefinition);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void UnregisterFolder(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid knownFolderGuid);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void FindFolderFromPath(
[In, MarshalAs(UnmanagedType.LPWStr)] string path,
[In] int mode,
[Out, MarshalAs(UnmanagedType.Interface)] out IKnownFolderNative knownFolder);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
HResult FindFolderFromIDList(nint pidl, [Out, MarshalAs(UnmanagedType.Interface)] out IKnownFolderNative knownFolder);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void Redirect();
}
[ComImport,
Guid(KnownFoldersIIDGuid.IKnownFolder),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IKnownFolderNative
{
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
Guid GetId();
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
FolderCategory GetCategory();
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
[PreserveSig]
HResult GetShellItem([In] int i,
ref Guid interfaceGuid,
[Out, MarshalAs(UnmanagedType.Interface)] out IShellItem2 shellItem);
[return: MarshalAs(UnmanagedType.LPWStr)]
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
string GetPath([In] int option);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void SetPath([In] int i, [In] string path);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void GetIDList([In] int i,
[Out] out nint itemIdentifierListPointer);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
Guid GetFolderType();
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
RedirectionCapability GetRedirectionCapabilities();
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
void GetFolderDefinition(
[Out, MarshalAs(UnmanagedType.Struct)] out KnownFoldersSafeNativeMethods.NativeFolderDefinition definition);
}
[ComImport]
[Guid("4df0c730-df9d-4ae3-9153-aa6b82e9795a")]
internal class KnownFolderManagerClass : IKnownFolderManager
{
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void FolderIdFromCsidl(int csidl,
[Out] out Guid knownFolderID);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void FolderIdToCsidl(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid id,
[Out] out int csidl);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void GetFolderIds(
[Out] out nint folders,
[Out] out uint count);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual HResult GetFolder(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid id,
[Out, MarshalAs(UnmanagedType.Interface)]
out IKnownFolderNative knownFolder);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void GetFolderByName(
string canonicalName,
[Out, MarshalAs(UnmanagedType.Interface)] out IKnownFolderNative knownFolder);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void RegisterFolder(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid knownFolderGuid,
[In] ref KnownFoldersSafeNativeMethods.NativeFolderDefinition knownFolderDefinition);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void UnregisterFolder(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid knownFolderGuid);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void FindFolderFromPath(
[In, MarshalAs(UnmanagedType.LPWStr)] string path,
[In] int mode,
[Out, MarshalAs(UnmanagedType.Interface)] out IKnownFolderNative knownFolder);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual HResult FindFolderFromIDList(nint pidl, [Out, MarshalAs(UnmanagedType.Interface)] out IKnownFolderNative knownFolder);
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType = MethodCodeType.Runtime)]
public extern virtual void Redirect();
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Runtime.InteropServices;
using System.Security;
namespace MicaSetup.Shell.Dialogs;
[SuppressUnmanagedCodeSecurity]
internal static class KnownFoldersSafeNativeMethods
{
[StructLayout(LayoutKind.Sequential)]
internal struct NativeFolderDefinition
{
internal FolderCategory category;
internal nint name;
internal nint description;
internal Guid parentId;
internal nint relativePath;
internal nint parsingName;
internal nint tooltip;
internal nint localizedName;
internal nint icon;
internal nint security;
internal uint attributes;
internal DefinitionOptions definitionOptions;
internal Guid folderTypeId;
}
}

View File

@@ -0,0 +1,408 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
[StructLayout(LayoutKind.Explicit)]
public sealed class PropVariant : IDisposable
{
[StructLayout(LayoutKind.Sequential)]
private struct Blob
{
public int Number;
public nint Pointer;
}
private static Dictionary<Type, Action<PropVariant, Array, uint>> _vectorActions = null!;
private static Dictionary<Type, Action<PropVariant, Array, uint>> GenerateVectorActions()
{
Dictionary<Type, Action<PropVariant, Array, uint>> cache = new()
{
{
typeof(short),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetInt16Elem(pv, i, out short val);
array.SetValue(val, i);
}
},
{
typeof(ushort),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetUInt16Elem(pv, i, out ushort val);
array.SetValue(val, i);
}
},
{
typeof(int),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetInt32Elem(pv, i, out int val);
array.SetValue(val, i);
}
},
{
typeof(uint),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetUInt32Elem(pv, i, out uint val);
array.SetValue(val, i);
}
},
{
typeof(long),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetInt64Elem(pv, i, out long val);
array.SetValue(val, i);
}
},
{
typeof(ulong),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetUInt64Elem(pv, i, out ulong val);
array.SetValue(val, i);
}
},
{
typeof(DateTime),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetFileTimeElem(pv, i, out System.Runtime.InteropServices.ComTypes.FILETIME val);
long fileTime = GetFileTimeAsLong(ref val);
array.SetValue(DateTime.FromFileTime(fileTime), i);
}
},
{
typeof(bool),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetBooleanElem(pv, i, out bool val);
array.SetValue(val, i);
}
},
{
typeof(double),
(pv, array, i) =>
{
PropVariantNativeMethods.PropVariantGetDoubleElem(pv, i, out double val);
array.SetValue(val, i);
}
},
{
typeof(float),
(pv, array, i) =>
{
float[] val = new float[1];
Marshal.Copy(pv._blob.Pointer, val, (int)i, 1);
array.SetValue(val[0], (int)i);
}
},
{
typeof(decimal),
(pv, array, i) =>
{
int[] val = new int[4];
for (int a = 0; a < val.Length; a++)
{
val[a] = Marshal.ReadInt32(pv._blob.Pointer,
(int)i * sizeof(decimal) + a * sizeof(int));
}
array.SetValue(new decimal(val), i);
}
},
{
typeof(string),
(pv, array, i) =>
{
string val = string.Empty;
PropVariantNativeMethods.PropVariantGetStringElem(pv, i, ref val);
array.SetValue(val, i);
}
}
};
return cache;
}
public static PropVariant FromObject(object value)
{
if (value == null)
{
return new PropVariant();
}
else
{
Func<object, PropVariant> func = GetDynamicConstructor(value.GetType());
return func(value);
}
}
private static readonly Dictionary<Type, Func<object, PropVariant>> _cache = new();
private static readonly object _padlock = new();
private static Func<object, PropVariant> GetDynamicConstructor(Type type)
{
lock (_padlock)
{
if (!_cache.TryGetValue(type, out var action))
{
System.Reflection.ConstructorInfo constructor = typeof(PropVariant)
.GetConstructor(new Type[] { type });
if (constructor == null)
{
throw new ArgumentException(LocalizedMessages.PropVariantTypeNotSupported);
}
else
{
ParameterExpression arg = Expression.Parameter(typeof(object), "arg");
NewExpression create = Expression.New(constructor, Expression.Convert(arg, type));
action = Expression.Lambda<Func<object, PropVariant>>(create, arg).Compile();
_cache.Add(type, action);
}
}
return action;
}
}
[FieldOffset(0)]
private readonly decimal _decimal;
[FieldOffset(0)]
private ushort _valueType;
[FieldOffset(8)]
private readonly Blob _blob;
[FieldOffset(8)]
private nint _ptr;
[FieldOffset(8)]
private readonly int _int32;
[FieldOffset(8)]
private readonly uint _uint32;
[FieldOffset(8)]
private readonly byte _byte;
[FieldOffset(8)]
private readonly sbyte _sbyte;
[FieldOffset(8)]
private readonly short _short;
[FieldOffset(8)]
private readonly ushort _ushort;
[FieldOffset(8)]
private readonly long _long;
[FieldOffset(8)]
private readonly ulong _ulong;
[FieldOffset(8)]
private readonly double _double;
[FieldOffset(8)]
private readonly float _float;
public PropVariant()
{
}
public PropVariant(string value)
{
if (value == null)
{
throw new ArgumentException(LocalizedMessages.PropVariantNullString, "value");
}
_valueType = (ushort)VarEnum.VT_LPWSTR;
_ptr = Marshal.StringToCoTaskMemUni(value);
}
public PropVariant(bool value)
{
_valueType = (ushort)VarEnum.VT_BOOL;
_int32 = (value == true) ? -1 : 0;
}
public PropVariant(DateTime value)
{
_valueType = (ushort)VarEnum.VT_FILETIME;
System.Runtime.InteropServices.ComTypes.FILETIME ft = DateTimeToFileTime(value);
PropVariantNativeMethods.InitPropVariantFromFileTime(ref ft, this);
}
public PropVariant(int value)
{
_valueType = (ushort)VarEnum.VT_I4;
_int32 = value;
}
public PropVariant(double value)
{
_valueType = (ushort)VarEnum.VT_R8;
_double = value;
}
public VarEnum VarType
{
get => (VarEnum)_valueType;
set => _valueType = (ushort)value;
}
public bool IsNullOrEmpty => (_valueType == (ushort)VarEnum.VT_EMPTY || _valueType == (ushort)VarEnum.VT_NULL);
public object Value
{
get
{
return (VarEnum)_valueType switch
{
VarEnum.VT_I1 => _sbyte,
VarEnum.VT_UI1 => _byte,
VarEnum.VT_I2 => _short,
VarEnum.VT_UI2 => _ushort,
VarEnum.VT_I4 or VarEnum.VT_INT => _int32,
VarEnum.VT_UI4 or VarEnum.VT_UINT => _uint32,
VarEnum.VT_I8 => _long,
VarEnum.VT_UI8 => _ulong,
VarEnum.VT_R4 => _float,
VarEnum.VT_R8 => _double,
VarEnum.VT_BOOL => _int32 == -1,
VarEnum.VT_ERROR => _long,
VarEnum.VT_CY => _decimal,
VarEnum.VT_DATE => DateTime.FromOADate(_double),
VarEnum.VT_FILETIME => DateTime.FromFileTime(_long),
VarEnum.VT_BSTR => Marshal.PtrToStringBSTR(_ptr),
VarEnum.VT_BLOB => GetBlobData(),
VarEnum.VT_LPSTR => Marshal.PtrToStringAnsi(_ptr),
VarEnum.VT_LPWSTR => Marshal.PtrToStringUni(_ptr),
VarEnum.VT_UNKNOWN => Marshal.GetObjectForIUnknown(_ptr),
VarEnum.VT_DISPATCH => Marshal.GetObjectForIUnknown(_ptr),
VarEnum.VT_DECIMAL => _decimal,
VarEnum.VT_ARRAY | VarEnum.VT_UNKNOWN => CrackSingleDimSafeArray(_ptr),
(VarEnum.VT_VECTOR | VarEnum.VT_LPWSTR) => GetVector<string>(),
(VarEnum.VT_VECTOR | VarEnum.VT_I2) => GetVector<short>(),
(VarEnum.VT_VECTOR | VarEnum.VT_UI2) => GetVector<ushort>(),
(VarEnum.VT_VECTOR | VarEnum.VT_I4) => GetVector<int>(),
(VarEnum.VT_VECTOR | VarEnum.VT_UI4) => GetVector<uint>(),
(VarEnum.VT_VECTOR | VarEnum.VT_I8) => GetVector<long>(),
(VarEnum.VT_VECTOR | VarEnum.VT_UI8) => GetVector<ulong>(),
(VarEnum.VT_VECTOR | VarEnum.VT_R4) => GetVector<float>(),
(VarEnum.VT_VECTOR | VarEnum.VT_R8) => GetVector<double>(),
(VarEnum.VT_VECTOR | VarEnum.VT_BOOL) => GetVector<bool>(),
(VarEnum.VT_VECTOR | VarEnum.VT_FILETIME) => GetVector<DateTime>(),
(VarEnum.VT_VECTOR | VarEnum.VT_DECIMAL) => GetVector<decimal>(),
_ => null!,
};
}
}
private static long GetFileTimeAsLong(ref System.Runtime.InteropServices.ComTypes.FILETIME val) => (((long)val.dwHighDateTime) << 32) + val.dwLowDateTime;
private static System.Runtime.InteropServices.ComTypes.FILETIME DateTimeToFileTime(DateTime value)
{
long hFT = value.ToFileTime();
System.Runtime.InteropServices.ComTypes.FILETIME ft =
new()
{
dwLowDateTime = (int)(hFT & 0xFFFFFFFF),
dwHighDateTime = (int)(hFT >> 32)
};
return ft;
}
private object GetBlobData()
{
byte[] blobData = new byte[_int32];
nint pBlobData = _blob.Pointer;
Marshal.Copy(pBlobData, blobData, 0, _int32);
return blobData;
}
private Array GetVector<T>()
{
int count = PropVariantNativeMethods.PropVariantGetElementCount(this);
if (count <= 0) { return null!; }
lock (_padlock)
{
_vectorActions ??= GenerateVectorActions();
}
if (!_vectorActions.TryGetValue(typeof(T), out var action))
{
throw new InvalidCastException(LocalizedMessages.PropVariantUnsupportedType);
}
Array array = new T[count];
for (uint i = 0; i < count; i++)
{
action(this, array, i);
}
return array;
}
private static Array CrackSingleDimSafeArray(nint psa)
{
uint cDims = PropVariantNativeMethods.SafeArrayGetDim(psa);
if (cDims != 1)
throw new ArgumentException(LocalizedMessages.PropVariantMultiDimArray, "psa");
int lBound = PropVariantNativeMethods.SafeArrayGetLBound(psa, 1U);
int uBound = PropVariantNativeMethods.SafeArrayGetUBound(psa, 1U);
int n = uBound - lBound + 1;
object[] array = new object[n];
for (int i = lBound; i <= uBound; ++i)
{
array[i] = PropVariantNativeMethods.SafeArrayGetElement(psa, ref i);
}
return array;
}
public void Dispose()
{
PropVariantNativeMethods.PropVariantClear(this);
GC.SuppressFinalize(this);
}
~PropVariant()
{
Dispose();
}
public override string ToString() => string.Format(System.Globalization.CultureInfo.InvariantCulture,
"{0}: {1}", Value, VarType.ToString());
}

View File

@@ -0,0 +1,102 @@
using MicaSetup.Natives;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
internal static class PropVariantNativeMethods
{
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromBooleanVector([In, MarshalAs(UnmanagedType.LPArray)] bool[] prgf, uint cElems, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromDoubleVector([In, Out] double[] prgn, uint cElems, [Out] PropVariant propvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromFileTime([In] ref System.Runtime.InteropServices.ComTypes.FILETIME pftIn, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromFileTimeVector([In, Out] System.Runtime.InteropServices.ComTypes.FILETIME[] prgft, uint cElems, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromInt16Vector([In, Out] short[] prgn, uint cElems, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromInt32Vector([In, Out] int[] prgn, uint cElems, [Out] PropVariant propVar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromInt64Vector([In, Out] long[] prgn, uint cElems, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromPropVariantVectorElem([In] PropVariant propvarIn, uint iElem, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromStringVector([In, Out] string[] prgsz, uint cElems, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromUInt16Vector([In, Out] ushort[] prgn, uint cElems, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromUInt32Vector([In, Out] uint[] prgn, uint cElems, [Out] PropVariant ppropvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void InitPropVariantFromUInt64Vector([In, Out] ulong[] prgn, uint cElems, [Out] PropVariant ppropvar);
[DllImport(Lib.Ole32, PreserveSig = false)]
internal static extern void PropVariantClear([In, Out] PropVariant pvar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetBooleanElem([In] PropVariant propVar, [In] uint iElem, [Out, MarshalAs(UnmanagedType.Bool)] out bool pfVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetDoubleElem([In] PropVariant propVar, [In] uint iElem, [Out] out double pnVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.I4)]
internal static extern int PropVariantGetElementCount([In] PropVariant propVar);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetFileTimeElem([In] PropVariant propVar, [In] uint iElem, [Out, MarshalAs(UnmanagedType.Struct)] out System.Runtime.InteropServices.ComTypes.FILETIME pftVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetInt16Elem([In] PropVariant propVar, [In] uint iElem, [Out] out short pnVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetInt32Elem([In] PropVariant propVar, [In] uint iElem, [Out] out int pnVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetInt64Elem([In] PropVariant propVar, [In] uint iElem, [Out] out long pnVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetStringElem([In] PropVariant propVar, [In] uint iElem, [MarshalAs(UnmanagedType.LPWStr)] ref string ppszVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetUInt16Elem([In] PropVariant propVar, [In] uint iElem, [Out] out ushort pnVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetUInt32Elem([In] PropVariant propVar, [In] uint iElem, [Out] out uint pnVal);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true, PreserveSig = false)]
internal static extern void PropVariantGetUInt64Elem([In] PropVariant propVar, [In] uint iElem, [Out] out ulong pnVal);
[DllImport(Lib.OleAut32, PreserveSig = false)]
internal static extern nint SafeArrayAccessData(nint psa);
[DllImport(Lib.OleAut32, PreserveSig = true)]
internal static extern nint SafeArrayCreateVector(ushort vt, int lowerBound, uint cElems);
[DllImport(Lib.OleAut32, PreserveSig = true)]
internal static extern uint SafeArrayGetDim(nint psa);
[DllImport(Lib.OleAut32, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.IUnknown)]
internal static extern object SafeArrayGetElement(nint psa, ref int rgIndices);
[DllImport(Lib.OleAut32, PreserveSig = false)]
internal static extern int SafeArrayGetLBound(nint psa, uint nDim);
[DllImport(Lib.OleAut32, PreserveSig = false)]
internal static extern int SafeArrayGetUBound(nint psa, uint nDim);
[DllImport(Lib.OleAut32, PreserveSig = false)]
internal static extern void SafeArrayUnaccessData(nint psa);
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct PropertyKey : IEquatable<PropertyKey>
{
private Guid formatId;
private readonly int propertyId;
public Guid FormatId => formatId;
public int PropertyId => propertyId;
public PropertyKey(Guid formatId, int propertyId)
{
this.formatId = formatId;
this.propertyId = propertyId;
}
public PropertyKey(string formatId, int propertyId)
{
this.formatId = new Guid(formatId);
this.propertyId = propertyId;
}
public bool Equals(PropertyKey other) => other.Equals((object)this);
public override int GetHashCode() => formatId.GetHashCode() ^ propertyId;
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (!(obj is PropertyKey))
return false;
var other = (PropertyKey)obj;
return other.formatId.Equals(formatId) && (other.propertyId == propertyId);
}
public static bool operator ==(PropertyKey propKey1, PropertyKey propKey2) => propKey1.Equals(propKey2);
public static bool operator !=(PropertyKey propKey1, PropertyKey propKey2) => !propKey1.Equals(propKey2);
public override string ToString() => string.Format(System.Globalization.CultureInfo.InvariantCulture,
LocalizedMessages.PropertyKeyFormatString,
formatId.ToString("B"), propertyId);
}

View File

@@ -0,0 +1,304 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
#pragma warning disable CS0108
[ComImport,
Guid(ShellIIDGuid.IPropertyDescription),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyDescription
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetPropertyKey(out PropertyKey pkey);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCanonicalName([MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetPropertyType(out VarEnum pvartype);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime),
PreserveSig]
HResult GetDisplayName(out nint ppszName);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetEditInvitation(out nint ppszInvite);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetTypeFlags([In] PropertyTypeOptions mask, out PropertyTypeOptions ppdtFlags);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetViewFlags(out PropertyViewOptions ppdvFlags);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetDefaultColumnWidth(out uint pcxChars);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetDisplayType(out PropertyDisplayType pdisplaytype);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetColumnState(out PropertyColumnStateOptions pcsFlags);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetGroupingRange(out PropertyGroupingRange pgr);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetRelativeDescriptionType(out PropertySystemNativeMethods.RelativeDescriptionType prdt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetRelativeDescription([In] PropVariant propvar1, [In] PropVariant propvar2, [MarshalAs(UnmanagedType.LPWStr)] out string ppszDesc1, [MarshalAs(UnmanagedType.LPWStr)] out string ppszDesc2);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetSortDescription(out PropertySortDescription psd);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetSortDescriptionLabel([In] bool fDescending, out nint ppszDescription);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetAggregationType(out PropertyAggregationType paggtype);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetConditionType(out PropertyConditionType pcontype, out PropertyConditionOperation popDefault);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetEnumTypeList([In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IPropertyEnumTypeList ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void CoerceToCanonicalValue([In, Out] PropVariant propvar);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult FormatForDisplay([In] PropVariant propvar, [In] ref PropertyDescriptionFormatOptions pdfFlags, [MarshalAs(UnmanagedType.LPWStr)] out string ppszDisplay);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult IsValueCanonical([In] PropVariant propvar);
}
[ComImport,
Guid(ShellIIDGuid.IPropertyDescription2),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyDescription2 : IPropertyDescription
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetPropertyKey(out PropertyKey pkey);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCanonicalName([MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetPropertyType(out VarEnum pvartype);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetEditInvitation([MarshalAs(UnmanagedType.LPWStr)] out string ppszInvite);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetTypeFlags([In] PropertyTypeOptions mask, out PropertyTypeOptions ppdtFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetViewFlags(out PropertyViewOptions ppdvFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDefaultColumnWidth(out uint pcxChars);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDisplayType(out PropertyDisplayType pdisplaytype);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetColumnState(out uint pcsFlags);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetGroupingRange(out PropertyGroupingRange pgr);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetRelativeDescriptionType(out PropertySystemNativeMethods.RelativeDescriptionType prdt);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetRelativeDescription(
[In] PropVariant propvar1,
[In] PropVariant propvar2,
[MarshalAs(UnmanagedType.LPWStr)] out string ppszDesc1,
[MarshalAs(UnmanagedType.LPWStr)] out string ppszDesc2);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSortDescription(out PropertySortDescription psd);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetSortDescriptionLabel([In] int fDescending, [MarshalAs(UnmanagedType.LPWStr)] out string ppszDescription);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAggregationType(out PropertyAggregationType paggtype);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetConditionType(
out PropertyConditionType pcontype,
out PropertyConditionOperation popDefault);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetEnumTypeList([In] ref Guid riid, out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void CoerceToCanonicalValue([In, Out] PropVariant ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void FormatForDisplay([In] PropVariant propvar, [In] ref PropertyDescriptionFormatOptions pdfFlags, [MarshalAs(UnmanagedType.LPWStr)] out string ppszDisplay);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult IsValueCanonical([In] PropVariant propvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetImageReferenceForValue(
[In] PropVariant propvar,
[Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszImageRes);
}
[ComImport,
Guid(ShellIIDGuid.IPropertyDescriptionList),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyDescriptionList
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCount(out uint pcElem);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAt([In] uint iElem, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IPropertyDescription ppv);
}
[ComImport,
Guid(ShellIIDGuid.IPropertyEnumType),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyEnumType
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetEnumType([Out] out PropEnumType penumtype);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetValue([Out] PropVariant ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetRangeMinValue([Out] PropVariant ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetRangeSetValue([Out] PropVariant ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDisplayText([Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszDisplay);
}
[ComImport,
Guid(ShellIIDGuid.IPropertyEnumType2),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyEnumType2 : IPropertyEnumType
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetEnumType([Out] out PropEnumType penumtype);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetValue([Out] PropVariant ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetRangeMinValue([Out] PropVariant ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetRangeSetValue([Out] PropVariant ppropvar);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetDisplayText([Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszDisplay);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetImageReference([Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszImageRes);
}
[ComImport,
Guid(ShellIIDGuid.IPropertyEnumTypeList),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyEnumTypeList
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCount([Out] out uint pctypes);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAt(
[In] uint itype,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out IPropertyEnumType ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetConditionAt(
[In] uint index,
[In] ref Guid riid,
out nint ppv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void FindMatchingIndex(
[In] PropVariant propvarCmp,
[Out] out uint pnIndex);
}
[ComImport]
[Guid(ShellIIDGuid.IPropertyStore)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyStore
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetCount([Out] out uint propertyCount);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetAt([In] uint propertyIndex, out PropertyKey key);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetValue([In] ref PropertyKey key, [Out] PropVariant pv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), PreserveSig]
HResult SetValue([In] ref PropertyKey key, [In] PropVariant pv);
[PreserveSig]
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult Commit();
}
[ComImport]
[Guid(ShellIIDGuid.IPropertyStoreCache)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyStoreCache
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetState(ref PropertyKey key, [Out] out PropertyStoreCacheState state);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult GetValueAndState(ref PropertyKey propKey, [Out] PropVariant pv, [Out] out PropertyStoreCacheState state);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult SetState(ref PropertyKey propKey, PropertyStoreCacheState state);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
HResult SetValueAndState(ref PropertyKey propKey, [In] PropVariant pv, PropertyStoreCacheState state);
}
[ComImport]
[Guid(ShellIIDGuid.IPropertyStoreCapabilities)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyStoreCapabilities
{
HResult IsPropertyWritable([In] ref PropertyKey propertyKey);
}
#pragma warning restore 108

View File

@@ -0,0 +1,49 @@
using MicaSetup.Natives;
using System;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
public static class PropertySystemNativeMethods
{
public enum RelativeDescriptionType
{
General,
Date,
Size,
Count,
Revision,
Length,
Duration,
Speed,
Rate,
Rating,
Priority
}
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int PSGetNameFromPropertyKey(
ref PropertyKey propkey,
[Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszCanonicalName
);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern HResult PSGetPropertyDescription(
ref PropertyKey propkey,
ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out IPropertyDescription ppv
);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int PSGetPropertyDescriptionListFromString(
[In, MarshalAs(UnmanagedType.LPWStr)] string pszPropList,
[In] ref Guid riid,
out IPropertyDescriptionList ppv
);
[DllImport(Lib.PropSys, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int PSGetPropertyKeyFromName(
[In, MarshalAs(UnmanagedType.LPWStr)] string pszCanonicalName,
out PropertyKey propkey
);
}

View File

@@ -0,0 +1,150 @@
using MicaSetup.Natives;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace MicaSetup.Shell.Dialogs;
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b7d14566-0509-4cce-a71f-0a554233bd9b")]
public interface IInitializeWithFile
{
void Initialize([MarshalAs(UnmanagedType.LPWStr)] string filePath, AccessModes fileMode);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("7f73be3f-fb79-493c-a6c7-7ee14e245841")]
public interface IInitializeWithItem
{
void Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object shellItem, AccessModes accessMode);
}
[SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
[ComVisible(true)]
[Guid("b824b49d-22ac-4161-ac8a-9916e8fa3f7f")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInitializeWithStream
{
void Initialize(IStream stream, AccessModes fileMode);
}
[ComVisible(true)]
[Guid("e357fccd-a995-4576-b01f-234630154e96")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IThumbnailProvider
{
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#")]
void GetThumbnail(uint squareLength, out nint bitmapHandle, out uint bitmapType);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("fc4801a3-2ba9-11cf-a229-00aa003d7352")]
internal interface IObjectWithSite
{
void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkSite);
void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvSite);
}
[ComImport]
[Guid("00000114-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOleWindow
{
void GetWindow(out nint phwnd);
void ContextSensitiveHelp([MarshalAs(UnmanagedType.Bool)] bool fEnterMode);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("8895b1c6-b41f-4c1c-a562-0d564250836f")]
internal interface IPreviewHandler
{
void SetWindow(nint hwnd, ref RECT rect);
void SetRect(ref RECT rect);
void DoPreview();
void Unload();
void SetFocus();
void QueryFocus(out nint phwnd);
[PreserveSig]
HResult TranslateAccelerator(ref MSG pmsg);
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("fec87aaf-35f9-447a-adb7-20234491401a")]
internal interface IPreviewHandlerFrame
{
void GetWindowContext(nint pinfo);
[PreserveSig]
HResult TranslateAccelerator(ref MSG pmsg);
};
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("8327b13c-b63f-4b24-9b8a-d010dcc3f599")]
internal interface IPreviewHandlerVisuals
{
void SetBackgroundColor(COLORREF color);
void SetFont(ref LogFont plf);
void SetTextColor(COLORREF color);
}
[StructLayout(LayoutKind.Sequential)]
internal struct COLORREF
{
public uint Dword;
public Color Color => Color.FromArgb(
(int)(0x000000FFU & Dword),
(int)(0x0000FF00U & Dword) >> 8,
(int)(0x00FF0000U & Dword) >> 16);
}
[StructLayout(LayoutKind.Sequential)]
internal struct MSG
{
public nint hwnd;
public int message;
public nint wParam;
public nint lParam;
public int time;
public int pt_x;
public int pt_y;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal class LogFont
{
internal int height;
internal int width;
internal int escapement;
internal int orientation;
internal int weight;
internal byte italic;
internal byte underline;
internal byte strikeOut;
internal byte charSet;
internal byte outPrecision;
internal byte clipPrecision;
internal byte quality;
internal byte pitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
internal string lfFaceName = string.Empty;
}

View File

@@ -0,0 +1,132 @@
using MicaSetup.Natives;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace MicaSetup.Shell.Dialogs;
[StructLayout(LayoutKind.Sequential)]
public struct Message
{
private readonly nint windowHandle;
private readonly uint msg;
private readonly nint wparam;
private readonly nint lparam;
private readonly int time;
private POINT point;
internal Message(nint windowHandle, uint msg, nint wparam, nint lparam, int time, POINT point)
: this()
{
this.windowHandle = windowHandle;
this.msg = msg;
this.wparam = wparam;
this.lparam = lparam;
this.time = time;
this.point = point;
}
public nint LParam => lparam;
public uint Msg => msg;
public POINT Point => point;
public int Time => time;
public nint WindowHandle => windowHandle;
public nint WParam => wparam;
public static bool operator !=(Message first, Message second) => !(first == second);
public static bool operator ==(Message first, Message second) => first.WindowHandle == second.WindowHandle
&& first.Msg == second.Msg
&& first.WParam == second.WParam
&& first.LParam == second.LParam
&& first.Time == second.Time
&& first.Point == second.Point;
public override bool Equals(object obj) => (obj != null && obj is Message) ? this == (Message)obj : false;
public override int GetHashCode()
{
var hash = WindowHandle.GetHashCode();
hash = hash * 31 + Msg.GetHashCode();
hash = hash * 31 + WParam.GetHashCode();
hash = hash * 31 + LParam.GetHashCode();
hash = hash * 31 + Time.GetHashCode();
hash = hash * 31 + Point.GetHashCode();
return hash;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct WindowClassEx
{
internal uint Size;
internal uint Style;
internal ShellObjectWatcherNativeMethods.WndProcDelegate WndProc;
internal int ExtraClassBytes;
internal int ExtraWindowBytes;
internal nint InstanceHandle;
internal nint IconHandle;
internal nint CursorHandle;
internal nint BackgroundBrushHandle;
internal string MenuName;
internal string ClassName;
internal nint SmallIconHandle;
}
internal static class ShellObjectWatcherNativeMethods
{
public delegate int WndProcDelegate(nint hwnd, uint msg, nint wparam, nint lparam);
[DllImport(Lib.Ole32)]
public static extern HResult CreateBindCtx(
int reserved,
[Out] out IBindCtx bindCtx);
[DllImport(Lib.User32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern nint CreateWindowEx(
int extendedStyle,
[MarshalAs(UnmanagedType.LPWStr)]
string className,
[MarshalAs(UnmanagedType.LPWStr)]
string windowName,
int style,
int x,
int y,
int width,
int height,
nint parentHandle,
nint menuHandle,
nint instanceHandle,
nint additionalData);
[DllImport(Lib.User32)]
public static extern int DefWindowProc(
nint hwnd,
uint msg,
nint wparam,
nint lparam);
[DllImport(Lib.User32)]
public static extern void DispatchMessage([In] ref Message message);
[DllImport(Lib.User32)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetMessage(
[Out] out Message message,
nint windowHandle,
uint filterMinMessage,
uint filterMaxMessage);
[DllImport(Lib.User32, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint RegisterClassEx(
ref WindowClassEx windowClass
);
}

View File

@@ -0,0 +1,40 @@
using MicaSetup.Natives;
using System;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
internal static class StockIconsNativeMethods
{
[Flags]
internal enum StockIconOptions
{
Large = 0x000000000,
Small = 0x000000001,
ShellSize = 0x000000004,
Handle = 0x000000100,
SystemIndex = 0x000004000,
LinkOverlay = 0x000008000,
Selected = 0x000010000,
}
[PreserveSig]
[DllImport(Lib.Shell32, CharSet = CharSet.Unicode,
ExactSpelling = true, SetLastError = false)]
internal static extern HResult SHGetStockIconInfo(
StockIconIdentifier identifier,
StockIconOptions flags,
ref StockIconInfo info);
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct StockIconInfo
{
internal uint StuctureSize;
internal nint Handle;
internal int ImageIndex;
internal int Identifier;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
internal string Path;
}
}

View File

@@ -0,0 +1,172 @@
using System;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
[ComImportAttribute()]
[GuidAttribute("6332DEBF-87B5-4670-90C0-5E57B408A49E")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ICustomDestinationList
{
void SetAppID(
[MarshalAs(UnmanagedType.LPWStr)] string pszAppID);
[PreserveSig]
HResult BeginList(
out uint cMaxSlots,
ref Guid riid,
[Out(), MarshalAs(UnmanagedType.Interface)] out object ppvObject);
[PreserveSig]
HResult AppendCategory(
[MarshalAs(UnmanagedType.LPWStr)] string pszCategory,
[MarshalAs(UnmanagedType.Interface)] IObjectArray poa);
void AppendKnownCategory(
[MarshalAs(UnmanagedType.I4)] KnownDestinationCategory category);
[PreserveSig]
HResult AddUserTasks(
[MarshalAs(UnmanagedType.Interface)] IObjectArray poa);
void CommitList();
void GetRemovedDestinations(
ref Guid riid,
[Out(), MarshalAs(UnmanagedType.Interface)] out object ppvObject);
void DeleteList(
[MarshalAs(UnmanagedType.LPWStr)] string pszAppID);
void AbortList();
}
[ComImportAttribute()]
[GuidAttribute("92CA9DCD-5622-4BBA-A805-5E9F541BD8C9")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IObjectArray
{
void GetCount(out uint cObjects);
void GetAt(
uint iIndex,
ref Guid riid,
[Out(), MarshalAs(UnmanagedType.Interface)] out object ppvObject);
}
[ComImportAttribute()]
[GuidAttribute("5632B1A4-E38A-400A-928A-D4CD63230295")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IObjectCollection
{
[PreserveSig]
void GetCount(out uint cObjects);
[PreserveSig]
void GetAt(
uint iIndex,
ref Guid riid,
[Out(), MarshalAs(UnmanagedType.Interface)] out object ppvObject);
void AddObject(
[MarshalAs(UnmanagedType.Interface)] object pvObject);
void AddFromArray(
[MarshalAs(UnmanagedType.Interface)] IObjectArray poaSource);
void RemoveObject(uint uiIndex);
void Clear();
}
[ComImportAttribute()]
[GuidAttribute("c43dc798-95d1-4bea-9030-bb99e2983a1a")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITaskbarList4
{
[PreserveSig]
void HrInit();
[PreserveSig]
void AddTab(nint hwnd);
[PreserveSig]
void DeleteTab(nint hwnd);
[PreserveSig]
void ActivateTab(nint hwnd);
[PreserveSig]
void SetActiveAlt(nint hwnd);
[PreserveSig]
void MarkFullscreenWindow(
nint hwnd,
[MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
[PreserveSig]
void SetProgressValue(nint hwnd, ulong ullCompleted, ulong ullTotal);
[PreserveSig]
void SetProgressState(nint hwnd, TaskbarProgressBarStatus tbpFlags);
[PreserveSig]
void RegisterTab(nint hwndTab, nint hwndMDI);
[PreserveSig]
void UnregisterTab(nint hwndTab);
[PreserveSig]
void SetTabOrder(nint hwndTab, nint hwndInsertBefore);
[PreserveSig]
void SetTabActive(nint hwndTab, nint hwndInsertBefore, uint dwReserved);
[PreserveSig]
HResult ThumbBarAddButtons(
nint hwnd,
uint cButtons,
[MarshalAs(UnmanagedType.LPArray)] ThumbButton[] pButtons);
[PreserveSig]
HResult ThumbBarUpdateButtons(
nint hwnd,
uint cButtons,
[MarshalAs(UnmanagedType.LPArray)] ThumbButton[] pButtons);
[PreserveSig]
void ThumbBarSetImageList(nint hwnd, nint himl);
[PreserveSig]
void SetOverlayIcon(
nint hwnd,
nint hIcon,
[MarshalAs(UnmanagedType.LPWStr)] string pszDescription);
[PreserveSig]
void SetThumbnailTooltip(
nint hwnd,
[MarshalAs(UnmanagedType.LPWStr)] string pszTip);
[PreserveSig]
void SetThumbnailClip(
nint hwnd,
nint prcClip);
void SetTabProperties(nint hwndTab, SetTabPropertiesOption stpFlags);
}
[GuidAttribute("77F10CF0-3DB5-4966-B520-B7C54FD35ED6")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImportAttribute()]
internal class CDestinationList { }
[GuidAttribute("2D3468C1-36A7-43B6-AC24-D3F02FD9607A")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImportAttribute()]
internal class CEnumerableObjectCollection { }
[GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImportAttribute()]
internal class CTaskbarList { }

View File

@@ -0,0 +1,75 @@
using System;
using System.Runtime.InteropServices;
namespace MicaSetup.Shell.Dialogs;
public enum ThumbnailAlphaType
{
Unknown = 0,
NoAlphaChannel = 1,
HasAlphaChannel = 2,
}
internal enum KnownDestinationCategory
{
Frequent = 1,
Recent
}
internal enum SetTabPropertiesOption
{
None = 0x0,
UseAppThumbnailAlways = 0x1,
UseAppThumbnailWhenActive = 0x2,
UseAppPeekAlways = 0x4,
UseAppPeekWhenActive = 0x8
}
internal enum TaskbarProgressBarStatus
{
NoProgress = 0,
Indeterminate = 0x1,
Normal = 0x2,
Error = 0x4,
Paused = 0x8
}
internal enum ThumbButtonMask
{
Bitmap = 0x1,
Icon = 0x2,
Tooltip = 0x4,
THB_FLAGS = 0x8
}
[Flags]
internal enum ThumbButtonOptions
{
Enabled = 0x00000000,
Disabled = 0x00000001,
DismissOnClick = 0x00000002,
NoBackground = 0x00000004,
Hidden = 0x00000008,
NonInteractive = 0x00000010
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct ThumbButton
{
internal const int Clicked = 0x1800;
[MarshalAs(UnmanagedType.U4)]
internal ThumbButtonMask Mask;
internal uint Id;
internal uint Bitmap;
internal nint Icon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
internal string Tip;
[MarshalAs(UnmanagedType.U4)]
internal ThumbButtonOptions Flags;
}