-
Notifications
You must be signed in to change notification settings - Fork 0
/
configureFileAssociation.bas
409 lines (321 loc) · 10.9 KB
/
configureFileAssociation.bas
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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
call InitRegistry
gosub [findLBexes]
dim LBExeList$(numLBexes)
For x = 1 to numLBexes
LBExeList$(x) = word$(LBExes$, x, "|")
Next x
'Form created with the help of Freeform 3 v07-15-08
'Generated on Jan 15, 2016 at 22:13:48
[setup.m.Window]
nomainwin
'-----Begin code for #m
WindowWidth = 520
WindowHeight = 245
UpperLeftX=int((DisplayWidth-WindowWidth)/2)
UpperLeftY=int((DisplayHeight-WindowHeight)/2)
'-----Begin GUI objects code
button #m.btnFindExe,"Locate custom EXE",[findEXE], UL, 40, 172, 140, 25
TextboxColor$ = "white"
textbox #m.tbExePath, 40, 132, 415, 25
button #m.btnSetAssociation,"Set Association",[setAssociation], UL, 350, 172, 103, 25
ListboxColor$ = "white"
listbox #m.lbExeList, LBExeList$(), [selectListEntry], 40, 17, 415, 100
'-----End GUI objects code
open "Set BAS file association" for window as #m
print #m, "font ms_sans_serif 10"
#m.btnSetAssociation, "!disable"
#m.lbExeList, "singleclickselect"
#m, "trapclose [quit.m]"
[m.inputLoop] 'wait here for input event
wait
[selectListEntry]
#m.lbExeList, "selection? LBPath$"
#m.tbExePath, LBPath$
#m.btnSetAssociation, "!enable"
wait
[findEXE] 'Perform action for the button named 'btnFindExe'
'Insert your own code here
filedialog "Locate LB exe...", "*.exe", LBPath$
if LBPath$ = "" then
#m.tbExePath, "<no EXE file selected>"
#m.btnSetAssociation, "!disable"
else
#m.btnSetAssociation, "!enable"
end if
#m.tbExePath, LBPath$
wait
[setAssociation] 'Perform action for the button named 'btnSetAssociation'
'Insert your own code here
assocPath$ = chr$(34) + LBPath$ + chr$(34) + " " + chr$(34) + "%1" + chr$(34)
a = RegOpenKeyEx(_HKEY_CLASSES_ROOT, ".bas", 0, _KEY_READ, hBas)
If a <> 0 then
goto [skipBackup]
end if
bufSize = 0
[bufferLoop]
buf$ = space$(bufSize)
a = RegQueryValueEx(hBas, "", buf$, bufSize)
if a = ERROR.MORE.DATA then [bufferLoop]
if a <> 0 then
a = RegCloseKey(hBas)
goto [skipBackup]
wait
end if
originalBasAssocation$ = trim$(buf$)
[skipBackup]
a = RegCreateKeyEx(_HKEY_CURRENT_USER, "Software\Classes\LibertyBASIC.BasFile\shell\open\command",_
0, _KEY_ALL_ACCESS, hCommand)
If a <> 0 then
ret = FormatSystemErrorMessage(a, formattedMessage$)
errMsg$ = "Registry error" + chr$(13) + _
"Unable to open HKCU\Software\Classes\LibertyBASIC.BasFile\shell\open\command for writing."
errMsg$ = errMsg$ + chr$(13) + chr$(13) + "RegCreateKeyEx() returned ";a;":"
errMsg$ = errMsg$ + chr$(13) + formattedMessage$
notice errMsg$
wait
end if
a = RegSetValueEx(hCommand, "", assocPath$)
If a <> 0 then
ret = FormatSystemErrorMessage(a, formattedMessage$)
errMsg$ = "Registry error" + chr$(13) + _
"Unable to write new association to HKCU\Software\Classes\LibertyBASIC.BasFile\shell\open\command\(default)"
errMsg$ = errMsg$ + chr$(13) + chr$(13) + "RegSetValueEx() returned ";a;":"
errMsg$ = errMsg$ + chr$(13) + formattedMessage$
notice errMsg$
a = RegCloseKey(hCommand)
wait
end if
a = RegCloseKey(hCommand)
a = RegCreateKeyEx(_HKEY_CURRENT_USER, "Software\Classes\.bas", 0, _KEY_ALL_ACCESS, hBas)
If a <> 0 then
ret = FormatSystemErrorMessage(a, formattedMessage$)
errMsg$ = "Registry error" + chr$(13) + "Unable to open HKCU\Software\Classes\.bas for writing."
errMsg$ = errMsg$ + chr$(13) + chr$(13) + "RegCreateKeyEx() returned ";a;":"
errMsg$ = errMsg$ + chr$(13) + formattedMessage$
notice errMsg$
End If
a = RegSetValueEx(hBas, "", "LibertyBASIC.BasFile")
If a <> 0 then
ret = FormatSystemErrorMessage(a, formattedMessage$)
errMsg$ = "Registry error" + chr$(13) + _
"Unable to write new association identifier to HKCU\Software\Classes\.bas\(default)."
errMsg$ = errMsg$ + chr$(13) + chr$(13) + "RegSetValueEx() returned ";a;":"
errMsg$ = errMsg$ + chr$(13) + formattedMessage$
notice errMsg$
a = RegCloseKey(hBas)
wait
End If
a = RegCloseKey(hBas)
Call SHNotifyAssocChange
Notice "New association set!"
wait
[quit.m] 'End the program
call EndRegistry
close #m
end
'===============================================
' SUBS/FUNCTIONS BELOW
'===============================================
[findLBexes]
CSIDL.PROGRAMFILES = 38
programFilesName$ = GetFileName$(GetSpecialFolder$(CSIDL.PROGRAMFILES))
'EXE names to search for
searchExes$ = "liberty.exe lbpro.exe lbworkshop.exe jbasic.exe"
driveNum = 1
driveLetter$ = word$(Drives$, driveNum) + "\"
dim info$(10, 10)
[nextDrive]
files driveLetter$, info$()
numFiles = val(info$(0,0))
numFolders = val(info$(0,1))
searchPath$ = ""
'Confirm that the folder <driveLetter>\<programFilesName> exists
if numFolders = 0 then [skipSearchFolder]
for x = numFiles+1 to (numFiles+numFolders)
folderName$ = info$(x, 1)
if folderName$ = programFilesName$ then
searchPath$ = driveLetter$ + folderName$
end if
next x
print "searchPath$ = ";searchPath$
'Search through <programFilesName> for LB-related program folders
LBFolderList$ = ""
numLBFolders = 0
if searchPath$ <> "" then
files searchPath$, info$()
numFiles = val(info$(0,0))
numFolders = val(info$(0,1))
if numFolders = 0 then [skipSearchFolder]
for x = numFiles+1 to (numFiles+numFolders)
folderName$ = info$(x, 1)
foundLBfolder = 0
if left$(folderName$, 13) = "Liberty BASIC" then foundLBfolder = 1
if left$(folderName$, 10) = "Just BASIC" then foundLBfolder = 1
if folderName$ = "LB Workshop" then foundLBfolder = 1
if foundLBfolder = 1 then
LBFolderList$ = LBFolderList$ + searchPath$ + "\" + folderName$ + "|"
numLBFolders = numLBFolders + 1
end if
next x
end if
print LBFolderList$
'For each LB-related program folder, find the EXE name
if numLBFolders = 0 then [skipSearchFolder]
for x = 1 to numLBFolders
searchPath$ = word$(LBFolderList$, x, "|")
files searchPath$, info$()
numFiles = val(info$(0, 0))
if numFiles = 0 then [doNextFolder]
For y = 1 to numFiles
if instr(searchExes$, info$(y, 0)) > 0 then
LBExes$ = LBExes$ + searchPath$ + "\" + info$(y, 0) + "|"
numLBexes = numLBexes + 1
end if
next y
[doNextFolder]
next x
[skipSearchFolder]
driveNum = driveNum + 1
driveLetter$ = word$(Drives$, driveNum) + "\"
if driveLetter$ <> "\" then [nextDrive]
return
[theEnd]
end
Function GetFileName$(fullPath$)
lenFullPath = len(fullPath$)
For x = lenFullPath to 1 step -1
if mid$(fullPath$, x, 1) = "\" then
GetFileName$ = mid$(fullPath$, x+1)
goto [skip]
end if
next x
[skip]
End Function
Function GetSpecialFolder$(CSIDL)
struct IDL, _
cb As uLong, _
abID As short
calldll #shell32, "SHGetSpecialFolderLocation",_
0 as ulong, _
CSIDL as ulong, _
IDL as struct,_
ret as ulong
if ret=0 then
Path$ = Space$(_MAX_PATH)
id = IDL.cb.struct
calldll #shell32, "SHGetPathFromIDListA",_
id as ulong, _
Path$ as ptr, _
ret as ulong
GetSpecialFolder$ = trim$(Path$)
end if
if GetSpecialFolder$ = "" then GetSpecialFolder$ = "Not Applicable"
End Function
Sub SHNotifyAssocChange
SHCNE.ASSOCCHANGED = hexdec("08000000")
SHCNF.IDLIST = 0
CallDLL #shell32, "SHChangeNotify",_
SHCNE.ASSOCCHANGED as long,_
SHCNF.IDLIST as long,_
0 as long,_
0 as long,_
ret as void
End Sub
Function FormatSystemErrorMessage(code, byref buffer$)
bufLen = (1024 * 64) - 1
buffer$ = space$(bufLen)
CallDLL #kernel32, "FormatMessageA",_
_FORMAT_MESSAGE_FROM_SYSTEM as long,_
0 as long,_
code as long,_
0 as long,_
buffer$ as ptr,_
bufLen as long,_
0 as long,_
FormatSystemErrorMessage as long
buffer$ = trim$(buffer$)
End Function
Function GetLastError()
CallDLL #kernel32, "GetLastError",_
GetLastError as long
End Function
Sub InitRegistry
Open "advapi32" for DLL as #advapi32
Global ERROR.MORE.DATA : ERROR.MORE.DATA = 234
End Sub
Sub EndRegistry
close #advapi32
End Sub
Function RegCreateKeyEx(hKey, subKey$, dwOptions, samDesired, byref phkResult)
struct res, a as ulong
CallDLL #advapi32, "RegCreateKeyExA",_
hKey as ulong,_
subKey$ as ptr,_
0 as long,_ 'Reserved, must be 0.
0 as ulong,_ 'User-defined class type of key.
_ 'Very unlikely to be used, so 0.
dwOptions as long,_
samDesired as long,_
0 as ulong,_ 'lpSecurityAttributes, used for setting permissions on
_ 'the key, among other things. Unlikely to be used.
res as struct,_
0 as ulong,_ 'lpDisposition, tells us if the key was opened or created.
_ 'Again, unlikely to be used, so 0.
RegCreateKeyEx as long
phkResult = res.a.struct
End Function
'For ease of function use, all registry keys will be strings.
Function RegSetValueEx(hKey, valueName$, data$)
cbSize = len(data$)
CallDLL #advapi32, "RegSetValueExA",_
hKey as ulong,_
valueName$ as ptr,_
0 as long,_ 'Reserved.
_REG_SZ as long,_ 'Always string.
data$ as ptr,_
cbSize as long,_
RegSetValueEx as long
End Function
Function RegOpenKeyEx(hKey, subKey$, dwOptions, samDesired, byref phkResult)
struct res, a as ulong
CallDLL #advapi32, "RegOpenKeyExA",_
hKey as ulong,_
subKey$ as ptr,_
0 as long,_ 'Reserved, must be 0.
0 as ulong,_ 'User-defined class type of key.
_ 'Very unlikely to be used, so 0.
dwOptions as long,_
samDesired as long,_
RegCreateKeyEx as long
phkResult = res.a.struct
End Function
Function RegQueryValueEx(hKey, valueName$, byref data$, byref bufSize)
struct a, size as long
a.size.struct = bufSize
CallDLL #advapi32, "RegQueryValueExA",_
hKey as ulong,_
valueName$ as ptr,_
0 as long,_ 'Reserved.
0 as ulong,_ 'Datatype. Not used, this function only uses REG_SZ.
data$ as ptr,_
a as struct,_
RegQueryValueEx as long
bufSize = a.size.struct
End Function
Function RegDeleteValue(hKey, valueName$)
CallDLL #advapi32, "RegDeleteValueA",_
hKey as ulong,_
valueName$ as ptr,_
RegDeleteValue as long
End Function
Function RegDeleteKey(hKey, keyName$)
CallDLL #advapi32, "RegDeleteKeyA",_
hKey as ulong,_
keyName$ as ptr,_
RegDeleteKey as long
End Function
Function RegCloseKey(hKey)
CallDLL #advapi32, "RegCloseKey",_
hKey as ulong,_
RegCloseKey as long
End Function