Skip to content

Commit 05a34b4

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

File tree

9 files changed

+470
-325
lines changed

9 files changed

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

0 commit comments

Comments
 (0)