diff --git a/PInvoke/Shell32/EmptyVC.cs b/PInvoke/Shell32/EmptyVC.cs
new file mode 100644
index 00000000..13d2e32a
--- /dev/null
+++ b/PInvoke/Shell32/EmptyVC.cs
@@ -0,0 +1,944 @@
+namespace Vanara.PInvoke;
+
+public static partial class Shell32
+{
+ /// A flag that can be sent to the disk cleanup manager.
+ [PInvokeData("emptyvc.h", MSDNShortId = "NN:emptyvc.IEmptyVolumeCacheCallBack")]
+ [Flags]
+ public enum EVCCBF : uint
+ {
+ ///
+ /// This flag should be set if the handler will not call this method again. It is typically set when the scan is near completion.
+ ///
+ EVCCBF_LASTNOTIFICATION = 0x0001
+ }
+
+ /// The flags that are used to pass information to the handler and back to the disk cleanup manager.
+ [PInvokeData("emptyvc.h", MSDNShortId = "NN:emptyvc.IEmptyVolumeCache")]
+ [Flags]
+ public enum EVCF
+ {
+ ///
+ /// Set this flag to indicate that the handler can display a UI. An example of a simple UI is a list box that displays the deletable
+ /// files and allows the user to select which ones to delete. The disk cleanup manager will then display a button below the cleanup
+ /// handler's description. The user clicks this button to request the UI. The default button text is "Settings", but the handler can
+ /// specify a different text by setting the AdvancedButtonText value in its registry key.
+ ///
+ EVCF_HASSETTINGS = 0x0001,
+
+ ///
+ /// Set this flag to have the handler checked by default in the cleanup manager's list. It will run every time the Disk Cleanup
+ /// utility runs, unless the user clears the handler's check box. Once the check box has been cleared, the handler will not be run
+ /// until the user selects it again.
+ ///
+ EVCF_ENABLEBYDEFAULT = 0x0002,
+
+ ///
+ /// Set this flag to remove the handler from the disk cleanup manager's list. All registry information will be deleted, and the
+ /// handler cannot be run again until the key and its values are restored. This flag is used primarily for one-time cleanup operations.
+ ///
+ EVCF_REMOVEFROMLIST = 0x0004,
+
+ ///
+ /// Set this flag to have the handler run automatically during scheduled cleanup. This flag should only be set when deletion of the
+ /// files is low-risk. As with EVCF_ENABLEBYDEFAULT, the user can choose not to run the handler by clearing its check box in
+ /// the disk cleanup manager's list.
+ ///
+ EVCF_ENABLEBYDEFAULT_AUTO = 0x0008,
+
+ ///
+ /// Set this flag when there are no files to delete. When IEmptyVolumeCache::GetSpaceUsed is called, set the pdwSpaceUsed
+ /// parameter to zero, and the disk cleanup manager will omit the handler from its list.
+ ///
+ EVCF_DONTSHOWIFZERO = 0x0010,
+
+ ///
+ /// If the disk cleanup manager is being run on a schedule, it will set this flag. You must assign values to the
+ /// ppwszDisplayName and ppwszDescription parameters. If this flag is set, the disk cleanup manager will not call
+ /// IEmptyVolumeCache::GetSpaceUsed, IEmptyVolumeCache::Purge, or IEmptyVolumeCache::ShowProperties. Because
+ /// IEmptyVolumeCache::Purge will not be called, cleanup must be handled by IEmptyVolumeCache::Initialize. The handler
+ /// should ignore the pcwszVolume parameter and clean up any unneeded files regardless of what drive they are on. Because
+ /// there is no opportunity for user feedback, only those files that are extremely safe to clean up should be touched.
+ ///
+ EVCF_SETTINGSMODE = 0x0020,
+
+ ///
+ /// If this flag is set, the user is out of disk space on the drive. When this flag is received, the handler should be aggressive
+ /// about freeing disk space, even if it results in a performance loss. The handler, however, should not delete files that would
+ /// cause an application to fail, or the user to lose data.
+ ///
+ EVCF_OUTOFDISKSPACE = 0x0040,
+
+ ///
+ EVCF_USERCONSENTOBTAINED = 0x0080,
+
+ ///
+ EVCF_SYSTEMAUTORUN = 0x0100,
+ }
+
+ ///
+ /// Used by the disk cleanup manager to communicate with a disk cleanup handler. Exposes methods that enable the manager to request
+ /// information from a handler, and notify it of events such as the start of a scan or purge.
+ ///
+ ///
+ /// This interface must be implemented by disk cleanup handlers running on Windows 98. Handlers running on Windows 2000 should also
+ /// expose IEmptyVolumeCache2.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nn-emptyvc-iemptyvolumecache
+ [PInvokeData("emptyvc.h", MSDNShortId = "NN:emptyvc.IEmptyVolumeCache")]
+ [ComImport, Guid("8FCE5227-04DA-11d1-A004-00805F8ABE06"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IEmptyVolumeCache
+ {
+ /// Initializes the disk cleanup handler, based on the information stored under the specified registry key.
+ ///
+ /// Type: HKEY
+ /// A handle to the registry key that holds the information about the handler object.
+ ///
+ ///
+ /// Type: LPCWSTR
+ /// A pointer to a null-terminated Unicode string with the volume root—for example, "C:".
+ ///
+ ///
+ /// Type: LPWSTR*
+ ///
+ /// A pointer to a null-terminated Unicode string with the name that will be displayed in the disk cleanup manager's list of
+ /// handlers. If no value is assigned, the registry value will be used.
+ ///
+ ///
+ ///
+ /// Type: LPWSTR*
+ ///
+ /// A pointer to a null-terminated Unicode string that will be displayed when this object is selected from the disk cleanup manager's
+ /// list of available disk cleanup handlers. If no value is assigned, the registry value will be used.
+ ///
+ ///
+ ///
+ /// Type: DWORD*
+ /// The flags that are used to pass information to the handler and back to the disk cleanup manager.
+ /// These flags can be passed in to the object:
+ /// EVCF_OUTOFDISKSPACE
+ ///
+ /// If this flag is set, the user is out of disk space on the drive. When this flag is received, the handler should be aggressive
+ /// about freeing disk space, even if it results in a performance loss. The handler, however, should not delete files that would
+ /// cause an application to fail, or the user to lose data.
+ ///
+ /// EVCF_SETTINGSMODE
+ ///
+ /// If the disk cleanup manager is being run on a schedule, it will set this flag. You must assign values to the
+ /// ppwszDisplayName and ppwszDescription parameters. If this flag is set, the disk cleanup manager will not call
+ /// IEmptyVolumeCache::GetSpaceUsed, IEmptyVolumeCache::Purge, or IEmptyVolumeCache::ShowProperties. Because
+ /// IEmptyVolumeCache::Purge will not be called, cleanup must be handled by IEmptyVolumeCache::Initialize. The handler
+ /// should ignore the pcwszVolume parameter and clean up any unneeded files regardless of what drive they are on. Because
+ /// there is no opportunity for user feedback, only those files that are extremely safe to clean up should be touched.
+ ///
+ /// These flags can be passed by the handler back to the disk cleanup manager:
+ /// EVCF_DONTSHOWIFZERO
+ ///
+ /// Set this flag when there are no files to delete. When IEmptyVolumeCache::GetSpaceUsed is called, set the pdwSpaceUsed
+ /// parameter to zero, and the disk cleanup manager will omit the handler from its list.
+ ///
+ /// EVCF_ENABLEBYDEFAULT
+ ///
+ /// Set this flag to have the handler checked by default in the cleanup manager's list. It will run every time the Disk Cleanup
+ /// utility runs, unless the user clears the handler's check box. Once the check box has been cleared, the handler will not be run
+ /// until the user selects it again.
+ ///
+ /// EVCF_ENABLEBYDEFAULT_AUTO
+ ///
+ /// Set this flag to have the handler run automatically during scheduled cleanup. This flag should only be set when deletion of the
+ /// files is low-risk. As with EVCF_ENABLEBYDEFAULT, the user can choose not to run the handler by clearing its check box in
+ /// the disk cleanup manager's list.
+ ///
+ /// EVCF_HASSETTINGS
+ ///
+ /// Set this flag to indicate that the handler can display a UI. An example of a simple UI is a list box that displays the deletable
+ /// files and allows the user to select which ones to delete. The disk cleanup manager will then display a button below the cleanup
+ /// handler's description. The user clicks this button to request the UI. The default button text is "Settings", but the handler can
+ /// specify a different text by setting the AdvancedButtonText value in its registry key.
+ ///
+ /// EVCF_REMOVEFROMLIST
+ ///
+ /// Set this flag to remove the handler from the disk cleanup manager's list. All registry information will be deleted, and the
+ /// handler cannot be run again until the key and its values are restored. This flag is used primarily for one-time cleanup operations.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// Success.
+ ///
+ /// -
+ /// S_FALSE
+ /// There are no files to delete.
+ ///
+ /// -
+ /// E_ABORT
+ /// The cleanup operation was ended prematurely.
+ ///
+ /// -
+ /// E_FAIL
+ /// The cleanup operation failed.
+ ///
+ ///
+ ///
+ ///
+ /// This method is used by the Windows 98 disk cleanup manager. Windows 2000 uses the InitializeEx method exported by IEmptyVolumeCache2.
+ ///
+ /// Use CoTaskMemAlloc to allocate memory for the strings returned through ppwszDisplayName and ppwszDescription. The
+ /// disk cleanup manager will free the memory when it is no longer needed.
+ ///
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-initialize HRESULT Initialize( [in] HKEY
+ // hkRegKey, [in] LPCWSTR pcwszVolume, [out] LPWSTR *ppwszDisplayName, [out] LPWSTR *ppwszDescription, [in, out] DWORD *pdwFlags );
+ [PreserveSig]
+ HRESULT Initialize([In] HKEY hkRegKey, [MarshalAs(UnmanagedType.LPWStr)] string pcwszVolume, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszDisplayName,
+ [MarshalAs(UnmanagedType.LPWStr)] out string ppwszDescription, out EVCF pdwFlags);
+
+ /// Requests the amount of disk space that the disk cleanup handler can free.
+ ///
+ /// Type: DWORDLONG*
+ ///
+ /// The amount of disk space, in bytes, that the handler can free. This value will be displayed in the disk cleanup manager's list,
+ /// to the right of the handler's check box. To indicate that you do not know how much disk space can be freed, set this parameter to
+ /// -1, and "???MB" will be displayed. If you set the EVCF_DONTSHOWIFZERO flag when Initialize was called, setting
+ /// pdwSpaceUsed to zero will notify the disk cleanup manager to omit the handler from its list.
+ ///
+ ///
+ ///
+ /// Type: IEmptyVolumeCacheCallback*
+ ///
+ /// A pointer to the disk cleanup manager's IEmptyVolumeCacheCallback interface. This pointer can be used to call that interface's
+ /// ScanProgress method to report on the progress of the operation.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// Success.
+ ///
+ /// -
+ /// S_FALSE
+ /// An error occurred when the handler tried to calculate the amount of disk space that could be freed.
+ ///
+ /// -
+ /// E_ABORT
+ ///
+ /// The scan operation was ended prematurely. This value is usually returned when a call to ScanProgress returns E_ABORT. This return
+ /// value indicates that the user canceled the operation by clicking the disk cleanup manager's Cancel button.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// When this method is called by the disk cleanup manager, the handler should start scanning its files to determine which of them
+ /// can be deleted, and how much disk space will be freed. Handlers should call IEmptyVolumeCache::ScanProgress periodically to keep
+ /// the user informed of the progress of the scan, especially if it will take a long time. Calling this method frequently also allows
+ /// the handler to determine whether the user has canceled the operation. If ScanProgress returns E_ABORT, the user has
+ /// canceled the scan. The handler should immediately stop scanning and return E_ABORT.
+ ///
+ ///
+ /// You should only set the pdwSpaceUsed parameter to -1 as a last resort. The handler is of limited value to a user if they
+ /// don't know how much space will be freed.
+ ///
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-getspaceused HRESULT GetSpaceUsed( [out]
+ // DWORDLONG *pdwlSpaceUsed, [in] IEmptyVolumeCacheCallBack *picb );
+ [PreserveSig]
+ HRESULT GetSpaceUsed(out ulong pdwlSpaceUsed, [In, Optional] IEmptyVolumeCacheCallBack? picb);
+
+ /// Notifies the handler to start deleting its unneeded files.
+ ///
+ /// Type: DWORDLONG
+ ///
+ /// The amount of disk space that the handler should free. If this parameter is set to -1, the handler should delete all its files.
+ ///
+ ///
+ ///
+ /// Type: IEmptyVolumeCacheCallback*
+ ///
+ /// A pointer to the disk cleanup manager's IEmptyVolumeCacheCallBack interface. This pointer can be used to call the interface's
+ /// PurgeProgress method to report on the progress of the operation.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// Success.
+ ///
+ /// -
+ /// E_ABORT
+ ///
+ /// The operation was ended prematurely. This value is usually returned when PurgeProgress returns E_ABORT. This typically happens
+ /// when the user cancels the operation by clicking the disk cleanup manager's Cancel button.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// For Windows 98, the dwSpaceToFree parameter is always set to the value specified by the handler when
+ /// IEmptyVolumeCache::GetSpaceUsed was called.
+ ///
+ ///
+ /// In general, handlers should be kept simple and delete all of their files when this function is called. If there are significant
+ /// performance advantages to only deleting a portion of the files, the handler should implement the ShowProperties method. When
+ /// called, this method displays a UI that allows the user to select the files to be deleted.
+ ///
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-purge HRESULT Purge( [in] DWORDLONG
+ // dwlSpaceToFree, [in] IEmptyVolumeCacheCallBack *picb );
+ [PreserveSig]
+ HRESULT Purge(ulong dwlSpaceToFree = ulong.MaxValue, [In] IEmptyVolumeCacheCallBack? picb = null);
+
+ /// Notifies the handler to display its UI.
+ ///
+ /// Type: HWND
+ /// The parent window to be used when displaying the UI.
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// The user changed one or more settings.
+ ///
+ /// -
+ /// S_FALSE
+ /// No settings were changed.
+ ///
+ ///
+ ///
+ ///
+ /// A handler can display a UI, which is typically used to allow the user to select which files are to be cleaned up and how. To do
+ /// so, the handler sets the EVCF_HASSETTINGS flag in the pdwFlags parameter when Initialize is called. The disk
+ /// cleanup manager will then display a Settings button. When that button is clicked, the disk cleanup manager calls
+ /// ShowProperties to notify the handler to display its UI.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-showproperties HRESULT ShowProperties(
+ // [in] HWND hwnd );
+ [PreserveSig]
+ HRESULT ShowProperties([In] HWND hwnd);
+
+ /// Notifies the handler that the disk cleanup manager is shutting down.
+ ///
+ /// Type: DWORD*
+ /// A flag that can be set to return information to the disk cleanup manager. It can have the following value.
+ /// EVCF_REMOVEFROMLIST
+ /// If this flag is set, the disk cleanup manager will delete the handler's registry subkey.
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// This value should always be returned.
+ ///
+ ///
+ ///
+ ///
+ /// If the EVCF_REMOVEFROMLIST flag is set, the handler will not be run again unless the registry entries are reestablished.
+ /// This flag is typically used for a handler that will only run once.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-deactivate HRESULT Deactivate( [out]
+ // DWORD *pdwFlags );
+ [PreserveSig]
+ HRESULT Deactivate(out EVCF pdwFlags);
+ }
+
+ ///
+ /// Extends IEmptyVolumeCache. This interface defines one additional method, InitializeEx, that provides better localization support than IEmptyVolumeCache::Initialize.
+ ///
+ ///
+ /// This interface should be exported by disk cleanup handlers running on Windows 2000. Handlers running on Windows 98 must export IEmptyVolumeCache.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nn-emptyvc-iemptyvolumecache2
+ [PInvokeData("emptyvc.h", MSDNShortId = "NN:emptyvc.IEmptyVolumeCache2")]
+ [ComImport, Guid("02b7e3ba-4db3-11d2-b2d9-00c04f8eec8c"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IEmptyVolumeCache2 : IEmptyVolumeCache
+ {
+ /// Initializes the disk cleanup handler, based on the information stored under the specified registry key.
+ ///
+ /// Type: HKEY
+ /// A handle to the registry key that holds the information about the handler object.
+ ///
+ ///
+ /// Type: LPCWSTR
+ /// A pointer to a null-terminated Unicode string with the volume root—for example, "C:".
+ ///
+ ///
+ /// Type: LPWSTR*
+ ///
+ /// A pointer to a null-terminated Unicode string with the name that will be displayed in the disk cleanup manager's list of
+ /// handlers. If no value is assigned, the registry value will be used.
+ ///
+ ///
+ ///
+ /// Type: LPWSTR*
+ ///
+ /// A pointer to a null-terminated Unicode string that will be displayed when this object is selected from the disk cleanup manager's
+ /// list of available disk cleanup handlers. If no value is assigned, the registry value will be used.
+ ///
+ ///
+ ///
+ /// Type: DWORD*
+ /// The flags that are used to pass information to the handler and back to the disk cleanup manager.
+ /// These flags can be passed in to the object:
+ /// EVCF_OUTOFDISKSPACE
+ ///
+ /// If this flag is set, the user is out of disk space on the drive. When this flag is received, the handler should be aggressive
+ /// about freeing disk space, even if it results in a performance loss. The handler, however, should not delete files that would
+ /// cause an application to fail, or the user to lose data.
+ ///
+ /// EVCF_SETTINGSMODE
+ ///
+ /// If the disk cleanup manager is being run on a schedule, it will set this flag. You must assign values to the
+ /// ppwszDisplayName and ppwszDescription parameters. If this flag is set, the disk cleanup manager will not call
+ /// IEmptyVolumeCache::GetSpaceUsed, IEmptyVolumeCache::Purge, or IEmptyVolumeCache::ShowProperties. Because
+ /// IEmptyVolumeCache::Purge will not be called, cleanup must be handled by IEmptyVolumeCache::Initialize. The handler
+ /// should ignore the pcwszVolume parameter and clean up any unneeded files regardless of what drive they are on. Because
+ /// there is no opportunity for user feedback, only those files that are extremely safe to clean up should be touched.
+ ///
+ /// These flags can be passed by the handler back to the disk cleanup manager:
+ /// EVCF_DONTSHOWIFZERO
+ ///
+ /// Set this flag when there are no files to delete. When IEmptyVolumeCache::GetSpaceUsed is called, set the pdwSpaceUsed
+ /// parameter to zero, and the disk cleanup manager will omit the handler from its list.
+ ///
+ /// EVCF_ENABLEBYDEFAULT
+ ///
+ /// Set this flag to have the handler checked by default in the cleanup manager's list. It will run every time the Disk Cleanup
+ /// utility runs, unless the user clears the handler's check box. Once the check box has been cleared, the handler will not be run
+ /// until the user selects it again.
+ ///
+ /// EVCF_ENABLEBYDEFAULT_AUTO
+ ///
+ /// Set this flag to have the handler run automatically during scheduled cleanup. This flag should only be set when deletion of the
+ /// files is low-risk. As with EVCF_ENABLEBYDEFAULT, the user can choose not to run the handler by clearing its check box in
+ /// the disk cleanup manager's list.
+ ///
+ /// EVCF_HASSETTINGS
+ ///
+ /// Set this flag to indicate that the handler can display a UI. An example of a simple UI is a list box that displays the deletable
+ /// files and allows the user to select which ones to delete. The disk cleanup manager will then display a button below the cleanup
+ /// handler's description. The user clicks this button to request the UI. The default button text is "Settings", but the handler can
+ /// specify a different text by setting the AdvancedButtonText value in its registry key.
+ ///
+ /// EVCF_REMOVEFROMLIST
+ ///
+ /// Set this flag to remove the handler from the disk cleanup manager's list. All registry information will be deleted, and the
+ /// handler cannot be run again until the key and its values are restored. This flag is used primarily for one-time cleanup operations.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// Success.
+ ///
+ /// -
+ /// S_FALSE
+ /// There are no files to delete.
+ ///
+ /// -
+ /// E_ABORT
+ /// The cleanup operation was ended prematurely.
+ ///
+ /// -
+ /// E_FAIL
+ /// The cleanup operation failed.
+ ///
+ ///
+ ///
+ ///
+ /// This method is used by the Windows 98 disk cleanup manager. Windows 2000 uses the InitializeEx method exported by IEmptyVolumeCache2.
+ ///
+ /// Use CoTaskMemAlloc to allocate memory for the strings returned through ppwszDisplayName and ppwszDescription. The
+ /// disk cleanup manager will free the memory when it is no longer needed.
+ ///
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-initialize HRESULT Initialize( [in] HKEY
+ // hkRegKey, [in] LPCWSTR pcwszVolume, [out] LPWSTR *ppwszDisplayName, [out] LPWSTR *ppwszDescription, [in, out] DWORD *pdwFlags );
+ [PreserveSig]
+ new HRESULT Initialize([In] HKEY hkRegKey, [MarshalAs(UnmanagedType.LPWStr)] string pcwszVolume, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszDisplayName,
+ [MarshalAs(UnmanagedType.LPWStr)] out string ppwszDescription, out EVCF pdwFlags);
+
+ /// Requests the amount of disk space that the disk cleanup handler can free.
+ ///
+ /// Type: DWORDLONG*
+ ///
+ /// The amount of disk space, in bytes, that the handler can free. This value will be displayed in the disk cleanup manager's list,
+ /// to the right of the handler's check box. To indicate that you do not know how much disk space can be freed, set this parameter to
+ /// -1, and "???MB" will be displayed. If you set the EVCF_DONTSHOWIFZERO flag when Initialize was called, setting
+ /// pdwSpaceUsed to zero will notify the disk cleanup manager to omit the handler from its list.
+ ///
+ ///
+ ///
+ /// Type: IEmptyVolumeCacheCallback*
+ ///
+ /// A pointer to the disk cleanup manager's IEmptyVolumeCacheCallback interface. This pointer can be used to call that interface's
+ /// ScanProgress method to report on the progress of the operation.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// Success.
+ ///
+ /// -
+ /// S_FALSE
+ /// An error occurred when the handler tried to calculate the amount of disk space that could be freed.
+ ///
+ /// -
+ /// E_ABORT
+ ///
+ /// The scan operation was ended prematurely. This value is usually returned when a call to ScanProgress returns E_ABORT. This return
+ /// value indicates that the user canceled the operation by clicking the disk cleanup manager's Cancel button.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// When this method is called by the disk cleanup manager, the handler should start scanning its files to determine which of them
+ /// can be deleted, and how much disk space will be freed. Handlers should call IEmptyVolumeCache::ScanProgress periodically to keep
+ /// the user informed of the progress of the scan, especially if it will take a long time. Calling this method frequently also allows
+ /// the handler to determine whether the user has canceled the operation. If ScanProgress returns E_ABORT, the user has
+ /// canceled the scan. The handler should immediately stop scanning and return E_ABORT.
+ ///
+ ///
+ /// You should only set the pdwSpaceUsed parameter to -1 as a last resort. The handler is of limited value to a user if they
+ /// don't know how much space will be freed.
+ ///
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-getspaceused HRESULT GetSpaceUsed( [out]
+ // DWORDLONG *pdwlSpaceUsed, [in] IEmptyVolumeCacheCallBack *picb );
+ [PreserveSig]
+ new HRESULT GetSpaceUsed(out ulong pdwlSpaceUsed, [In, Optional] IEmptyVolumeCacheCallBack? picb);
+
+ /// Notifies the handler to start deleting its unneeded files.
+ ///
+ /// Type: DWORDLONG
+ ///
+ /// The amount of disk space that the handler should free. If this parameter is set to -1, the handler should delete all its files.
+ ///
+ ///
+ ///
+ /// Type: IEmptyVolumeCacheCallback*
+ ///
+ /// A pointer to the disk cleanup manager's IEmptyVolumeCacheCallBack interface. This pointer can be used to call the interface's
+ /// PurgeProgress method to report on the progress of the operation.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// Success.
+ ///
+ /// -
+ /// E_ABORT
+ ///
+ /// The operation was ended prematurely. This value is usually returned when PurgeProgress returns E_ABORT. This typically happens
+ /// when the user cancels the operation by clicking the disk cleanup manager's Cancel button.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// For Windows 98, the dwSpaceToFree parameter is always set to the value specified by the handler when
+ /// IEmptyVolumeCache::GetSpaceUsed was called.
+ ///
+ ///
+ /// In general, handlers should be kept simple and delete all of their files when this function is called. If there are significant
+ /// performance advantages to only deleting a portion of the files, the handler should implement the ShowProperties method. When
+ /// called, this method displays a UI that allows the user to select the files to be deleted.
+ ///
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-purge HRESULT Purge( [in] DWORDLONG
+ // dwlSpaceToFree, [in] IEmptyVolumeCacheCallBack *picb );
+ [PreserveSig]
+ new HRESULT Purge(ulong dwlSpaceToFree = ulong.MaxValue, [In] IEmptyVolumeCacheCallBack? picb = null);
+
+ /// Notifies the handler to display its UI.
+ ///
+ /// Type: HWND
+ /// The parent window to be used when displaying the UI.
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// The user changed one or more settings.
+ ///
+ /// -
+ /// S_FALSE
+ /// No settings were changed.
+ ///
+ ///
+ ///
+ ///
+ /// A handler can display a UI, which is typically used to allow the user to select which files are to be cleaned up and how. To do
+ /// so, the handler sets the EVCF_HASSETTINGS flag in the pdwFlags parameter when Initialize is called. The disk
+ /// cleanup manager will then display a Settings button. When that button is clicked, the disk cleanup manager calls
+ /// ShowProperties to notify the handler to display its UI.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-showproperties HRESULT ShowProperties(
+ // [in] HWND hwnd );
+ [PreserveSig]
+ new HRESULT ShowProperties([In] HWND hwnd);
+
+ /// Notifies the handler that the disk cleanup manager is shutting down.
+ ///
+ /// Type: DWORD*
+ /// A flag that can be set to return information to the disk cleanup manager. It can have the following value.
+ /// EVCF_REMOVEFROMLIST
+ /// If this flag is set, the disk cleanup manager will delete the handler's registry subkey.
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// This value should always be returned.
+ ///
+ ///
+ ///
+ ///
+ /// If the EVCF_REMOVEFROMLIST flag is set, the handler will not be run again unless the registry entries are reestablished.
+ /// This flag is typically used for a handler that will only run once.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache-deactivate HRESULT Deactivate( [out]
+ // DWORD *pdwFlags );
+ [PreserveSig]
+ new HRESULT Deactivate(out EVCF pdwFlags);
+
+ /// Initializes the disk cleanup handler. It provides better support for localization than Initialize.
+ ///
+ /// Type: HKEY
+ /// A handle to the registry key that holds the information about the handler object.
+ ///
+ ///
+ /// Type: LPCWSTR
+ /// A pointer to a null-terminated Unicode string with the volume root—for example, "C:".
+ ///
+ ///
+ /// Type: LPCWSTR
+ /// A pointer to a null-terminated Unicode string with the name of the handler's registry key.
+ ///
+ ///
+ /// Type: LPWSTR*
+ ///
+ /// A pointer to a null-terminated Unicode string with the name that will be displayed in the disk cleanup manager's list of
+ /// handlers. You must assign a value to this parameter.
+ ///
+ ///
+ ///
+ /// Type: LPWSTR*
+ ///
+ /// A pointer to a null-terminated Unicode string that will be displayed when this object is selected from the disk cleanup manager's
+ /// list of available disk cleaners. You must assign a value to this parameter.
+ ///
+ ///
+ ///
+ /// Type: LPWSTR*
+ ///
+ /// A pointer to a null-terminated Unicode string with the text that will be displayed on the disk cleanup manager's Settings
+ /// button. If the EVCF_HASSETTINGS flag is set, you must assign a value to ppwszBtnText. Otherwise, you can set it to NULL.
+ ///
+ ///
+ ///
+ /// Type: DWORD*
+ /// Flags that are used to pass information to the handler, and back to the disk cleanup manager.
+ /// These flags can be passed in to the object:
+ /// EVCF_OUTOFDISKSPACE
+ ///
+ /// If this flag is set, the user is out of disk space on the drive. When this flag is received, the handler should be aggressive
+ /// about freeing disk space, even if it results in a performance loss. The handler, however, should not delete files that would
+ /// cause an application to fail, or the user to lose data.
+ ///
+ /// EVCF_SETTINGSMODE
+ ///
+ /// If the disk cleanup manager is run on a schedule, it will set the EVCF_SETTINGSMODE flag. You must assign values to the
+ /// ppwszDisplayName and ppwszDescription parameters. If this flag is set, the disk cleanup manager will not call
+ /// GetSpaceUsed, Purge, or ShowProperties. Because Purge will not be called, cleanup must be handled by InitializeEx.
+ /// The handler should ignore the pcwszVolume parameter and clean up any unneeded files regardless of what drive they are on.
+ /// Because there is no opportunity for user feedback, only those files that are extremely safe to clean up should be touched.
+ ///
+ /// These flags can be passed by the handler back to the disk cleanup manager:
+ /// EVCF_DONTSHOWIFZERO
+ ///
+ /// Set this flag when there are no files to delete. When GetSpaceUsed is called, set the pdwSpaceUsed parameter to zero, and
+ /// the disk cleanup manager will omit the handler from its list.
+ ///
+ /// EVCF_ENABLEBYDEFAULT
+ ///
+ /// Set this flag to have the handler checked by default in the disk cleanup manager's list. The handler will be run every time the
+ /// disk cleanup utility runs, unless the user clears the handler's check box. Once the check box has been cleared, the handler will
+ /// not be run until the user selects it again.
+ ///
+ /// EVCF_ENABLEBYDEFAULT_AUTO
+ ///
+ /// Set this flag to have the handler run automatically during scheduled cleanup. This flag should only be set when deletion of the
+ /// files is low-risk. As with EVCF_ENABLEBYDEFAULT, the user can choose not to run the handler by clearing its check box in
+ /// the disk cleanup manager's list.
+ ///
+ /// EVCF_HASSETTINGS
+ ///
+ /// Set this flag to indicate that the handler can display a UI. An example of a simple UI is a list box that displays the deletable
+ /// files and allows the user to select which ones to delete. The disk cleanup manager will then display a button below the cleanup
+ /// handler's description. The user clicks this button to request the UI. Use the ppwszBtnText parameter to specify the
+ /// button's text.
+ ///
+ /// EVCF_REMOVEFROMLIST
+ ///
+ /// Set this flag to remove the handler from the disk cleanup manager's list. All registry information will be deleted, and the
+ /// handler cannot be run again until the key and its values are restored. This flag is used primarily for one-time cleanup operations.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// Success.
+ ///
+ /// -
+ /// S_FALSE
+ /// There are no files to delete.
+ ///
+ /// -
+ /// E_ABORT
+ /// The cleanup operation was ended prematurely.
+ ///
+ /// -
+ /// E_FAIL
+ /// The cleanup operation failed.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The Windows 2000 disk cleanup manager will first call IEmptyVolumeCache2::InitializeEx to initialize a disk cleanup
+ /// handler. It will only call Initialize if the IEmptyVolumeCache2 interface is not implemented. The Windows 98 disk cleanup manager
+ /// only supports Initialize.
+ ///
+ ///
+ /// InitializeEx is intended to provide better localization support than Initialize. When InitializeEx is called, the
+ /// handler application must assign appropriately localized values to the ppwszDisplayName and ppwszDescription
+ /// parameters. If the Settings button is enabled, you must also assign a value to the ppwszBtnText parameter. Unlike
+ /// Initialize, if you set these strings to NULL to notify the disk cleanup manager to retrieve the default values from
+ /// the registry, InitializeEx will fail.
+ ///
+ ///
+ /// Use CoTaskMemAlloc to allocate memory for the strings returned through ppwszDisplayName, ppwszDescription, and
+ /// ppwszBtnText. The disk cleanup manager will free the memory when it is no longer needed.
+ ///
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecache2-initializeex HRESULT InitializeEx( [in]
+ // HKEY hkRegKey, [in] LPCWSTR pcwszVolume, [in] LPCWSTR pcwszKeyName, [out] LPWSTR *ppwszDisplayName, [out] LPWSTR
+ // *ppwszDescription, [out] LPWSTR *ppwszBtnText, [in, out] DWORD *pdwFlags );
+ [PreserveSig]
+ HRESULT InitializeEx([In] HKEY hkRegKey, [MarshalAs(UnmanagedType.LPWStr)] string pcwszVolume, [MarshalAs(UnmanagedType.LPWStr)] string pcwszKeyName,
+ [MarshalAs(UnmanagedType.LPWStr)] out string ppwszDisplayName, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszDescription,
+ [MarshalAs(UnmanagedType.LPWStr)] out string? ppwszBtnText, out EVCF pdwFlags);
+ }
+
+ /// Exposes methods that are used by a disk cleanup handler to communicate with the disk cleanup manager.
+ ///
+ /// A disk cleanup handler uses this interface to report to the disk cleanup manager on the progress either of deleting files or of
+ /// scanning for deletable files. It also provides a way to query the manager, to find out if the user has canceled the operation. The
+ /// handler receives a pointer to this interface when the manager calls the IEmptyVolumeCache::GetSpaceUsed or IEmptyVolumeCache::Purge methods.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nn-emptyvc-iemptyvolumecachecallback
+ [PInvokeData("emptyvc.h", MSDNShortId = "NN:emptyvc.IEmptyVolumeCacheCallBack")]
+ [ComImport, Guid("6E793361-73C6-11D0-8469-00AA00442901"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IEmptyVolumeCacheCallBack
+ {
+ /// Called by a disk cleanup handler to update the disk cleanup manager on the progress of a scan for deletable files.
+ ///
+ /// Type: DWORDLONG
+ /// The amount of disk space that the handler can free at this point in the scan.
+ ///
+ ///
+ /// Type: DWORD
+ /// A flag that can be sent to the disk cleanup manager. This flag can have the following value.
+ /// EVCCBF_LASTNOTIFICATION
+ /// This flag should be set if the handler will not call this method again. It is typically set when the scan is near completion.
+ ///
+ ///
+ /// Type: LPCWSTR
+ /// Reserved.
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// The handler should continue scanning for deletable files.
+ ///
+ /// -
+ /// E_ABORT
+ ///
+ /// This value is returned when the user clicks the Cancel button on the disk cleanup manager's dialog box while a scan is in
+ /// progress. The handler should stop scanning and shut down.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// This method is typically called by the handler's GetSpaceUsed method while the handler is scanning for deletable files.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecachecallback-scanprogress HRESULT
+ // ScanProgress( [in] DWORDLONG dwlSpaceUsed, [in] DWORD dwFlags, [in] LPCWSTR pcwszStatus );
+ [PreserveSig]
+ HRESULT ScanProgress(ulong dwlSpaceUsed, EVCCBF dwFlags, [Optional] string? pcwszStatus);
+
+ ///
+ /// Called periodically by a disk cleanup handler to update the disk cleanup manager on the progress of a purge of deletable files.
+ ///
+ ///
+ /// Type: DWORDLONG
+ ///
+ /// The amount of disk space, in bytes, that has been freed at this point in the purge. The disk cleanup manager uses this value to
+ /// update its progress bar.
+ ///
+ ///
+ ///
+ /// Type: DWORDLONG
+ /// The amount of disk space, in bytes, that remains to be freed at this point in the purge.
+ ///
+ ///
+ /// Type: DWORD
+ /// A flag that can be sent to the disk cleanup manager. It can have the following value:
+ /// EVCCBF_LASTNOTIFICATION
+ /// This flag should be set if the handler will not call this method again. It is typically set when the purge is near completion.
+ ///
+ ///
+ /// Type: LPCWSTR
+ /// Reserved.
+ ///
+ ///
+ /// Type: HRESULT
+ /// This method can return one of these values.
+ ///
+ ///
+ /// Return code
+ /// Description
+ ///
+ /// -
+ /// S_OK
+ /// The handler should continue purging deletable files.
+ ///
+ /// -
+ /// E_ABORT
+ ///
+ /// This value is returned when the user clicks the Cancel button on the disk cleanup manager's dialog box while a scan is in
+ /// progress. The handler should stop purging files and shut down.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// This method is typically called by the handler's Purge method while the handler is purging deletable files. Handlers should call
+ /// PurgeProgress periodically to keep the user informed of progress, especially if the purge will take a long time. Calling
+ /// this method frequently also allows the handler to shut down promptly if a user cancels a purge.
+ ///
+ // https://learn.microsoft.com/en-us/windows/win32/api/emptyvc/nf-emptyvc-iemptyvolumecachecallback-purgeprogress HRESULT
+ // PurgeProgress( [in] DWORDLONG dwlSpaceFreed, [in] DWORDLONG dwlSpaceToFree, [in] DWORD dwFlags, [in] LPCWSTR pcwszStatus );
+ HRESULT PurgeProgress(ulong dwlSpaceFreed, ulong dwlSpaceToFree, EVCCBF dwFlags, [Optional] string? pcwszStatus);
+ }
+
+ /// Class to get the default system volume cache instance using key in registry.
+ public static class SystemVolumeCache
+ {
+ /// Gets and instance of using the CLSID defined .
+ /// A string with the volume root—for example, "C:".
+ /// The registry key name that holds the information about the handler object.
+ /// A instance.
+ ///
+ public static IEmptyVolumeCache CreateInitializedInstance(string volume = @"C:\", string regSubKeyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Thumbnail Cache")
+ {
+ AdvApi32.RegOpenKeyEx(HKEY.HKEY_LOCAL_MACHINE, regSubKeyName, 0, AdvApi32.REGSAM.KEY_READ, out var hk).ThrowIfFailed();
+ using (hk)
+ {
+ Type? type = Type.GetTypeFromCLSID(Guid.Parse(AdvApi32.RegQueryValueEx(hk, null)!.ToString()!), true);
+ var ievc = (IEmptyVolumeCache?)Activator.CreateInstance(type!) ?? throw new InvalidOperationException();
+ ievc.Initialize(hk, volume, out _, out _, out _).ThrowIfFailed();
+ return ievc;
+ }
+ }
+ }
+}
\ No newline at end of file