-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFileOperation.cs
114 lines (99 loc) · 4.17 KB
/
FileOperation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Stephen Toub
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Windows.Forms;
using BackgroundJobsLib.Interop;
namespace BackgroundJobsLib
{
public class FileOperation : IDisposable
{
private bool _disposed;
private IFileOperation _fileOperation;
private FileOperationProgressSink _callbackSink;
private uint _sinkCookie;
public FileOperation() : this(null) { }
public FileOperation(FileOperationProgressSink callbackSink) : this(callbackSink, null) { }
public FileOperation(FileOperationProgressSink callbackSink, IWin32Window owner)
{
_callbackSink = callbackSink;
_fileOperation = (IFileOperation)Activator.CreateInstance(_fileOperationType);
_fileOperation.SetOperationFlags(FileOperationFlags.FOF_NOCONFIRMMKDIR);
if (_callbackSink != null) _sinkCookie = _fileOperation.Advise(_callbackSink);
if (owner != null) _fileOperation.SetOwnerWindow((uint)owner.Handle);
}
public void CopyItem(string source, string destination, string newName)
{
ThrowIfDisposed();
using (ComReleaser<IShellItem> sourceItem = CreateShellItem(source))
using (ComReleaser<IShellItem> destinationItem = CreateShellItem(destination))
{
_fileOperation.CopyItem(sourceItem.Item, destinationItem.Item, newName, null);
}
}
public void MoveItem(string source, string destination, string newName)
{
ThrowIfDisposed();
using (ComReleaser<IShellItem> sourceItem = CreateShellItem(source))
using (ComReleaser<IShellItem> destinationItem = CreateShellItem(destination))
{
_fileOperation.MoveItem(sourceItem.Item, destinationItem.Item, newName, null);
}
}
public void RenameItem(string source, string newName)
{
ThrowIfDisposed();
using (ComReleaser<IShellItem> sourceItem = CreateShellItem(source))
{
_fileOperation.RenameItem(sourceItem.Item, newName, null);
}
}
public void DeleteItem(string source)
{
ThrowIfDisposed();
using (ComReleaser<IShellItem> sourceItem = CreateShellItem(source))
{
_fileOperation.DeleteItem(sourceItem.Item, null);
}
}
public void NewItem(string folderName, string name, FileAttributes attrs)
{
ThrowIfDisposed();
using (ComReleaser<IShellItem> folderItem = CreateShellItem(folderName))
{
_fileOperation.NewItem(folderItem.Item, attrs, name, string.Empty, _callbackSink);
}
}
public void PerformOperations()
{
ThrowIfDisposed();
_fileOperation.PerformOperations();
}
private void ThrowIfDisposed()
{
if (_disposed) throw new ObjectDisposedException(GetType().Name);
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
if (_callbackSink != null) _fileOperation.Unadvise(_sinkCookie);
Marshal.FinalReleaseComObject(_fileOperation);
}
}
private static ComReleaser<IShellItem> CreateShellItem(string path)
{
return new ComReleaser<IShellItem>(
(IShellItem)SHCreateItemFromParsingName(path, null, ref _shellItemGuid));
}
[DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode, PreserveSig=false)]
[return: MarshalAs(UnmanagedType.Interface)]
private static extern object SHCreateItemFromParsingName(
[MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, ref Guid riid);
private static readonly Guid CLSID_FileOperation = new Guid("3ad05575-8857-4850-9277-11b85bdb8e09");
private static readonly Type _fileOperationType = Type.GetTypeFromCLSID(CLSID_FileOperation);
private static Guid _shellItemGuid = typeof(IShellItem).GUID;
}
}