Skip to content

Commit aca0c12

Browse files
Init
Co-Authored-By: Dongle <[email protected]>
1 parent dde3ee7 commit aca0c12

File tree

9 files changed

+458
-325
lines changed

9 files changed

+458
-325
lines changed

src/Files.App.CsWin32/NativeMethods.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,5 @@ FILE_FILE_COMPRESSION
172172
WM_WINDOWPOSCHANGING
173173
WINDOWPOS
174174
UnregisterClass
175+
E_POINTER
176+
E_NOINTERFACE

src/Files.App.Storage/Files.App.Storage.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
<Configurations>Debug;Release</Configurations>
1010
<Platforms>x86;x64;arm64</Platforms>
1111
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
12+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
1213
</PropertyGroup>
1314

1415
<ItemGroup>
1516
<PackageReference Include="FluentFTP" />
1617
</ItemGroup>
1718

1819
<ItemGroup>
20+
<ProjectReference Include="..\Files.App.CsWin32\Files.App.CsWin32.csproj" />
1921
<ProjectReference Include="..\Files.Core.Storage\Files.Core.Storage.csproj" />
2022
<ProjectReference Include="..\Files.Shared\Files.Shared.csproj" />
2123
</ItemGroup>
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Windows.Win32;
5+
using Windows.Win32.Foundation;
6+
using Windows.Win32.System.Com;
7+
using Windows.Win32.UI.Shell;
8+
9+
namespace Files.App.Storage.Storables
10+
{
11+
public sealed partial class WindowsBulkOperations : IDisposable
12+
{
13+
// Fields
14+
15+
private readonly ComPtr<IFileOperation> _pFileOperation;
16+
private readonly ComPtr<IFileOperationProgressSink> _pProgressSink;
17+
private readonly uint _progressSinkCookie;
18+
19+
private int _disposedValue = 0;
20+
private FILEOPERATION_FLAGS _operationFlags;
21+
private HWND _owner;
22+
23+
// Events
24+
25+
public event EventHandler<WindowsBulkOperationsEventArgs>? FinishOperations;
26+
public event EventHandler<WindowsBulkOperationsEventArgs>? PostCopyItem;
27+
public event EventHandler<WindowsBulkOperationsEventArgs>? PostDeleteItem;
28+
public event EventHandler<WindowsBulkOperationsEventArgs>? PostMoveItem;
29+
public event EventHandler<WindowsBulkOperationsEventArgs>? PostNewItem;
30+
public event EventHandler<WindowsBulkOperationsEventArgs>? PostRenameItem;
31+
public event EventHandler<WindowsBulkOperationsEventArgs>? PreCopyItem;
32+
public event EventHandler<WindowsBulkOperationsEventArgs>? PreDeleteItem;
33+
public event EventHandler<WindowsBulkOperationsEventArgs>? PreMoveItem;
34+
public event EventHandler<WindowsBulkOperationsEventArgs>? PreNewItem;
35+
public event EventHandler<WindowsBulkOperationsEventArgs>? PreRenameItem;
36+
public event EventHandler? StartOperations;
37+
public event ProgressChangedEventHandler? UpdateProgress;
38+
39+
// Constructor
40+
41+
public unsafe WindowsBulkOperations(HWND owner = default, FILEOPERATION_FLAGS flags = FILEOPERATION_FLAGS.FOF_ALLOWUNDO | FILEOPERATION_FLAGS.FOF_NOCONFIRMMKDIR)
42+
{
43+
var clsid = typeof(FileOperation).GUID;
44+
var iid = typeof(IFileOperation).GUID;
45+
46+
HRESULT hr = PInvoke.CoCreateInstance(
47+
&clsid,
48+
null,
49+
CLSCTX.CLSCTX_LOCAL_SERVER,
50+
&iid,
51+
(void**)_pFileOperation.GetAddressOf());
52+
53+
_owner = owner;
54+
if (owner != default)
55+
hr = _pFileOperation.Get()->SetOwnerWindow(owner);
56+
_operationFlags = flags;
57+
58+
_pProgressSink.Attach((IFileOperationProgressSink*)WindowsBulkOperationsSink.Create(this));
59+
hr = _pFileOperation.Get()->Advise(_pProgressSink.Get(), out var progressSinkCookie);
60+
_progressSinkCookie = progressSinkCookie;
61+
}
62+
63+
public unsafe HRESULT QueueCopyItem(ComPtr<IShellItem> psiItem, ComPtr<IShellItem> psiDestinationFolder, PCWSTR pszCopyName)
64+
{
65+
HRESULT hr = default;
66+
67+
hr = _pFileOperation.Get()->CopyItem(psiItem.Get(), psiDestinationFolder.Get(), pszCopyName, _pProgressSink.Get());
68+
return hr;
69+
}
70+
71+
public unsafe HRESULT QueueDeleteItem(ComPtr<IShellItem> psiItem)
72+
{
73+
HRESULT hr = default;
74+
75+
hr = _pFileOperation.Get()->DeleteItem(psiItem.Get(), _pProgressSink.Get());
76+
return hr;
77+
}
78+
79+
public unsafe HRESULT QueueMoveItem(ComPtr<IShellItem> psiItem, ComPtr<IShellItem> psiDestinationFolder, PCWSTR pszNewName)
80+
{
81+
HRESULT hr = default;
82+
83+
hr = _pFileOperation.Get()->MoveItem(psiItem.Get(), psiDestinationFolder.Get(), pszNewName, null);
84+
return hr;
85+
}
86+
87+
public unsafe HRESULT QueueNewItem(ComPtr<IShellItem> psiDestinationFolder, uint dwFileAttributes, PCWSTR pszName, PCWSTR pszTemplateName)
88+
{
89+
HRESULT hr = default;
90+
91+
hr = _pFileOperation.Get()->NewItem(psiDestinationFolder.Get(), dwFileAttributes, pszName, pszTemplateName, _pProgressSink.Get());
92+
return hr;
93+
}
94+
95+
public unsafe HRESULT QueueRenameItem(ComPtr<IShellItem> psiItem, PCWSTR pszNewName)
96+
{
97+
HRESULT hr = default;
98+
99+
hr = _pFileOperation.Get()->RenameItem(psiItem.Get(), pszNewName, _pProgressSink.Get());
100+
return hr;
101+
}
102+
103+
public unsafe HRESULT PerformOperations()
104+
{
105+
HRESULT hr = default;
106+
107+
hr = _pFileOperation.Get()->PerformOperations();
108+
return hr;
109+
}
110+
111+
public unsafe void Dispose()
112+
{
113+
_pFileOperation.Get()->Unadvise(_progressSinkCookie);
114+
_pFileOperation.Dispose();
115+
_pProgressSink.Dispose();
116+
}
117+
}
118+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using System.Runtime.CompilerServices;
5+
using Windows.Win32;
6+
using Windows.Win32.Foundation;
7+
using Windows.Win32.System.Com;
8+
using Windows.Win32.UI.Shell;
9+
10+
namespace Files.App.Storage.Storables
11+
{
12+
public class WindowsBulkOperationsEventArgs : EventArgs
13+
{
14+
}
15+
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Windows.Win32.Foundation;
5+
using Windows.Win32.UI.Shell;
6+
7+
namespace Files.App.Storage.Storables
8+
{
9+
public sealed partial class WindowsBulkOperations : IDisposable
10+
{
11+
private unsafe partial struct WindowsBulkOperationsSink : IFileOperationProgressSink.Interface
12+
{
13+
public HRESULT StartOperations()
14+
{
15+
return HRESULT.S_OK;
16+
}
17+
18+
public HRESULT FinishOperations(HRESULT hrResult)
19+
{
20+
return HRESULT.S_OK;
21+
}
22+
23+
public unsafe HRESULT PreRenameItem(uint dwFlags, IShellItem* psiItem, PCWSTR pszNewName)
24+
{
25+
if (_operationsHandle.Target is WindowsBulkOperations operations)
26+
{
27+
operations.PreRenameItem?.Invoke(operations, new());
28+
return HRESULT.S_OK;
29+
}
30+
31+
return HRESULT.E_INVALIDARG;
32+
}
33+
34+
public unsafe HRESULT PostRenameItem(uint dwFlags, IShellItem* psiItem, PCWSTR pszNewName, HRESULT hrRename, IShellItem* psiNewlyCreated)
35+
{
36+
if (_operationsHandle.Target is WindowsBulkOperations operations)
37+
{
38+
operations.PostRenameItem?.Invoke(operations, new());
39+
return HRESULT.S_OK;
40+
}
41+
42+
return HRESULT.E_INVALIDARG;
43+
}
44+
45+
public unsafe HRESULT PreMoveItem(uint dwFlags, IShellItem* psiItem, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
46+
{
47+
if (_operationsHandle.Target is WindowsBulkOperations operations)
48+
{
49+
operations.PreMoveItem?.Invoke(operations, new());
50+
return HRESULT.S_OK;
51+
}
52+
53+
return HRESULT.E_INVALIDARG;
54+
}
55+
56+
public unsafe HRESULT PostMoveItem(uint dwFlags, IShellItem* psiItem, IShellItem* psiDestinationFolder, PCWSTR pszNewName, HRESULT hrMove, IShellItem* psiNewlyCreated)
57+
{
58+
if (_operationsHandle.Target is WindowsBulkOperations operations)
59+
{
60+
operations.PostMoveItem?.Invoke(operations, new());
61+
return HRESULT.S_OK;
62+
}
63+
64+
return HRESULT.E_INVALIDARG;
65+
}
66+
67+
public unsafe HRESULT PreCopyItem(uint dwFlags, IShellItem* psiItem, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
68+
{
69+
if (_operationsHandle.Target is WindowsBulkOperations operations)
70+
{
71+
operations.PreCopyItem?.Invoke(operations, new());
72+
return HRESULT.S_OK;
73+
}
74+
75+
return HRESULT.E_INVALIDARG;
76+
}
77+
78+
public unsafe HRESULT PostCopyItem(uint dwFlags, IShellItem* psiItem, IShellItem* psiDestinationFolder, PCWSTR pszNewName, HRESULT hrCopy, IShellItem* psiNewlyCreated)
79+
{
80+
if (_operationsHandle.Target is WindowsBulkOperations operations)
81+
{
82+
operations.PostCopyItem?.Invoke(operations, new());
83+
return HRESULT.S_OK;
84+
}
85+
86+
return HRESULT.E_INVALIDARG;
87+
}
88+
89+
public unsafe HRESULT PreDeleteItem(uint dwFlags, IShellItem* psiItem)
90+
{
91+
if (_operationsHandle.Target is WindowsBulkOperations operations)
92+
{
93+
operations.PreDeleteItem?.Invoke(operations, new());
94+
return HRESULT.S_OK;
95+
}
96+
97+
return HRESULT.E_INVALIDARG;
98+
}
99+
100+
public unsafe HRESULT PostDeleteItem(uint dwFlags, IShellItem* psiItem, HRESULT hrDelete, IShellItem* psiNewlyCreated)
101+
{
102+
if (_operationsHandle.Target is WindowsBulkOperations operations)
103+
{
104+
operations.PostDeleteItem?.Invoke(operations, new());
105+
return HRESULT.S_OK;
106+
}
107+
108+
return HRESULT.E_INVALIDARG;
109+
}
110+
111+
public unsafe HRESULT PreNewItem(uint dwFlags, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
112+
{
113+
if (_operationsHandle.Target is WindowsBulkOperations operations)
114+
{
115+
operations.PreNewItem?.Invoke(operations, new());
116+
return HRESULT.S_OK;
117+
}
118+
119+
return HRESULT.E_INVALIDARG;
120+
}
121+
122+
public unsafe HRESULT PostNewItem(uint dwFlags, IShellItem* psiDestinationFolder, PCWSTR pszNewName, PCWSTR pszTemplateName, uint dwFileAttributes, HRESULT hrNew, IShellItem* psiNewItem)
123+
{
124+
if (_operationsHandle.Target is WindowsBulkOperations operations)
125+
{
126+
operations.PostNewItem?.Invoke(operations, new());
127+
return HRESULT.S_OK;
128+
}
129+
130+
return HRESULT.E_INVALIDARG;
131+
}
132+
133+
public HRESULT UpdateProgress(uint iWorkTotal, uint iWorkSoFar)
134+
{
135+
return HRESULT.S_OK;
136+
}
137+
138+
public HRESULT ResetTimer()
139+
{
140+
return HRESULT.S_OK;
141+
}
142+
143+
public HRESULT PauseTimer()
144+
{
145+
return HRESULT.S_OK;
146+
}
147+
148+
public HRESULT ResumeTimer()
149+
{
150+
return HRESULT.S_OK;
151+
}
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)