Τρίτη 16 Δεκεμβρίου 2025

Search Inkscape.exe (or any exe file) Updated

This is the new solution using ItemUrl which return file://path using / as URL. Also there is a way to read the path from link. Path from link maybe is ANSI encoded for language of OS system (we have to use the proper locale id (using Locale 1032 for greek names), or UTF16LE. So if you make a text file والكليات.txt in Documents and make a lnk file and then move this file to Desktop folder (and rename the link as والكليات ) then the inner function findlnk find the unicode name. All names have 0 at the end (like all C strings).

When we load the lnk file in a buffer we get offsets from base 0 (not base 1 for file). 


function findExefile(this$, typ$="exe") {
function findlnk(linkfile$) {
function ReadSingleString(b as buffer, offset) {
=leftpart$(chr$(eval$(b, offset, len(b)-offset)), chr$(0))
}
function ReadDoubleString(b as buffer, offset) {
=leftpart$(eval$(b, offset, len(b)-offset), chr$(0))
}
=""
let a=buffer(linkfile$), offset=0
if eval(a, offset as long)=76 then
ShortcutFilename=""
Long offset=20
long Flags=a[offset]
if binary.and(Flags,2)>1 then
offset= eval(a, 76 as integer)+76+2
end if
if binary.and(Flags,2)>0 then
TotalStructLength=eval(a, offset as long)
PtrBasePath=eval(a, offset+16 as long)
PtrNetworkVolumeInfo=eval(a, offset+20 as long)
PtrFilename=eval(a, offset+24 as long)
If PtrBasePath Then
ShortcutFilename = ReadSingleString(a, offset + PtrBasePath)
if len(ShortcutFilename)<TotalStructLength-PtrBasePath-2 then
ShortcutFilename=ReadDoubleString(a, offset + PtrBasePath+len(ShortcutFilename)+1)
end if
Else.If PtrNetworkVolumeInfo Then
ShortcutFilename = ReadSingleString(a, offset + PtrNetworkVolumeInfo + &H14)
End If
If PtrFilename Then
Str = ReadSingleString(a, offset + PtrFilename)
If Str <> "" and false Then
If Right$(ShortcutFilename, 1) <> "\" Then
ShortcutFilename += "\"
End If
ShortcutFilename += Str
End If
End If
= ShortcutFilename
end if
end if
}
ShortcutFilename=""
declare cn "ADODB.Connection"
method cn, "open", "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
search$={SELECT System.ItemUrl
FROM SystemIndex
WHERE System.FileName = '@@@.###'
}
if typ$="" else
method cn, "execute", replace$("@@@", this$, replace$("###",typ$,search$)) as rs
with rs, "eof" as rs.EOF, "fields" as field()
while not rs.EOF {
ShortcutFilename=field(0)
method rs, "movenext"
}
end if
if ShortcutFilename="" else =replace$("/","\",rightpart$(ShortcutFilename, ":")): exit
method cn, "execute", replace$("@@@", this$, replace$("###","lnk",search$)) as rs
if Valid(rs.EOF) Else with rs, "eof" as rs.EOF, "fields" as field()
while not rs.EOF {
ShortcutFilename=field(0)
method rs, "movenext"
}
if ShortcutFilename="" then exit
=findlnk(replace$("/","\",rightpart$(ShortcutFilename, ":")))


}
Print findExefile("Inkscape")
Print findExefile("والكليات", "txt")

This is from my example, there are two links in desktop folder which the Search.CollatorDSO provider can find (We can change the folder list from windows indexing options)

C:\Program Files\Inkscape\bin\inkscape.exe  (was ANSI)

C:\Users\fotod\OneDrive\Έγγραφα\والكليات.txt (was two parts: the ansi but with three languages English, Greek, Arabian, was impossible to read, and the UTF16LE which is ok)


OLD: works if we have English language for OS, because the ItemPathDisplay return names like folder USERS using the system language of Windows. 

Using simple function:

Print @findExe("Inkscape")


function findExe(this$)
declare local cn "ADODB.Connection"
method cn, "open", "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
local search$={SELECT System.ItemPathDisplay
FROM SystemIndex
WHERE System.FileName = '@@@.exe'
}
method cn, "execute", replace$("@@@", this$, search$) as new rs
with rs, "eof" as new rs.EOF, "fields" as new field()
=""
if not rs.EOF then =field(0)
end function


Using function (can be member of a class too)

function findExe(this$) {
declare cn "ADODB.Connection"
method cn, "open", "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
search$={SELECT System.ItemPathDisplay
FROM SystemIndex
WHERE System.FileName = '@@@.exe'
}
method cn, "execute", replace$("@@@", this$, search$) as rs
with rs, "eof" as rs.EOF, "fields" as field()
=""
if not rs.EOF then =field(0)
}
Print findExe("Inkscape")


This is the simple version which find inkscape exe and lnk files:

declare cn "ADODB.Connection"
method cn, "open", "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
search$={SELECT System.ItemNameDisplay, System.ItemPathDisplay
FROM SystemIndex
WHERE System.FileName = 'Inkscape.exe'
OR (System.FileExtension = '.lnk' AND System.ItemNameDisplay LIKE '%Inkscape%')
}
method cn, "execute", search$ as rs
with rs, "eof" as rs.EOF, "fields" as field()
while not rs.EOF
Print field(0);" -> ";field(1)
method rs, "MoveNext"
end while


Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.