C++ 以编程方式检索 java.exe 路径

c++ programmatically retrieve java.exe path

我正在尝试检索 Windows 上的 java.exe 安装路径。然而,我至今无法成功。

我试过的是:

  1. getenv("JAVA_HOME"),在我看来很少设置(大部分 return 什么都没有,因为它没有设置?)
  2. CMD 命令 for %i in (java.exe) do @echo. %~$PATH:i,其中 return 是我在 cmd 中手动执行时的路径,但是我无法在 C++ 中以编程方式检索它? _popen return 当我执行这段代码时,我什么也没有,但是一个简单的 dir 语句 return 我得到了正确的输出(目录列表)。

所以,我只想检索 java.exe 所在的路径,这是我在应用程序中需要的。如果您有任何好的想法,请告诉我。我愿意解决这个问题。

string cmd(char *command) {
    FILE *fpipe;
    string response = "";
    char c = 0;
    if (0 == (fpipe = (FILE*)_popen(command, "r"))) {
        Exit("popen() failed.");
    }
    while (fread(&c, sizeof c, 1, fpipe)) {
        //printf("%c", c);
        response += c;
    }
    _pclose(fpipe);
    return response;
}
cout << cmd("for %i in (java.exe) do @echo. %~$PATH:i") << endl; //EMPTY (MANUAL ON CMD RETURNS THE RIGHT PATH)
cout << cmd("dir"); //RETURNS LIST OF CONTENTS

使用 JAVA_HOME 已被弃用一段时间,因此您使用的涉及该变量的任何解决方案都会严重老化。

如果 Java 是使用标准 Oracle 安装程序安装的,那么 %ProgramData%\Oracle\Java\javapath\java.exe 应该是当前启动器的 link。而且它是一个实际的 link,而不是 "Windows shortcut" 蹩脚的假 symlink-wannabe,因此您可以直接使用该路径名(无论如何,在检索 ProgramData 环境变量之后)。 javapath 部分是一些 NTFS hardlink/junction 魔术发生的地方,特别是这样它可以添加到 $PATH 而不是不断地更新 "Java/jre-X.Y.Z/bin" 和类似的。

如果 Java 是以其他方式安装的——例如,"Server JRE" 故意没有安装程序并且可以放置在任何你有写权限的地方——那么你需要搞砸使用 CMD 中的 $PATH 技巧。我不知道为什么 popen 不起作用,除了 Windows 再次做自己的事情而不是简单地遵循 POSIX 标准(这就是为什么我的办公室基本上放弃直接在 Windows).

如果您希望您的应用程序 运行 在各种机器上运行,您不能假定任何固定路径,并且通常不能假定已设置某些环境变量。用户几乎总是可以选择一个完全任意的安装位置。通常情况下,获取有关程序安装位置信息的唯一可靠方法是通过 Windows 注册表。甚至假设通过安装程序进行安装,该安装程序实际上将该信息写入注册表。

在 Win 注册表中查找 JRE 安装路径

对于 Oracle Java 运行时,您需要的所有信息都存储在注册表中,前提是它是使用自己的安装程序安装的。

相关注册表路径取决于 Java 的类型和 Windows 的类型。

64 位 Java 64 位 Windows 或 32 位 Java 32 位 Windows:

HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment

32 位 Java 64 位 Windows:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Runtime Environment

该密钥有一个条目 CurrentVersion,其中包含最新安装的版本号。它还具有许多子键,每个已安装的 Java Runtime 版本至少有一个。这些密钥有一个条目 JavaHome,其中包含顶级 Java 安装目录。我不太熟悉 Java,但我假设从该位置开始目录和文件布局是固定的,因此您可以假设 java.exe 可以总是在相对于 JavaHome.

的相同路径中找到

为了使这一点更清楚,假设您安装了 1.8.0_111 版作为最新版本。

  • 您的 CurrentVersion 条目将为“1.8”。
  • 该版本将有两个子密钥。

    ...\Java Runtime Environment.8
    ...\Java Runtime Environment.8.0_111
    
  • 两个子键都会有一个JavaHome入口指向安装目录,例如:“C:\Program Files ( x86)\Java\jre1.8.0_111”.

使用 C++ 访问注册表

您可以直接使用WinAPI。对于您查询一些甚至可能是合理的键的简单任务。还有一大堆包装 WinAPI 的库,为您提供更像 C++ 的 WinAPI 注册表函数接口。我没用过,所以不推荐。