Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
“Nice” application names
#1
The examples in Samples2 give a good way to put together a list of the currently running applications. Unfortunately, Windows tends to use cryptic names like MSIMN.exe, though.

Is there any good way of getting a human-readable name for each one? The best I have been able to figure out is to check the registry key
"Software\Microsoft\Windows\ShellNoRoam\MUICache"

I have no idea what the part of the registry is supposed to do, but it usually (but not always) gives a readable application name. (This is with Windows XP Home SP1.)

Just in case you’re curious, here’s the macro I’m using this with. Beware that this probably has a memory bug hidden in it — I don’t recommend it for general use.

(It’s meant to be triggered by a mouse click in the upper right corner of the screen, using a filter function. Filter functions are definitely keen. Smile )

---------------------------

#compile "toolhelp"

str theWindowList
int listChoice

spe
;ClearOutput


str s.flags=1; s.all(MAX_PATH)
str sLong.flags=1; sLong.all(MAX_PATH)
str realNameList = ""; realNameList.all(1024)
str appList = ""; appList.all(512)
str realName; realName.all(256)

int n, n2(256), i, hMod, hProcess
int* a

rep()
,a=realloc(a n2*2)
,if( !EnumProcesses(a n2 &n) or n!n2 )
,,break
for i 0 n/4
,hProcess = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ 0 a[i] )
,if( !hProcess )
,,continue
,if( !EnumProcessModules(hProcess &hMod 4 &n2) )
,,continue
,sLong.fix(GetModuleFileNameEx(hProcess hMod sLong 256))
,;;s.fix(GetModuleFileNameEx(hProcess hMod sLong 256))
,realName = ""
,rget( realName, sLong, "Software\Microsoft\Windows\ShellNoRoam\MUICache" )
,s.fix(GetModuleBaseName(hProcess hMod s 256))
,;;s.getfilename(s)
,CloseHandle(hProcess)
,theWindowList = ""
,GetWindowList( &theWindowList, s, 1+4 )
,if( theWindowList != "" )
,,appList + s
,,;out s
,,;out theWindowList
,,if( realName != "" )
,,,realNameList + realName
,,else
,,,if( find( theWindowList, "[]" ) == -1 )
,,,,realNameList + theWindowList
,,,else
,,,,Substitute(&s, ".exe", "", 1)
,,,,realNameList + s
,,appList + "[]"
,,realNameList + "[]"
free a

if( appList.len == 0 )
,ret
realNameList.left(realNameList realNameList.len-2) ;; Remove the extra CR-LF at the end of the last line
listChoice = PopupMenu( realNameList 0 0 0 1)
if( listChoice != 0 )
,str chosenApp
,chosenApp.getl( appList, listChoice-1 )
,str appWindows
,GetWindowList( &appWindows, chosenApp, 1+4 )
,;out appWindows
,int foundCount
,for( foundCount, 0, 100 )
,,if( findl( appWindows, foundCount ) == -1 )
,,,break
,foundCount - 1
,;out "%i" foundCount
,rep( foundCount )
,,str winName
,,winName.getl( appWindows, foundCount-1 )
,,;out winName
,,act( win( winName "" chosenApp ) )
,,foundCount - 1
9: ) Lindsey Dubb
#2
Function GetFileVersionString extracts file description directly from exe. I tested it only with several programs, XP.

Code:
Copy      Help
;/
function# $file str&string [$infokind]

;Extracts string from version resource of exe or dll.
;infokind can be one of following strings (default is "FileDescription"):
;Comments InternalName ProductName CompanyName LegalCopyright ProductVersion FileDescription LegalTrademarks PrivateBuild FileVersion OriginalFilename SpecialBuild
;Returns 1 on success, 0 on failure.

;EXAMPLE
;str s
;if(GetFileVersionString("iexplore.exe" &s)) out s


dll# version GetFileVersionInfoSize $lptstrFilename *lpdwHandle
dll# version GetFileVersionInfo $lptstrFilename dwHandle dwLen !*lpData
dll# version VerQueryValue !*pBlock $lpSubBlock !**lplpBuffer *puLen

if(!infokind or !infokind[0]) infokind="FileDescription"

str file2.searchpath(file); if(!file2.len) end "file not found"
int i vis=GetFileVersionInfoSize(file2, &i); if(!vis) ret
str s.all(vis 2) ss; word* lc; lpstr ls
if(!GetFileVersionInfo(file2, i, vis, s)) ret
if(!VerQueryValue(s, "\VarFileInfo\Translation", &lc, &i) or !lc or !i) ret

ss.format("\StringFileInfo\%04x%04x\%s" lc[0] lc[1] infokind)
if(VerQueryValue(s, ss, &ls, &i)) goto return
;lc[0] has problems with some programs (Word, Excel)
ss.format("\StringFileInfo\0409%04x\%s" lc[1] infokind)
if(VerQueryValue(s, ss, &ls, &i)) goto return
ret
;return
string=ls
ret 1
#3
Thanks! Yes, that’s working reasonably well. A quick note for other people who use the routine — the goto label line
“;return”
only worked after it was changed to
“ return”
(Note the space before the word.)

So there are now four levels of the script’s logic to find the name.
- Try the mystery registry entry
- Try GetFileVersionString
- If the application has a single visible window, use its name
- Just use the executable name
9: ) Lindsey Dubb
#4
Gintaras:

This works wonderful, but must the entire path be included? I just tried using a different exe file and it didnt find it.

Thanks!
#5
If only filename is used, this will find only files that are in Windows, System, QM, My QM folders, folders specified in PATH environment variable, and folders specified in registry App Paths key.


Attached Files
.qml   xtreme activex.qml (Size: 4.35 KB / Downloads: 117)


Forum Jump:


Users browsing this thread: 1 Guest(s)