Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the full path to the Mercurial executable, when Windows is able to locate it?

To clarify: The question is really: How do I locate the Mercurial command line client. If the answer is applicable to any executable, so much the better, but I'm really interested in the hg.exe executable file.

If I know the name of an executable, say hg.exe, the Mercurial command line client, and Windows knows where it is because I can execute just hg log from a command prompt and it executes, what steps are involved in order for me to find that executable myself, in the same manner that the command prompt and Windows does it?

Basically, if Windows is able to locate it, I want my program to be able to locate it.

Is there a WinAPI function, or similar? The code will run in .NET, written in C#, so if there's anything built into .NET for this that would be the preferred solution, but otherwise I'm not adverse to using P/Invoke for this.

I've seen one potential duplicate of this question: c# Check if an executable exists in the windows path, but is that all there is to it? Just iterate over the contents of the PATH environment variable and looking in each of those directories for the executable?

I have a vague notion that that's just one of the steps involved, and possibly that there are registry overrides that Windows can use that I should be aware of, so I'll post the question here.

If, on the other hand, there really is just the PATH variable in play here, it can probably safely be closed as a duplicate.

like image 727
Lasse V. Karlsen Avatar asked Nov 09 '10 22:11

Lasse V. Karlsen


4 Answers

you can cheat and use the where.exe command

public GetFullPath(string program)
{
    string result;

    Process myProcess = new Process()
    {
        UseShellExecute = false,
        RedirectStandardOutput = true,
        StartInfo = new ProcessStartInfo(@"%SYSTEMDIR%\where.exe" )
    };

    using (StreamReader sr = myProcess.StandardOutput)
    {
        myProcess.Start();
        result = myStreamReader.ReadLine();
        myProcess.Close();
    }

    return result;
}
like image 143
Greg Buehler Avatar answered Nov 14 '22 20:11

Greg Buehler


It depends on how the program is registered with the system. Since hg is generally run from either tools or the command line, it's not going to be registered with the system. If it were there's a set of registry keys that has the exe name and path. Otherwise, you just iter the path from the first entry to the last till you find the file you need. First one found on the path wins.

Examples of such a "registered" program, excel or winword.

EDIT:

@BillyONeal makes a good point below, that only works for "run" command programs, but my point was there was a second place to look.

Additionally, for those who haven't seen this, here's the install procedures:

An alternative scheme that works better for some is to search for hg on the PATH

like image 3
jcolebrand Avatar answered Nov 14 '22 20:11

jcolebrand


Executables load according to the first matching instance in the system path. If executed from a shortcut or other mode that uses an absolute path, of course that's the version that runs, though.

DLLs are a bit more complicated - for native DLLs there are overrides, perhaps that's what you are thinking about? See here.

like image 2
Steve Townsend Avatar answered Nov 14 '22 20:11

Steve Townsend


Windows provides the SearchPath function. If you pass NULL as the lpPath parameter, it uses the system search path. In your case you should call:

SearchPath(NULL, "hg", NULL, ...)

The C# declaration is:

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern int SearchPath(string path, string fileName, string extension, int numBufferChars, StringBuilder buffer, int[] filePart);
like image 2
Michael Avatar answered Nov 14 '22 21:11

Michael