7

I want to find a .exe files path programatically in Java, for example:

  • Skype.exe is entered into a program to find the direct path to it
  • Program does an algorithm that finds the file path
  • Program returns the file path C:\Users\Public\Desktop\Skype.exe

A method I have tried is sorting through the systems files until "skype.exe" is found, but that takes up a lot of time and resources.

Is there any hack that could make it almost instant, like maybe a Win_Api function/cmd command or is sorting through the file system until the program is found the only way?

Mitch Zinck
  • 312
  • 3
  • 11
  • 1
    Prioritizing common locations of executables might help speed this up on the average system. Other than that I have nothing. – DeathByTensors Dec 16 '13 at 23:33
  • The only way I can think of this being done in a timely fashion is use [Jawin](http://jawinproject.sourceforge.net/) to interface with Windows libraries and then implement something akin to the "Start Menu" search feature that operates on recently accessed files and short-cuts present in `C:\ProgramData\Microsoft\Windows\Start Menu\Programs`. Might even be able to do so with using Windows libraries. More research is necessary of course. – Taylor Hx Dec 17 '13 at 01:34
  • Are looking for any `exe` files, or would a solution that very quickly finds "installed" `exe` files suffice? – Taylor Hx Dec 17 '13 at 04:12
  • That could actually work, going through installed exe's – Mitch Zinck Dec 17 '13 at 22:00
  • 1
    Start looking in the PATH. – Thorbjørn Ravn Andersen Feb 02 '14 at 19:35

3 Answers3

2

I actually found something that works, albeit not the fastest but only takes around 100ms - 500ms to do depending on the exe.

You need to use a runtime process to do this.

Basically you go into the root of your drive, and then search the filesystem using these commands in the cmd.

cd \
dir /s /b mytool.exe

This will return the filepath.

My code for it:

(Hackish I know)

try {
        Process p = Runtime.getRuntime().exec("./res/getPrograms.bat " + exeName);
        BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while(true) {
            line = input.readLine();
            if(line == null) {
                break;
            }
            System.out.println(line);
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

And the .bat file (I am passing the parameter "eclipse.exe" to the bat file which is represented as %1):

cd \
dir /s /b %1
exit

The output becomes:

C:\Users\Mitchell\workspace\Remote Admin>cd \ 

C:\>dir /s /b eclipse.exe 
C:\eclipse\eclipse.exe
Mitch Zinck
  • 312
  • 3
  • 11
1

As an extension to @Minor's answer, if you wanted to increase performance by limiting search to only programs that are currently "installed" on Windows, the following registry keys contain information on "installed" programs.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

Using powershell, you can access properties of installed software stored in these keys. Of particular interest is the InstallLocation property.

Then, you just modify your Java code to utilise another batch script that retrieves these install locations, and specifically target these install locations for exe files.

getInstalledPrograms.bat

@echo off
powershell -Command "Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object {$_.DisplayName -match \"%1\"} | Select-Object -Property InstallLocation"
exit

getPrograms.bat

@echo off
cd %1
dir /b /s "*%2*.exe"
exit

Java Example:

String search = "skype";
try {
    Process getInstalled = Runtime.getRuntime().exec("./src/getInstalledPrograms.bat " + search);
    BufferedReader installed = new BufferedReader(new InputStreamReader(getInstalled.getInputStream()));
    String install;
    String exe;
    int count = 0;
    while(true) {
        install = installed.readLine();
        if(install == null) {
            break;
        }
        install = install.trim();
        // Ignore powershell table header and newlines.
        if(count < 3 || install.equals("")) {
            count++;
            continue;
        }
        Process getExes = Runtime.getRuntime().exec("./src/getPrograms.bat " + "\"" + install + "\"");
        BufferedReader exes = new BufferedReader(new InputStreamReader(getExes.getInputStream()));
        while(true) {
            exe = exes.readLine();
            if(exe == null) {
                break;
            }
            exe = exe.trim();
            System.out.println(exe);
        }
    }

} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Currently my Java example duplicates InstallLocation returned by getInstalledPrograms.bat, although the script works fine in cmd. Conceptually though, this solution is sound.

JonP
  • 627
  • 6
  • 13
Taylor Hx
  • 2,815
  • 23
  • 36
0

If you want to know WHICH executable is being executed from the command line when you type . Use the which/where commands..

Unix/linux/Mac OSX Possix <which>

which chmod which cd which ls which myprogram

returns returns nothing if no such program file exists.

for Windows use where <where> /? for help on this command

If you don't have an executable but an alias or some sort of environment function/procedure/shell command.. use the <type> command on Unix/linux/Mac OS X. That will tell yo if you are dealing with an alias, environment function, or executable.

JMS
  • 181
  • 2
  • 6