2
2
using System . Collections . Generic ;
3
3
using System . Runtime . InteropServices ;
4
4
using System . Text ;
5
+ using System . Threading ;
6
+ using Wox . Infrastructure . Logger ;
5
7
using Wox . Plugin . Everything . Everything . Exceptions ;
6
8
7
9
namespace Wox . Plugin . Everything . Everything
8
10
{
9
- public sealed class EverythingAPI
11
+ public interface IEverythingApi
10
12
{
11
- #region DllImport
12
- [ DllImport ( Main . DLL , CharSet = CharSet . Unicode ) ]
13
- private static extern int Everything_SetSearchW ( string lpSearchString ) ;
14
- [ DllImport ( Main . DLL ) ]
15
- private static extern void Everything_SetMatchPath ( bool bEnable ) ;
16
- [ DllImport ( Main . DLL ) ]
17
- private static extern void Everything_SetMatchCase ( bool bEnable ) ;
18
- [ DllImport ( Main . DLL ) ]
19
- private static extern void Everything_SetMatchWholeWord ( bool bEnable ) ;
20
- [ DllImport ( Main . DLL ) ]
21
- private static extern void Everything_SetRegex ( bool bEnable ) ;
22
- [ DllImport ( Main . DLL ) ]
23
- private static extern void Everything_SetMax ( int dwMax ) ;
24
- [ DllImport ( Main . DLL ) ]
25
- private static extern void Everything_SetOffset ( int dwOffset ) ;
26
-
27
- [ DllImport ( Main . DLL ) ]
28
- private static extern bool Everything_GetMatchPath ( ) ;
29
- [ DllImport ( Main . DLL ) ]
30
- private static extern bool Everything_GetMatchCase ( ) ;
31
- [ DllImport ( Main . DLL ) ]
32
- private static extern bool Everything_GetMatchWholeWord ( ) ;
33
- [ DllImport ( Main . DLL ) ]
34
- private static extern bool Everything_GetRegex ( ) ;
35
- [ DllImport ( Main . DLL ) ]
36
- private static extern UInt32 Everything_GetMax ( ) ;
37
- [ DllImport ( Main . DLL ) ]
38
- private static extern UInt32 Everything_GetOffset ( ) ;
39
- [ DllImport ( Main . DLL , CharSet = CharSet . Unicode ) ]
40
- private static extern string Everything_GetSearchW ( ) ;
41
- [ DllImport ( Main . DLL ) ]
42
- private static extern StateCode Everything_GetLastError ( ) ;
43
-
44
- [ DllImport ( Main . DLL , CharSet = CharSet . Unicode ) ]
45
- private static extern bool Everything_QueryW ( bool bWait ) ;
46
-
47
- [ DllImport ( Main . DLL ) ]
48
- private static extern void Everything_SortResultsByPath ( ) ;
49
-
50
- [ DllImport ( Main . DLL ) ]
51
- private static extern int Everything_GetNumFileResults ( ) ;
52
- [ DllImport ( Main . DLL ) ]
53
- private static extern int Everything_GetNumFolderResults ( ) ;
54
- [ DllImport ( Main . DLL ) ]
55
- private static extern int Everything_GetNumResults ( ) ;
56
- [ DllImport ( Main . DLL ) ]
57
- private static extern int Everything_GetTotFileResults ( ) ;
58
- [ DllImport ( Main . DLL ) ]
59
- private static extern int Everything_GetTotFolderResults ( ) ;
60
- [ DllImport ( Main . DLL ) ]
61
- private static extern int Everything_GetTotResults ( ) ;
62
- [ DllImport ( Main . DLL ) ]
63
- private static extern bool Everything_IsVolumeResult ( int nIndex ) ;
64
- [ DllImport ( Main . DLL ) ]
65
- private static extern bool Everything_IsFolderResult ( int nIndex ) ;
66
- [ DllImport ( Main . DLL ) ]
67
- private static extern bool Everything_IsFileResult ( int nIndex ) ;
68
- [ DllImport ( Main . DLL , CharSet = CharSet . Unicode ) ]
69
- private static extern void Everything_GetResultFullPathNameW ( int nIndex , StringBuilder lpString , int nMaxCount ) ;
70
- [ DllImport ( Main . DLL ) ]
71
- private static extern void Everything_Reset ( ) ;
72
- #endregion
73
-
74
- enum StateCode
13
+ /// <summary>
14
+ /// Searches the specified key word.
15
+ /// </summary>
16
+ /// <param name="keyWord">The key word.</param>
17
+ /// <param name="token">token that allow cancellation</param>
18
+ /// <param name="offset">The offset.</param>
19
+ /// <param name="maxCount">The max count.</param>
20
+ /// <returns></returns>
21
+ List < SearchResult > Search ( string keyWord , CancellationToken token , int offset = 0 , int maxCount = 100 ) ;
22
+
23
+ void Load ( string sdkPath ) ;
24
+ }
25
+
26
+ public sealed class EverythingApi : IEverythingApi
27
+ {
28
+ private const int BufferSize = 4096 ;
29
+
30
+ private readonly object _syncObject = new object ( ) ;
31
+ // cached buffer to remove redundant allocations.
32
+ private readonly StringBuilder _buffer = new StringBuilder ( BufferSize ) ;
33
+
34
+ public enum StateCode
75
35
{
76
36
OK ,
77
37
MemoryError ,
@@ -87,63 +47,63 @@ enum StateCode
87
47
/// Gets or sets a value indicating whether [match path].
88
48
/// </summary>
89
49
/// <value><c>true</c> if [match path]; otherwise, <c>false</c>.</value>
90
- public Boolean MatchPath
50
+ public bool MatchPath
91
51
{
92
52
get
93
53
{
94
- return Everything_GetMatchPath ( ) ;
54
+ return EverythingApiDllImport . Everything_GetMatchPath ( ) ;
95
55
}
96
56
set
97
57
{
98
- Everything_SetMatchPath ( value ) ;
58
+ EverythingApiDllImport . Everything_SetMatchPath ( value ) ;
99
59
}
100
60
}
101
61
102
62
/// <summary>
103
63
/// Gets or sets a value indicating whether [match case].
104
64
/// </summary>
105
65
/// <value><c>true</c> if [match case]; otherwise, <c>false</c>.</value>
106
- public Boolean MatchCase
66
+ public bool MatchCase
107
67
{
108
68
get
109
69
{
110
- return Everything_GetMatchCase ( ) ;
70
+ return EverythingApiDllImport . Everything_GetMatchCase ( ) ;
111
71
}
112
72
set
113
73
{
114
- Everything_SetMatchCase ( value ) ;
74
+ EverythingApiDllImport . Everything_SetMatchCase ( value ) ;
115
75
}
116
76
}
117
77
118
78
/// <summary>
119
79
/// Gets or sets a value indicating whether [match whole word].
120
80
/// </summary>
121
81
/// <value><c>true</c> if [match whole word]; otherwise, <c>false</c>.</value>
122
- public Boolean MatchWholeWord
82
+ public bool MatchWholeWord
123
83
{
124
84
get
125
85
{
126
- return Everything_GetMatchWholeWord ( ) ;
86
+ return EverythingApiDllImport . Everything_GetMatchWholeWord ( ) ;
127
87
}
128
88
set
129
89
{
130
- Everything_SetMatchWholeWord ( value ) ;
90
+ EverythingApiDllImport . Everything_SetMatchWholeWord ( value ) ;
131
91
}
132
92
}
133
93
134
94
/// <summary>
135
95
/// Gets or sets a value indicating whether [enable regex].
136
96
/// </summary>
137
97
/// <value><c>true</c> if [enable regex]; otherwise, <c>false</c>.</value>
138
- public Boolean EnableRegex
98
+ public bool EnableRegex
139
99
{
140
100
get
141
101
{
142
- return Everything_GetRegex ( ) ;
102
+ return EverythingApiDllImport . Everything_GetRegex ( ) ;
143
103
}
144
104
set
145
105
{
146
- Everything_SetRegex ( value ) ;
106
+ EverythingApiDllImport . Everything_SetRegex ( value ) ;
147
107
}
148
108
}
149
109
@@ -152,93 +112,106 @@ public Boolean EnableRegex
152
112
/// </summary>
153
113
public void Reset ( )
154
114
{
155
- Everything_Reset ( ) ;
156
- }
157
-
158
- private void no ( )
159
- {
160
- switch ( Everything_GetLastError ( ) )
115
+ lock ( _syncObject )
161
116
{
162
- case StateCode . CreateThreadError :
163
- throw new CreateThreadException ( ) ;
164
- case StateCode . CreateWindowError :
165
- throw new CreateWindowException ( ) ;
166
- case StateCode . InvalidCallError :
167
- throw new InvalidCallException ( ) ;
168
- case StateCode . InvalidIndexError :
169
- throw new InvalidIndexException ( ) ;
170
- case StateCode . IPCError :
171
- throw new IPCErrorException ( ) ;
172
- case StateCode . MemoryError :
173
- throw new MemoryErrorException ( ) ;
174
- case StateCode . RegisterClassExError :
175
- throw new RegisterClassExException ( ) ;
117
+ EverythingApiDllImport . Everything_Reset ( ) ;
176
118
}
177
119
}
178
120
179
121
/// <summary>
180
- /// Searches the specified key word.
122
+ /// Searches the specified key word and reset the everything API afterwards
181
123
/// </summary>
182
124
/// <param name="keyWord">The key word.</param>
125
+ /// <param name="token">when cancelled the current search will stop and exit (and would not reset)</param>
183
126
/// <param name="offset">The offset.</param>
184
127
/// <param name="maxCount">The max count.</param>
185
128
/// <returns></returns>
186
- public IEnumerable < SearchResult > Search ( string keyWord , int offset = 0 , int maxCount = 100 )
129
+ public List < SearchResult > Search ( string keyWord , CancellationToken token , int offset = 0 , int maxCount = 100 )
187
130
{
188
131
if ( string . IsNullOrEmpty ( keyWord ) )
189
- throw new ArgumentNullException ( " keyWord" ) ;
132
+ throw new ArgumentNullException ( nameof ( keyWord ) ) ;
190
133
191
134
if ( offset < 0 )
192
- throw new ArgumentOutOfRangeException ( " offset" ) ;
135
+ throw new ArgumentOutOfRangeException ( nameof ( offset ) ) ;
193
136
194
137
if ( maxCount < 0 )
195
- throw new ArgumentOutOfRangeException ( " maxCount" ) ;
138
+ throw new ArgumentOutOfRangeException ( nameof ( maxCount ) ) ;
196
139
197
- if ( keyWord . StartsWith ( "@" ) )
140
+ lock ( _syncObject )
198
141
{
199
- Everything_SetRegex ( true ) ;
200
- keyWord = keyWord . Substring ( 1 ) ;
201
- }
202
- Everything_SetSearchW ( keyWord ) ;
203
- Everything_SetOffset ( offset ) ;
204
- Everything_SetMax ( maxCount ) ;
142
+ if ( keyWord . StartsWith ( "@" ) )
143
+ {
144
+ EverythingApiDllImport . Everything_SetRegex ( true ) ;
145
+ keyWord = keyWord . Substring ( 1 ) ;
146
+ }
205
147
148
+ EverythingApiDllImport . Everything_SetSearchW ( keyWord ) ;
149
+ EverythingApiDllImport . Everything_SetOffset ( offset ) ;
150
+ EverythingApiDllImport . Everything_SetMax ( maxCount ) ;
206
151
207
- if ( ! Everything_QueryW ( true ) )
208
- {
209
- switch ( Everything_GetLastError ( ) )
152
+ if ( token . IsCancellationRequested )
153
+ {
154
+ return null ;
155
+ }
156
+
157
+
158
+ if ( ! EverythingApiDllImport . Everything_QueryW ( true ) )
210
159
{
211
- case StateCode . CreateThreadError :
212
- throw new CreateThreadException ( ) ;
213
- case StateCode . CreateWindowError :
214
- throw new CreateWindowException ( ) ;
215
- case StateCode . InvalidCallError :
216
- throw new InvalidCallException ( ) ;
217
- case StateCode . InvalidIndexError :
218
- throw new InvalidIndexException ( ) ;
219
- case StateCode . IPCError :
220
- throw new IPCErrorException ( ) ;
221
- case StateCode . MemoryError :
222
- throw new MemoryErrorException ( ) ;
223
- case StateCode . RegisterClassExError :
224
- throw new RegisterClassExException ( ) ;
160
+ CheckAndThrowExceptionOnError ( ) ;
161
+ return null ;
225
162
}
226
- yield break ;
163
+
164
+ var results = new List < SearchResult > ( ) ;
165
+ for ( int idx = 0 ; idx < EverythingApiDllImport . Everything_GetNumResults ( ) ; ++ idx )
166
+ {
167
+ if ( token . IsCancellationRequested )
168
+ {
169
+ return null ;
170
+ }
171
+
172
+ EverythingApiDllImport . Everything_GetResultFullPathNameW ( idx , _buffer , BufferSize ) ;
173
+
174
+ var result = new SearchResult { FullPath = _buffer . ToString ( ) } ;
175
+ if ( EverythingApiDllImport . Everything_IsFolderResult ( idx ) )
176
+ result . Type = ResultType . Folder ;
177
+ else if ( EverythingApiDllImport . Everything_IsFileResult ( idx ) )
178
+ result . Type = ResultType . File ;
179
+
180
+ results . Add ( result ) ;
181
+ }
182
+
183
+ Reset ( ) ;
184
+
185
+ return results ;
227
186
}
187
+ }
228
188
229
- const int bufferSize = 4096 ;
230
- StringBuilder buffer = new StringBuilder ( bufferSize ) ;
231
- for ( int idx = 0 ; idx < Everything_GetNumResults ( ) ; ++ idx )
232
- {
233
- Everything_GetResultFullPathNameW ( idx , buffer , bufferSize ) ;
189
+ [ DllImport ( "kernel32.dll" ) ]
190
+ private static extern int LoadLibrary ( string name ) ;
234
191
235
- var result = new SearchResult { FullPath = buffer . ToString ( ) } ;
236
- if ( Everything_IsFolderResult ( idx ) )
237
- result . Type = ResultType . Folder ;
238
- else if ( Everything_IsFileResult ( idx ) )
239
- result . Type = ResultType . File ;
192
+ public void Load ( string sdkPath )
193
+ {
194
+ LoadLibrary ( sdkPath ) ;
195
+ }
240
196
241
- yield return result ;
197
+ private static void CheckAndThrowExceptionOnError ( )
198
+ {
199
+ switch ( EverythingApiDllImport . Everything_GetLastError ( ) )
200
+ {
201
+ case StateCode . CreateThreadError :
202
+ throw new CreateThreadException ( ) ;
203
+ case StateCode . CreateWindowError :
204
+ throw new CreateWindowException ( ) ;
205
+ case StateCode . InvalidCallError :
206
+ throw new InvalidCallException ( ) ;
207
+ case StateCode . InvalidIndexError :
208
+ throw new InvalidIndexException ( ) ;
209
+ case StateCode . IPCError :
210
+ throw new IPCErrorException ( ) ;
211
+ case StateCode . MemoryError :
212
+ throw new MemoryErrorException ( ) ;
213
+ case StateCode . RegisterClassExError :
214
+ throw new RegisterClassExException ( ) ;
242
215
}
243
216
}
244
217
}
0 commit comments