From a607495db4b4732b48469c38459a0bea7607f491 Mon Sep 17 00:00:00 2001 From: David Hall Date: Sun, 9 Jun 2024 13:07:21 -0600 Subject: [PATCH] Added IEmptyVolumeCache and supporting code --- PInvoke/Shell32/EmptyVC.cs | 944 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 944 insertions(+) create mode 100644 PInvoke/Shell32/EmptyVC.cs 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