Skip to content

Commit d9f6ee4

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

13 files changed

+693
-366
lines changed

Diff for: src/Files.App.CsWin32/NativeMethods.txt

+4
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,7 @@ FILE_FILE_COMPRESSION
172172
WM_WINDOWPOSCHANGING
173173
WINDOWPOS
174174
UnregisterClass
175+
E_POINTER
176+
E_NOINTERFACE
177+
E_FAIL
178+
IShellFolder

Diff for: src/Files.App.Storage/Files.App.Storage.csproj

+2
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>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using System.Runtime.InteropServices;
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 sealed partial class WindowsBulkOperations : IDisposable
13+
{
14+
// Fields
15+
16+
private readonly ComPtr<IFileOperation> _pFileOperation;
17+
private readonly ComPtr<IFileOperationProgressSink> _pProgressSink;
18+
private readonly uint _progressSinkCookie;
19+
20+
private int _disposedValue = 0;
21+
22+
// Events
23+
24+
public event EventHandler<WindowsBulkOperationsEventArgs>? OperationsFinished;
25+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemCopied;
26+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemDeleted;
27+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemMoved;
28+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemCreated;
29+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemRenamed;
30+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemCopying;
31+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemDeleting;
32+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemMoving;
33+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemCreating;
34+
public event EventHandler<WindowsBulkOperationsEventArgs>? ItemRenaming;
35+
public event EventHandler? OperationsStarted;
36+
public event ProgressChangedEventHandler? ProgressUpdated;
37+
38+
// Constructor
39+
40+
public unsafe WindowsBulkOperations(HWND owner = default, FILEOPERATION_FLAGS flags = FILEOPERATION_FLAGS.FOF_ALLOWUNDO | FILEOPERATION_FLAGS.FOF_NOCONFIRMMKDIR)
41+
{
42+
var clsid = typeof(FileOperation).GUID;
43+
var iid = typeof(IFileOperation).GUID;
44+
45+
HRESULT hr = PInvoke.CoCreateInstance(
46+
&clsid,
47+
null,
48+
CLSCTX.CLSCTX_LOCAL_SERVER,
49+
&iid,
50+
(void**)_pFileOperation.GetAddressOf());
51+
52+
if (owner != default)
53+
hr = _pFileOperation.Get()->SetOwnerWindow(owner);
54+
55+
hr = _pFileOperation.Get()->SetOperationFlags(flags);
56+
57+
_pProgressSink.Attach((IFileOperationProgressSink*)WindowsBulkOperationsSink.Create(this));
58+
hr = _pFileOperation.Get()->Advise(_pProgressSink.Get(), out var progressSinkCookie);
59+
_progressSinkCookie = progressSinkCookie;
60+
}
61+
62+
public unsafe HRESULT QueueCopyOperation(ComPtr<IShellItem> psiItem, ComPtr<IShellItem> psiDestinationFolder, PCWSTR pszCopyName)
63+
{
64+
HRESULT hr = default;
65+
66+
hr = _pFileOperation.Get()->CopyItem(psiItem.Get(), psiDestinationFolder.Get(), pszCopyName, _pProgressSink.Get());
67+
return hr;
68+
}
69+
70+
public unsafe HRESULT QueueDeleteOperation(ComPtr<IShellItem> psiItem)
71+
{
72+
HRESULT hr = default;
73+
74+
hr = _pFileOperation.Get()->DeleteItem(psiItem.Get(), _pProgressSink.Get());
75+
return hr;
76+
}
77+
78+
public unsafe HRESULT QueueMoveOperation(WindowsStorable targetItem, WindowsFolder destinationFolder, string? newName)
79+
{
80+
HRESULT hr = default;
81+
82+
fixed (char* pszNewName = newName)
83+
hr = _pFileOperation.Get()->MoveItem(targetItem.ThisPtr.Get(), destinationFolder.ThisPtr.Get(), pszNewName, null);
84+
85+
return hr;
86+
}
87+
88+
public unsafe HRESULT QueueCreateOperation(ComPtr<IShellItem> psiDestinationFolder, uint dwFileAttributes, PCWSTR pszName, PCWSTR pszTemplateName)
89+
{
90+
HRESULT hr = default;
91+
92+
hr = _pFileOperation.Get()->NewItem(psiDestinationFolder.Get(), dwFileAttributes, pszName, pszTemplateName, _pProgressSink.Get());
93+
return hr;
94+
}
95+
96+
public unsafe HRESULT QueueRenameOperation(ComPtr<IShellItem> psiItem, PCWSTR pszNewName)
97+
{
98+
HRESULT hr = default;
99+
100+
hr = _pFileOperation.Get()->RenameItem(psiItem.Get(), pszNewName, _pProgressSink.Get());
101+
return hr;
102+
}
103+
104+
public unsafe HRESULT PerformAllOperations()
105+
{
106+
HRESULT hr = default;
107+
108+
hr = _pFileOperation.Get()->PerformOperations();
109+
return hr;
110+
}
111+
112+
public unsafe void Dispose()
113+
{
114+
_pFileOperation.Get()->Unadvise(_progressSinkCookie);
115+
_pFileOperation.Dispose();
116+
_pProgressSink.Dispose();
117+
}
118+
}
119+
}
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+
}
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.ItemRenaming?.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.ItemRenamed?.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.ItemMoving?.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.ItemMoved?.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.ItemCopying?.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.ItemCopied?.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.ItemDeleting?.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.ItemDeleted?.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.ItemCreating?.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.ItemCreated?.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)