@@ -12,12 +12,12 @@ namespace Files.App.Storage
1212 /// <summary>
1313 /// Handles bulk file operations in Windows, such as copy, move, delete, create, and rename, supporting progress tracking and event notifications.
1414 /// </summary>
15- public sealed partial class WindowsBulkOperations : IDisposable
15+ public unsafe partial class WindowsBulkOperations : IDisposable
1616 {
1717 // Fields
1818
19- private readonly ComPtr < IFileOperation > _pFileOperation ;
20- private readonly ComPtr < IFileOperationProgressSink > _pProgressSink ;
19+ private readonly IFileOperation * _pFileOperation ;
20+ private readonly IFileOperationProgressSink * _pProgressSink ;
2121 private readonly uint _progressSinkCookie ;
2222
2323 // Events
@@ -70,24 +70,20 @@ public sealed partial class WindowsBulkOperations : IDisposable
7070 /// <param name="flags">Defines the behavior of the file operation, such as allowing undo and suppressing directory confirmation.</param>
7171 public unsafe WindowsBulkOperations ( HWND ownerHWnd = default , FILEOPERATION_FLAGS flags = FILEOPERATION_FLAGS . FOF_ALLOWUNDO | FILEOPERATION_FLAGS . FOF_NOCONFIRMMKDIR )
7272 {
73- var clsid = typeof ( FileOperation ) . GUID ;
74- var iid = typeof ( IFileOperation ) . GUID ;
73+ IFileOperation * pFileOperation = null ;
7574
76- HRESULT hr = PInvoke . CoCreateInstance (
77- & clsid ,
78- null ,
79- CLSCTX . CLSCTX_LOCAL_SERVER ,
80- & iid ,
81- ( void * * ) _pFileOperation . GetAddressOf ( ) )
82- . ThrowIfFailedOnDebug ( ) ;
75+ HRESULT hr = PInvoke . CoCreateInstance ( CLSID . CLSID_FileOperation , null , CLSCTX . CLSCTX_LOCAL_SERVER , IID . IID_IFileOperation , ( void * * ) & pFileOperation ) ;
76+ hr . ThrowIfFailedOnDebug ( ) ;
77+
78+ _pFileOperation = pFileOperation ;
8379
8480 if ( ownerHWnd != default )
85- hr = _pFileOperation . Get ( ) ->SetOwnerWindow ( ownerHWnd ) . ThrowIfFailedOnDebug ( ) ;
81+ hr = _pFileOperation ->SetOwnerWindow ( ownerHWnd ) . ThrowIfFailedOnDebug ( ) ;
8682
87- hr = _pFileOperation . Get ( ) ->SetOperationFlags ( flags ) . ThrowIfFailedOnDebug ( ) ;
83+ hr = _pFileOperation ->SetOperationFlags ( flags ) . ThrowIfFailedOnDebug ( ) ;
8884
89- _pProgressSink . Attach ( ( IFileOperationProgressSink * ) WindowsBulkOperationsSink . Create ( this ) ) ;
90- hr = _pFileOperation . Get ( ) ->Advise ( _pProgressSink . Get ( ) , out var progressSinkCookie ) . ThrowIfFailedOnDebug ( ) ;
85+ _pProgressSink = ( IFileOperationProgressSink * ) WindowsBulkOperationsSink . Create ( this ) ;
86+ hr = _pFileOperation ->Advise ( _pProgressSink , out var progressSinkCookie ) . ThrowIfFailedOnDebug ( ) ;
9187 _progressSinkCookie = progressSinkCookie ;
9288 }
9389
@@ -101,7 +97,7 @@ public unsafe WindowsBulkOperations(HWND ownerHWnd = default, FILEOPERATION_FLAG
10197 public unsafe HRESULT QueueCopyOperation ( WindowsStorable targetItem , WindowsFolder destinationFolder , string ? copyName )
10298 {
10399 fixed ( char * pszCopyName = copyName )
104- return _pFileOperation . Get ( ) ->CopyItem ( targetItem . ThisPtr . Get ( ) , destinationFolder . ThisPtr . Get ( ) , pszCopyName , _pProgressSink . Get ( ) ) ;
100+ return _pFileOperation ->CopyItem ( targetItem . ThisPtr , destinationFolder . ThisPtr , pszCopyName , _pProgressSink ) ;
105101 }
106102
107103 /// <summary>
@@ -111,7 +107,7 @@ public unsafe HRESULT QueueCopyOperation(WindowsStorable targetItem, WindowsFold
111107 /// <returns>If this method succeeds, it returns <see cref="HRESULT.S_OK"/>. Otherwise, it returns an <see cref="HRESULT"/> error code.</returns>
112108 public unsafe HRESULT QueueDeleteOperation ( WindowsStorable targetItem )
113109 {
114- return _pFileOperation . Get ( ) ->DeleteItem ( targetItem . ThisPtr . Get ( ) , _pProgressSink . Get ( ) ) ;
110+ return _pFileOperation ->DeleteItem ( targetItem . ThisPtr , _pProgressSink ) ;
115111 }
116112
117113 /// <summary>
@@ -124,7 +120,7 @@ public unsafe HRESULT QueueDeleteOperation(WindowsStorable targetItem)
124120 public unsafe HRESULT QueueMoveOperation ( WindowsStorable targetItem , WindowsFolder destinationFolder , string ? newName )
125121 {
126122 fixed ( char * pszNewName = newName )
127- return _pFileOperation . Get ( ) ->MoveItem ( targetItem . ThisPtr . Get ( ) , destinationFolder . ThisPtr . Get ( ) , pszNewName , null ) ;
123+ return _pFileOperation ->MoveItem ( targetItem . ThisPtr , destinationFolder . ThisPtr , pszNewName , null ) ;
128124 }
129125
130126 /// <summary>
@@ -138,7 +134,7 @@ public unsafe HRESULT QueueMoveOperation(WindowsStorable targetItem, WindowsFold
138134 public unsafe HRESULT QueueCreateOperation ( WindowsFolder destinationFolder , FILE_FLAGS_AND_ATTRIBUTES fileAttributes , string name , string ? templateName )
139135 {
140136 fixed ( char * pszName = name , pszTemplateName = templateName )
141- return _pFileOperation . Get ( ) ->NewItem ( destinationFolder . ThisPtr . Get ( ) , ( uint ) fileAttributes , pszName , pszTemplateName , _pProgressSink . Get ( ) ) ;
137+ return _pFileOperation ->NewItem ( destinationFolder . ThisPtr , ( uint ) fileAttributes , pszName , pszTemplateName , _pProgressSink ) ;
142138 }
143139
144140 /// <summary>
@@ -150,7 +146,7 @@ public unsafe HRESULT QueueCreateOperation(WindowsFolder destinationFolder, FILE
150146 public unsafe HRESULT QueueRenameOperation ( WindowsStorable targetItem , string newName )
151147 {
152148 fixed ( char * pszNewName = newName )
153- return _pFileOperation . Get ( ) ->RenameItem ( targetItem . ThisPtr . Get ( ) , pszNewName , _pProgressSink . Get ( ) ) ;
149+ return _pFileOperation ->RenameItem ( targetItem . ThisPtr , pszNewName , _pProgressSink ) ;
154150 }
155151
156152 /// <summary>
@@ -159,19 +155,19 @@ public unsafe HRESULT QueueRenameOperation(WindowsStorable targetItem, string ne
159155 /// <returns>If this method succeeds, it returns <see cref="HRESULT.S_OK"/>. Otherwise, it returns an <see cref="HRESULT"/> error code.</returns>
160156 public unsafe HRESULT PerformAllOperations ( )
161157 {
162- return _pFileOperation . Get ( ) ->PerformOperations ( ) ;
158+ return _pFileOperation ->PerformOperations ( ) ;
163159 }
164160
165161 // Disposer
166162
167163 /// <inheritdoc/>
168164 public unsafe void Dispose ( )
169165 {
170- if ( ! _pProgressSink . IsNull )
171- _pFileOperation . Get ( ) ->Unadvise ( _progressSinkCookie ) ;
166+ if ( _pProgressSink is not null )
167+ _pFileOperation ->Unadvise ( _progressSinkCookie ) ;
172168
173- _pFileOperation . Dispose ( ) ;
174- _pProgressSink . Dispose ( ) ;
169+ _pFileOperation -> Release ( ) ;
170+ _pProgressSink -> Release ( ) ;
175171 }
176172 }
177173}
0 commit comments