I've written the below which uses winapps
as suggested in my previous answer. This implementation has many limitations, such as it only works for programs installed for all users. However, you could alter this code to use another way of getting the install location and use getPossibleExePaths
to get the executables. This answer gives some alternative ways which may be better than winapps
.
import os
import winapps
import subprocess
def getPossibleExePaths(appPath):
if not appPath:
raise Exception("App Path cannot be None")
pattern = appPath + ":*exe"
try:
returned = subprocess.check_output(['where', pattern]).decode('utf-8')
listOfPaths = filter(None, returned.split(os.linesep))
return [i.strip() for i in list(listOfPaths)]
except subprocess.CalledProcessError as e:
raise Exception(f"Error getting path for '{appPath}'")
def getAppPath(appName):
for app in winapps.search_installed(appName):
installPath = str(app.install_location)
if installPath and installPath != "None":
return installPath
return None
if __name__ == '__main__':
print(getPossibleExePaths(getAppPath('Chrome')))
This code utilises Window's where
command so this will not work cross-platform.
However, please note that getPossibleExePaths
will return a list of executable paths and not necessarily the executable that will launch the process. You'll need to figure out how your program will deal with that, there's no easy way to separate out an uninstaller.exe
from launchApp.exe
. You could, of course, match up the uninstall location that winapps
provides and exclude it from the returned list but that doesn't solve the issue that it might not be the launch executable.
I hope that helps you