问题 当Windows能够找到它时,如何找到Mercurial可执行文件的完整路径?


澄清:问题是: 如何找到Mercurial命令行客户端。如果答案适用于任何可执行文件,那就更好了,但我真的很感兴趣 hg.exe 可执行文件。

如果我知道可执行文件的名称,请说 hg.exe,Mercurial命令行客户端,Windows知道它在哪里,因为我可以执行 hg log 从命令提示符执行,我自己找到可执行文件涉及哪些步骤,就像命令提示符和Windows一样?

基本上,如果Windows能够找到它,我希望我的程序能够找到它。

是否有WinAPI功能或类似功能?代码将在.NET中运行,用C#编写,所以如果.NET内置了任何内容,那么这将是首选的解决方案,但除此之外,我并不反对使用P / Invoke。

我已经看到了这个问题的一个潜在重复: c#检查Windows路径中是否存在可执行文件,但这就是它的全部吗?只是迭代的内容 PATH 环境变量并在每个目录中查找可执行文件?

我有一个模糊的概念,那只是所涉及的步骤之一,并且可能存在Windows可以使用的注册表覆盖,我应该知道,所以我将在此处发布问题。

另一方面,如果这里只有PATH变量,它可以安全地作为副本关闭。


8426
2017-11-09 22:25


起源



答案:


这取决于程序在系统中的注册方式。由于hg通常从任一工具或命令行运行,因此不会在系统中注册。如果它是一组具有exe名称和路径的注册表项。否则,您只需查看从第一个条目到最后一个条目的路径,直到找到所需的文件为止。在路径上找到的第一个获胜。

这种“注册”程序,excel或winword的示例。

编辑:

@BillyONeal在下面提出了一个很好的观点,它只适用于“运行”命令程序,但我的观点是有第二个看的地方。

另外,对于那些没有看过这个的人来说,这里是 安装程序

对某些人更有效的替代方案是在PATH上搜索hg


3
2017-11-09 22:33



好的,那就是我要做的。无论如何,代码都不是一成不变的,所以如果我以后发现更多,我总是可以改变它。 PATH方法现在可以很好地运行在我测试它的机器上,所以我暂时坚持使用它。谢谢。 - Lasse Vågsæther Karlsen
不完全的。 “注册”(或更确切地说,App Paths注册表项)仅在使用ShellExecute启动进程时使用(由“运行...”执行),而不是由CreateProcess启动(由命令处理器完成) - Billy ONeal
@BillyOneal很好,但我打算从hg小组发布关于它如何取决于%PATH%的URL。 - jcolebrand
因为看起来HG.exe应该总是在PATH中,根据文档(我现在已经找到了几个引用),我会接受这个答案。 - Lasse Vågsæther Karlsen
这就是我最终的结果: bitbucket.org/lassevk/mercurial.net/src/728f85d67447/... - Lasse Vågsæther Karlsen


答案:


这取决于程序在系统中的注册方式。由于hg通常从任一工具或命令行运行,因此不会在系统中注册。如果它是一组具有exe名称和路径的注册表项。否则,您只需查看从第一个条目到最后一个条目的路径,直到找到所需的文件为止。在路径上找到的第一个获胜。

这种“注册”程序,excel或winword的示例。

编辑:

@BillyONeal在下面提出了一个很好的观点,它只适用于“运行”命令程序,但我的观点是有第二个看的地方。

另外,对于那些没有看过这个的人来说,这里是 安装程序

对某些人更有效的替代方案是在PATH上搜索hg


3
2017-11-09 22:33



好的,那就是我要做的。无论如何,代码都不是一成不变的,所以如果我以后发现更多,我总是可以改变它。 PATH方法现在可以很好地运行在我测试它的机器上,所以我暂时坚持使用它。谢谢。 - Lasse Vågsæther Karlsen
不完全的。 “注册”(或更确切地说,App Paths注册表项)仅在使用ShellExecute启动进程时使用(由“运行...”执行),而不是由CreateProcess启动(由命令处理器完成) - Billy ONeal
@BillyOneal很好,但我打算从hg小组发布关于它如何取决于%PATH%的URL。 - jcolebrand
因为看起来HG.exe应该总是在PATH中,根据文档(我现在已经找到了几个引用),我会接受这个答案。 - Lasse Vågsæther Karlsen
这就是我最终的结果: bitbucket.org/lassevk/mercurial.net/src/728f85d67447/... - Lasse Vågsæther Karlsen


你可以欺骗和使用 where.exe 命令

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;
}

5
2017-11-09 22:37



他特意说他试图避开where命令 - jcolebrand
@drachenstern在SO聊天,但不在问题本身。 - Greg Buehler
:p~呀呀呀 - jcolebrand


可执行文件根据系统路径中的第一个匹配实例加载。如果从使用绝对路径的快捷方式或其他模式执行,当然这是运行的版本。

DLL有点复杂 - 对于本机DLL有覆盖,也许这就是你在想什么?看到 这里


2
2017-11-09 22:34



不,他正在使用hg(m​​ercurial),因此DLL不起作用。 - jcolebrand
@drachenstern - 只是试着说出问题中所说的含糊不清的概念。 - Steve Townsend
〜够了。对于dll,我不会试图看看路径,甚至是否有效?系统路径是,手动查看%path%tho? - jcolebrand


Windows提供了 SearchPath 功能。如果你通过 NULL 作为 lpPath 参数,它使用系统搜索路径。在你的情况下,你应该致电:

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

C#声明是:

[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);

1
2017-11-10 13:37