22using System . Collections . Generic ;
33using System . Runtime . InteropServices ;
44using System . Text ;
5+ using System . Threading ;
6+ using Wox . Infrastructure . Logger ;
57using Wox . Plugin . Everything . Everything . Exceptions ;
68
79namespace Wox . Plugin . Everything . Everything
810{
9- public sealed class EverythingAPI
11+ public interface IEverythingApi
1012 {
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
7535 {
7636 OK ,
7737 MemoryError ,
@@ -87,63 +47,63 @@ enum StateCode
8747 /// Gets or sets a value indicating whether [match path].
8848 /// </summary>
8949 /// <value><c>true</c> if [match path]; otherwise, <c>false</c>.</value>
90- public Boolean MatchPath
50+ public bool MatchPath
9151 {
9252 get
9353 {
94- return Everything_GetMatchPath ( ) ;
54+ return EverythingApiDllImport . Everything_GetMatchPath ( ) ;
9555 }
9656 set
9757 {
98- Everything_SetMatchPath ( value ) ;
58+ EverythingApiDllImport . Everything_SetMatchPath ( value ) ;
9959 }
10060 }
10161
10262 /// <summary>
10363 /// Gets or sets a value indicating whether [match case].
10464 /// </summary>
10565 /// <value><c>true</c> if [match case]; otherwise, <c>false</c>.</value>
106- public Boolean MatchCase
66+ public bool MatchCase
10767 {
10868 get
10969 {
110- return Everything_GetMatchCase ( ) ;
70+ return EverythingApiDllImport . Everything_GetMatchCase ( ) ;
11171 }
11272 set
11373 {
114- Everything_SetMatchCase ( value ) ;
74+ EverythingApiDllImport . Everything_SetMatchCase ( value ) ;
11575 }
11676 }
11777
11878 /// <summary>
11979 /// Gets or sets a value indicating whether [match whole word].
12080 /// </summary>
12181 /// <value><c>true</c> if [match whole word]; otherwise, <c>false</c>.</value>
122- public Boolean MatchWholeWord
82+ public bool MatchWholeWord
12383 {
12484 get
12585 {
126- return Everything_GetMatchWholeWord ( ) ;
86+ return EverythingApiDllImport . Everything_GetMatchWholeWord ( ) ;
12787 }
12888 set
12989 {
130- Everything_SetMatchWholeWord ( value ) ;
90+ EverythingApiDllImport . Everything_SetMatchWholeWord ( value ) ;
13191 }
13292 }
13393
13494 /// <summary>
13595 /// Gets or sets a value indicating whether [enable regex].
13696 /// </summary>
13797 /// <value><c>true</c> if [enable regex]; otherwise, <c>false</c>.</value>
138- public Boolean EnableRegex
98+ public bool EnableRegex
13999 {
140100 get
141101 {
142- return Everything_GetRegex ( ) ;
102+ return EverythingApiDllImport . Everything_GetRegex ( ) ;
143103 }
144104 set
145105 {
146- Everything_SetRegex ( value ) ;
106+ EverythingApiDllImport . Everything_SetRegex ( value ) ;
147107 }
148108 }
149109
@@ -152,93 +112,106 @@ public Boolean EnableRegex
152112 /// </summary>
153113 public void Reset ( )
154114 {
155- Everything_Reset ( ) ;
156- }
157-
158- private void no ( )
159- {
160- switch ( Everything_GetLastError ( ) )
115+ lock ( _syncObject )
161116 {
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 ( ) ;
176118 }
177119 }
178120
179121 /// <summary>
180- /// Searches the specified key word.
122+ /// Searches the specified key word and reset the everything API afterwards
181123 /// </summary>
182124 /// <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>
183126 /// <param name="offset">The offset.</param>
184127 /// <param name="maxCount">The max count.</param>
185128 /// <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 )
187130 {
188131 if ( string . IsNullOrEmpty ( keyWord ) )
189- throw new ArgumentNullException ( " keyWord" ) ;
132+ throw new ArgumentNullException ( nameof ( keyWord ) ) ;
190133
191134 if ( offset < 0 )
192- throw new ArgumentOutOfRangeException ( " offset" ) ;
135+ throw new ArgumentOutOfRangeException ( nameof ( offset ) ) ;
193136
194137 if ( maxCount < 0 )
195- throw new ArgumentOutOfRangeException ( " maxCount" ) ;
138+ throw new ArgumentOutOfRangeException ( nameof ( maxCount ) ) ;
196139
197- if ( keyWord . StartsWith ( "@" ) )
140+ lock ( _syncObject )
198141 {
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+ }
205147
148+ EverythingApiDllImport . Everything_SetSearchW ( keyWord ) ;
149+ EverythingApiDllImport . Everything_SetOffset ( offset ) ;
150+ EverythingApiDllImport . Everything_SetMax ( maxCount ) ;
206151
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 ) )
210159 {
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 ;
225162 }
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 ;
227186 }
187+ }
228188
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 ) ;
234191
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+ }
240196
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 ( ) ;
242215 }
243216 }
244217 }
0 commit comments