/
githubmirror
/
Files
Обзор
Документация
Войти
/
githubmirror
/
Files
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Files.App.Storage/Windows/WindowsBulkOperations.cs
167 строк
7 KB
0x5bfa
Code Quality: Replace raw ABI pointers with ComObject instances for safer disposal (#18684)
16 июл 2026, 18:32
Не верифицирован
16 июл 2026, 18:32
93dfb04
Код
Авторство
О чём код?
// Copyright (c) Files Community // SPDX-License-Identifier: MPL-2.0 using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.Storage.FileSystem; using Windows.Win32.System.Com; using Windows.Win32.UI.Shell; namespace Files.App.Storage { /// <summary> /// Handles bulk file operations in Windows, such as copy, move, delete, create, and rename, supporting progress tracking and event notifications. /// </summary> public unsafe partial class WindowsBulkOperations : IDisposable { // Fields private readonly IFileOperation _fileOperation; private readonly IFileOperationProgressSink _progressSink; private readonly uint _progressSinkCookie; // Events /// <summary>An event that is triggered when bulk operations are completed.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? OperationsFinished; /// <summary>An event that is triggered when an item is copied during bulk operations.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemCopied; /// <summary>An event that is triggered when an item is deleted during bulk operations.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemDeleted; /// <summary>An event that is triggered when an item is moved during bulk operations.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemMoved; /// <summary>An event that is triggered when a new item is created.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemCreated; /// <summary>An event that is triggered when an item is renamed.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemRenamed; /// <summary>An event that occurs when an item is being copied during bulk operations.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemCopying; /// <summary>An event that is triggered when an item is being deleted.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemDeleting; /// <summary>An event that is triggered when an item is being moved in bulk operations.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemMoving; /// <summary>An event that is triggered when an item is being created in bulk operations.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemCreating; /// <summary>An event that is triggered when an item is being renamed.</summary> public event EventHandler<WindowsBulkOperationsEventArgs>? ItemRenaming; /// <summary>An event that is triggered when operations start.</summary> public event EventHandler? OperationsStarted; /// <summary>An event that is triggered to indicate progress updates.</summary> public event ProgressChangedEventHandler? ProgressUpdated; // Constructor /// <summary> /// Initializes a <see cref="WindowsBulkOperations"/> instance for file operations on Windows. /// </summary> /// <param name="owner">Specifies the window handle that will own the file operation dialogs.</param> /// <param name="flags">Defines the behavior of the file operation, such as allowing undo and suppressing directory confirmation.</param> public WindowsBulkOperations(HWND ownerHWnd = default, FILEOPERATION_FLAGS flags = FILEOPERATION_FLAGS.FOF_ALLOWUNDO | FILEOPERATION_FLAGS.FOF_NOCONFIRMMKDIR) { HRESULT hr = PInvoke.CoCreateInstance(typeof(FileOperation).GUID, null, CLSCTX.CLSCTX_LOCAL_SERVER, out IFileOperation? fileOperation); hr.ThrowIfFailedOnDebug(); _fileOperation = fileOperation!; if (ownerHWnd != default) hr = _fileOperation.SetOwnerWindow(ownerHWnd).ThrowIfFailedOnDebug(); hr = _fileOperation.SetOperationFlags(flags).ThrowIfFailedOnDebug(); _progressSink = new WindowsBulkOperationsSink(this); hr = _fileOperation.Advise(_progressSink, out var progressSinkCookie).ThrowIfFailedOnDebug(); _progressSinkCookie = progressSinkCookie; } /// <summary> /// Queues a copy operation. /// </summary> /// <param name="targetItem"></param> /// <param name="destinationFolder"></param> /// <param name="copyName"></param> /// <returns>If this method succeeds, it returns <see cref="HRESULT.S_OK"/>. Otherwise, it returns an <see cref="HRESULT"/> error code.</returns> public unsafe HRESULT QueueCopyOperation(WindowsStorable targetItem, WindowsFolder destinationFolder, string? copyName) { fixed (char* pszCopyName = copyName) return _fileOperation.CopyItem(targetItem.ThisPtr, destinationFolder.ThisPtr, pszCopyName, _progressSink); } /// <summary> /// Queues a delete operation. /// </summary> /// <param name="targetItem"></param> /// <returns>If this method succeeds, it returns <see cref="HRESULT.S_OK"/>. Otherwise, it returns an <see cref="HRESULT"/> error code.</returns> public unsafe HRESULT QueueDeleteOperation(WindowsStorable targetItem) { return _fileOperation.DeleteItem(targetItem.ThisPtr, _progressSink); } /// <summary> /// Queues a move operation. /// </summary> /// <param name="targetItem"></param> /// <param name="destinationFolder"></param> /// <param name="newName"></param> /// <returns>If this method succeeds, it returns <see cref="HRESULT.S_OK"/>. Otherwise, it returns an <see cref="HRESULT"/> error code.</returns> public unsafe HRESULT QueueMoveOperation(WindowsStorable targetItem, WindowsFolder destinationFolder, string? newName) { fixed (char* pszNewName = newName) return _fileOperation.MoveItem(targetItem.ThisPtr, destinationFolder.ThisPtr, pszNewName, null!); } /// <summary> /// Queues a create operation. /// </summary> /// <param name="destinationFolder"></param> /// <param name="fileAttributes"></param> /// <param name="name"></param> /// <param name="templateName"></param> /// <returns>If this method succeeds, it returns <see cref="HRESULT.S_OK"/>. Otherwise, it returns an <see cref="HRESULT"/> error code.</returns> public unsafe HRESULT QueueCreateOperation(WindowsFolder destinationFolder, FILE_FLAGS_AND_ATTRIBUTES fileAttributes, string name, string? templateName) { fixed (char* pszName = name, pszTemplateName = templateName) return _fileOperation.NewItem(destinationFolder.ThisPtr, (uint)fileAttributes, pszName, pszTemplateName, _progressSink); } /// <summary> /// Queues a rename operation. /// </summary> /// <param name="targetItem"></param> /// <param name="newName"></param> /// <returns>If this method succeeds, it returns <see cref="HRESULT.S_OK"/>. Otherwise, it returns an <see cref="HRESULT"/> error code.</returns> public unsafe HRESULT QueueRenameOperation(WindowsStorable targetItem, string newName) { fixed (char* pszNewName = newName) return _fileOperation.RenameItem(targetItem.ThisPtr, pszNewName, _progressSink); } /// <summary> /// Performs the all queued operations. /// </summary> /// <returns>If this method succeeds, it returns <see cref="HRESULT.S_OK"/>. Otherwise, it returns an <see cref="HRESULT"/> error code.</returns> public unsafe HRESULT PerformAllOperations() { return _fileOperation.PerformOperations(); } // Disposer /// <inheritdoc/> public unsafe void Dispose() { _fileOperation.Unadvise(_progressSinkCookie); } } }