-
Notifications
You must be signed in to change notification settings - Fork 0
/
VolumeWatcher.cs
136 lines (120 loc) · 4.65 KB
/
VolumeWatcher.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.IO;
using System.Collections.Generic;
using MonoMac;
using MonoMac.Foundation;
using MonoMac.AppKit;
using MonoMac.ObjCRuntime;
namespace VimFastFind
{
public enum VolumeWatcherEvent
{
DidMount,
WillUnmount,
DidUnmount
}
// volume will resemble "C:" on windows and "/" or "/Volumes/xxx" on mac
public delegate void VolumeWatcherEventDelegate(VolumeWatcher sender, VolumeWatcherEvent evt, string volume);
// on mac, VolumeWatcher uses NSWorkspace notifications: to get notifications,
// your application's main thread must be in a CoreFoundation run loop.
//
public class VolumeWatcher : IDisposable
{
#pragma warning disable 0414
VolumeWatcherHelper _helper;
#pragma warning restore 0414
public event VolumeWatcherEventDelegate VolumeChanged;
public VolumeWatcher()
{
_helper = new VolumeWatcherHelper(this);
}
// returns the list of connected volumes.
public static IList<string> ScanVolumes()
{
var list = new List<string>();
using (NSAutoreleasePool pool = new NSAutoreleasePool())
{
foreach (string path in NSWorkspace.SharedWorkspace.MountedLocalVolumePaths)
list.Add(path);
}
return list;
}
void ev_VolumeChanged(VolumeWatcherEvent evt, string volume)
{
Trace("ev_VolumeChanged " + evt + ": " + volume);
if (VolumeChanged != null)
VolumeChanged(this, evt, volume);
}
void Trace(string s)
{
// Console.WriteLine(s);
}
public void Dispose()
{
_helper.Dispose();
}
[Register]
public class VolumeWatcherHelper : NSObject
{
VolumeWatcher outer;
object _disposelock = new object();
bool _disposed;
public VolumeWatcherHelper(VolumeWatcher vw)
{
outer = vw;
OSXUtils.ApplicationHelper.ExecuteWhenLaunched(delegate
{
using (NSAutoreleasePool pool = new NSAutoreleasePool ())
{
NSNotificationCenter nc = NSWorkspace.SharedWorkspace.NotificationCenter;
nc.AddObserver(this, new Selector("ev_VolumeDidMount:"), new NSString("NSWorkspaceDidMountNotification"), null);
nc.AddObserver(this, new Selector("ev_VolumeDidUnmount:"), new NSString("NSWorkspaceDidUnmountNotification"), null);
nc.AddObserver(this, new Selector("ev_VolumeWillUnmount:"), new NSString("NSWorkspaceWillUnmountNotification"), null);
}
});
}
protected override void Dispose(bool disposing)
{
if (_disposed) return;
lock (_disposelock)
{
if (_disposed) return;
OSXUtils.ApplicationHelper.ExecuteWhenLaunched(delegate
{
using (NSAutoreleasePool pool = new NSAutoreleasePool ())
NSWorkspace.SharedWorkspace.NotificationCenter.RemoveObserver (this);
});
_disposed = true;
}
base.Dispose(disposing);
}
[Export("ev_VolumeDidMount:")]
public void ev_VolumeDidMount(NSNotification n)
{
using (NSAutoreleasePool pool = new NSAutoreleasePool())
{
string mntpt = (NSString)n.UserInfo.ObjectForKey(new NSString("NSDevicePath"));
outer.ev_VolumeChanged(VolumeWatcherEvent.DidMount, mntpt);
}
}
[Export("ev_VolumeWillUnmount:")]
public void ev_VolumeWillUnmount(NSNotification n)
{
using (NSAutoreleasePool pool = new NSAutoreleasePool())
{
string mntpt = (NSString)n.UserInfo.ObjectForKey(new NSString("NSDevicePath"));
outer.ev_VolumeChanged(VolumeWatcherEvent.WillUnmount, mntpt);
}
}
[Export("ev_VolumeDidUnmount:")]
public void ev_VolumeDidUnmount(NSNotification n)
{
using (NSAutoreleasePool pool = new NSAutoreleasePool())
{
string mntpt = (NSString)n.UserInfo.ObjectForKey(new NSString("NSDevicePath"));
outer.ev_VolumeChanged(VolumeWatcherEvent.DidUnmount, mntpt);
}
}
}
}
}