Finding the application associated with an extension
by J.G.Harston, August 2008
The application associated with a particular file extension (actually, the command used to launch or open a file) is stored in the system registry. This associated command can be found with the following code:
DEF FNFile_Association(ext$) LOCAL root$,command$,A% root$=FNRegistry_RdStr(&80000000,ext$,"") :REM No file association command$=FNRegistry_RdStr(&80000000, root$+"\shell\open\command","") IF command$="" THEN ="" :REM No open command A%=INSTR(command$,"%1"):IF A% THEN command$=LEFT$(command$,A%-1)+MID$(command$,A%+2) A%=INSTR(command$,""""""):IF A% THEN command$=LEFT$(command$,A%-1)+MID$(command$,A%+2) =FNPath_Expand(command$)
So, for example, FNFile_Association(“.txt”) may return “C:\Program Files\Metapad\metapad.exe”. If there is no file association, then a null string is returned.
The above code uses the following code from the Registry library and a routine called FNPath_Expand:
DEF FNRegistry_RdInt(hk%,Key$,Item$):LOCAL Want%:Want%=4 DEF FNRegistry_RdBig(hk%,Key$,Item$):LOCAL Want%:Want%=4 DEF FNRegistry_RdStr(hk%,Key$,Item$):LOCAL Want%:Want%=1 DEF FNRegistry_Rd( hk%,Key$,Item$):LOCAL Want%:Want%=1 LOCAL K%,R%,L%,T%,S$,Buf% SYS "RegOpenKeyEx",hk%,Key$,0,&20001,^K% TO R% IF R%=0 THEN SYS "RegQueryValueEx",K%,Item$,0,^T%,0,^L%:DIM Buf% LOCAL L% SYS "RegQueryValueEx",K%,Item$,0,^T%,Buf%,^L% TO R% SYS "RegCloseKey",K% ENDIF IF Want%=4 :IF R%=0:=0 IF Want%=4 :=!Buf% IF R%:="" IF T%=1:Buf%?(L%-1)=0:=$$Buf% K%=Buf%:WHILE L%:S$+=CHR$?K%:K%+=1:L%-=1:ENDWHILE =S$ DEF FNPath_Expand(S$) LOCAL B%:DIM B% LOCAL 255 SYS "ExpandEnvironmentStrings", S$, B%, 256 =$$B%
by Richard Russell, September 2008
If you prefer not to access the Registry directly, the function below will return the path and name of the executable program which is associated with a particular file:
DEF FN_FindExecutable(file$) LOCAL executable{} DIM executable{name&(256)} SYS "FindExecutable", file$, "", executable{} = executable.name&()
The main difference from the code listed by Jonathan Harston is that rather than supplying just an extension you must supply the name of an actual file with that extension, which must exist. To overcome that restriction the following function temporarily creates such a file, and in so doing reproduces the functionality of DEFFNFile_Association:
DEF FNFile_Association(ext$) LOCAL executable{} DIM executable{name&(256)} OSCLI "SAVE temp"+ext$+" "+STR$~PAGE+" +0" SYS "FindExecutable", "temp"+ext$, "", executable{} OSCLI "DELETE temp"+ext$ = executable.name&()
Note that this function relies on the 'current directory' being writable.
by J.G.Harston, May 2009
BBC BASIC for Windows version 5.90 introduced the @tmp$ system variable which points to a writable temporary directory. The above code can be rewritten to avoid relying on writing to the current directory:
DEF FNFile_Association(ext$) LOCAL executable{} DIM executable{name&(256)} OSCLI "SAVE """+@tmp$+"temp"+ext$+""" "+STR$~PAGE+" +0" SYS "FindExecutable", @tmp$+"temp"+ext$, "", executable{} OSCLI "DELETE """+@tmp$+"temp"+ext$+"""" = executable.name&()