-
Notifications
You must be signed in to change notification settings - Fork 0
/
CLSID_IID_Search.ahk
297 lines (275 loc) · 9.27 KB
/
CLSID_IID_Search.ahk
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
SetBatchLines, -1
Fileread, constants, CLSID_IID.csv
Loop, Parse, constants, ","
data .= data ? "`n" A_LoopField : A_LoopField
Display := data
Options := "in"
Menu, HelpMenu, Add, &Help, Help
Gui, Menu, HelpMenu
Gui, Add, Edit, x10 y+10 w350 h25 vQueryText gQuery,
Gui, Add, Text, x+10 w30, Query
Gui, Add, ListView, grid x10 y+20 w800 r20 gMyListView vMyListView, Name | CLSID/IID
LV_ModifyCol(1, 500) ; change width of name field
LV_ModifyCol(2, 300)
Loop, Parse, Data, `n
{
rows++
Array1 := StrSplit(A_Loopfield, ",")
LV_Add("", Array1[1], Array1[2])
}
Gui, Show, , CLSID/IID Search
return
Query:
Gui, Submit, NoHide
Display := Sift_Regex(Data, QueryText, Options)
displayRows := 0
Loop, Parse, Display, `n
{
displayRows++
displayRow%a_index% := a_loopfield
}
loop % rows {
if (a_index <= displayRows) {
Array := StrSplit(displayRow%a_index%, ",")
LV_Modify(a_index,, Array[1], Array[2])
}
else {
LV_Modify(a_index,, "","")
}
}
return
Escape::
GuiClose:
ExitApp
MyListView:
if (A_GuiControlEvent == "R")
{
LV_GetText(name, A_EventInfo, 1)
clipboard := name
msgbox ID by name: %name%`r`n(on clipboard also)
return
}
if (A_GuiControlEvent == "DoubleClick")
{
LV_GetText(number, A_EventInfo, 2)
clipboard := number
msgbox CLS/I ID: %number%`r`n(on clipboard also)
return
}
;return
Help:
v =
(
Type in some or all of a CLSID or IID to find.
You can delete, edit, and otherwise modify your search,
and the ListView will refresh accordingly.
When you see an ID you want to retrieve:
Double-right-click to get the name on the clipboard;
Double-click to get the value on the clipboard.
That's it!
)
msgbox %v%
return
;{ Sift
; Fanatic Guru
; 2015 04 30
; Version 1.00
;
; LIBRARY to sift through a string or array and return items that match sift criteria.
;
; ===================================================================================================================================================
;
; Functions:
;
; ===================================================================================================================================================
; Sift_Regex(Haystack, Needle, Options, Delimiter)
;
; Parameters:
; 1) {Haystack} String or array of information to search, ByRef for efficiency but Haystack is not changed by function
;
; 2) {Needle} String providing search text or criteria, ByRef for efficiency but Needle is not changed by function
;
; 3) {Options}
; IN Needle anywhere IN Haystack item (Default = IN)
; LEFT Needle is to LEFT or beginning of Haystack item
; RIGHT Needle is to RIGHT or end of Haystack item
; EXACT Needle is an EXACT match to Haystack item
; REGEX Needle is an REGEX expression to check against Haystack item
; OC Needle is ORDERED CHARACTERS to be searched for even non-consecutively but in the given order in Haystack item
; OW Needle is ORDERED WORDS to be searched for even non-consecutively but in the given order in Haystack item
; UC Needle is UNORDERED CHARACTERS to be search for even non-consecutively and in any order in Haystack item
; UW Needle is UNORDERED WORDS to be search for even non-consecutively and in any order in Haystack item
;
; If an Option is all lower case then the search will be case insensitive
;
; 4) {Delimiter} Single character Delimiter of each item in a Haystack string (Default = `n)
;
; Returns:
; If Haystack is string then a string is returned of found Haystack items delimited by the Delimiter
; If Haystack is an array then an array is returned of found Haystack items
;
; Note:
; Sift_Regex searchs are all RegExMatch seaches with Needles crafted based on the options chosen
;
; ===================================================================================================================================================
; Sift_Ngram(Haystack, Needle, Delta, Haystack_Matrix, Ngram Size, Format)
;
; Parameters:
; 1) {Haystack} String or array of information to search, ByRef for efficiency but Haystack is not changed by function
;
; 2) {Needle} String providing search text or criteria, ByRef for efficiency but Needle is not changed by function
;
; 3) {Delta} (Default = .7) Fuzzy match coefficient, 1 is a prefect match, 0 is no match at all, only results above the Delta are returned
;
; 4) {Haystack_Matrix} (Default = false)
; An object containing the preprocessing of the Haystack for Ngrams content
; If a non-object is passed the Haystack is processed for Ngram content and the results are returned by ByRef
; If an object is passed then that is used as the processed Ngram content of Haystack
; If multiply calls to the function are made with no change to the Haystack then a previous processing of Haystack for Ngram content
; can be passed back to the function to avoid reprocessing the same Haystack again in order to increase efficiency.
;
; 5) {Ngram Size} (Default = 3) The length of Ngram used. Generally Ngrams made of 3 letters called a Trigram is good
;
; 6) {Format} (Default = S`n)
; S Return Object with results Sorted
; U Return Object with results Unsorted
; S%%% Return Sorted string delimited by characters after S
; U%%% Return Unsorted string delimited by characters after U
; Sorted results are by best match first
;
; Returns:
; A string or array depending on Format parameter.
; If string then it is delimited based on Format parameter.
; If array then an array of object is returned where each element is of the structure: {Object}.Delta and {Object}.Data
; Example Code to access object returned:
; for key, element in Sift_Ngram(Data, QueryText, NgramLimit, Data_Ngram_Matrix, NgramSize)
; Display .= element.delta "`t" element.data "`n"
;
; Dependencies: Sift_Ngram_Get, Sift_Ngram_Compare, Sift_Ngram_Matrix, Sift_SortResults
; These are helper functions that are generally not called directly. Although Sift_Ngram_Matrix could be useful to call directly to preprocess a large static Haystack
;
; Note:
; The string "dog house" would produce these Trigrams: dog|og |g h| ho|hou|ous|use
; Sift_Ngram breaks the needle and each item of the Haystack up into Ngrams.
; Then all the Needle Ngrams are looked for in the Haystack items Ngrams resulting in a percentage of Needle Ngrams found
;
; ===================================================================================================================================================
;
Sift_Regex(ByRef Haystack, ByRef Needle, Options := "IN", Delimit := "`n")
{
Sifted := {}
if (Options = "IN")
Needle_Temp := "\Q" Needle "\E"
else if (Options = "LEFT")
Needle_Temp := "^\Q" Needle "\E"
else if (Options = "RIGHT")
Needle_Temp := "\Q" Needle "\E$"
else if (Options = "EXACT")
Needle_Temp := "^\Q" Needle "\E$"
else if (Options = "REGEX")
Needle_Temp := Needle
else if (Options = "OC")
Needle_Temp := RegExReplace(Needle,"(.)","\Q$1\E.*")
else if (Options = "OW")
Needle_Temp := RegExReplace(Needle,"( )","\Q$1\E.*")
else if (Options = "UW")
Loop, Parse, Needle, " "
Needle_Temp .= "(?=.*\Q" A_LoopField "\E)"
else if (Options = "UC")
Loop, Parse, Needle
Needle_Temp .= "(?=.*\Q" A_LoopField "\E)"
if Options is lower
Needle_Temp := "i)" Needle_Temp
if IsObject(Haystack)
{
for key, Hay in Haystack
if RegExMatch(Hay, Needle_Temp)
Sifted.Insert(Hay)
}
else
{
Loop, Parse, Haystack, %Delimit%
if RegExMatch(A_LoopField, Needle_Temp)
Sifted .= A_LoopField Delimit
Sifted := SubStr(Sifted,1,-1)
}
return Sifted
}
Sift_Ngram(ByRef Haystack, ByRef Needle, Delta := .7, ByRef Haystack_Matrix := false, n := 3, Format := "S`n" )
{
if !IsObject(Haystack_Matrix)
Haystack_Matrix := Sift_Ngram_Matrix(Haystack, n)
Needle_Ngram := Sift_Ngram_Get(Needle, n)
if IsObject(Haystack)
{
Search_Results := {}
for key, Hay_Ngram in Haystack_Matrix
{
Result := Sift_Ngram_Compare(Hay_Ngram, Needle_Ngram)
if !(Result < Delta)
Search_Results[key,"Delta"] := Result, Search_Results[key,"Data"] := Haystack[key]
}
}
else
{
Search_Results := {}
Loop, Parse, Haystack, `n, `r
{
Result := Sift_Ngram_Compare(Haystack_Matrix[A_Index], Needle_Ngram)
if !(Result < Delta)
Search_Results[A_Index,"Delta"] := Result, Search_Results[A_Index,"Data"] := A_LoopField
}
}
if (Format ~= "i)^S")
Sift_SortResults(Search_Results)
if RegExMatch(Format, "i)^(S|U)(.+)$", Match)
{
for key, element in Search_Results
String_Results .= element.data Match2
return SubStr(String_Results,1,-StrLen(Match2))
}
else
return Search_Results
}
Sift_Ngram_Get(ByRef String, n := 3)
{
Pos := 1, Grams := {}
Loop, % (1 + StrLen(String) - n)
gram := SubStr(String, A_Index, n), Grams[gram] ? Grams[gram] ++ : Grams[gram] := 1
return Grams
}
Sift_Ngram_Compare(ByRef Hay, ByRef Needle)
{
for gram, Needle_Count in Needle
{
Needle_Total += Needle_Count
Match += (Hay[gram] > Needle_Count ? Needle_Count : Hay[gram])
}
return Match / Needle_Total
}
Sift_Ngram_Matrix(ByRef Data, n := 3)
{
if IsObject(Data)
{
Matrix := {}
for key, string in Data
Matrix.Insert(Sift_Ngram_Get(string, n))
}
else
{
Matrix := {}
Loop, Parse, Data, `n
Matrix.Insert(Sift_Ngram_Get(A_LoopField, n))
}
return Matrix
}
Sift_SortResults(ByRef Data)
{
Data_Temp := {}
for key, element in Data
Data_Temp[element.Delta SubStr("0000000000" key, -9)] := element
Data := {}
for key, element in Data_Temp
Data.InsertAt(1,element)
return
}