Minecraft(我的世界)中文论坛

 找回密码
 注册(register)

!header_login!

只需一步,立刻登录

查看: 831|回复: 2

[软件开发讨论] 关于注册表判断JAVA信息的最优解

[复制链接]
nsisogf 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
3492
钻石
性别
保密
注册时间
2015-5-24
查看详细资料
发表于 2018-8-22 09:50:58 | 显示全部楼层 |阅读模式

您尚未登录,立即登录享受更好的浏览体验!

您需要 登录 才可以下载或查看,没有帐号?注册(register)

x
在以前的贴中(http://www.mcbbs.net/thread-704797-1-1.html
我曾以注册表+命令行的方法获取java位数,版本信息
事实是这种方式是效率及其低,并且最不稳定的方式
一旦返回的内容修改,那么这种方法需要重新进行修改进行匹配

先略谈下JAVA注册表机制(以JRE进行说明,JDK略特殊不进行说明)
在安装JAVA后,JAVA会在注册表中写入相关信息
节点位于
LOCALMACHINE
|-SOFTWARE
    |-JavaSoft
        |-Java Runtime Environment(新版本为JRE)
在此节点中,所有子节点的名称即为一个JRE的版本
但是我个人发现,安装一个版本会写入两个子节点,比如1.8和1.8.x.xx,应该取最长的那个作为版本号
所以判断字符串的长度是否大于3即可

接下来进入该子节点,获取其中JavaHome的值,既是JRE主路径
但是由于启动mc需要的是可执行文件路径,所以在后面加上\bin\javaw.exe即可

关键是,如何获取位数?
这个需要你们动动脑筋咯
先整理下逻辑,x86平台上只能装x86的JAVA,所以在x86系统上无论查找到什么JAVA,都应该是x86的
x64平台上有两种可能,一种是32位的,另一种是64位的
在64位系统上,注册表有这么一个机制
在默认视图下,SOFTWARE里面还有一个Wow6432Node节点
这个节点是供64位操作表中提供对32位注册表的支持
也就是说64位注册表中32位应用写入的注册表在这个节点中
所以我们就很灵活的能在64位平台上判断JAVA位数了

接下来提供C#代码
先定义JAVA信息类
  1. public class Java
  2.     {
  3.         /// <summary>
  4.         /// JAVA路径
  5.         /// </summary>
  6.         public string Path { get; private set; }
  7.         /// <summary>
  8.         /// JAVA版本
  9.         /// </summary>
  10.         public string Version { get; private set; }
  11.         /// <summary>
  12.         /// java位数
  13.         /// </summary>
  14.         public ArchEnum Arch { get; private set; }
  15.         public Java(string path, string version, ArchEnum arch)
  16.         {
  17.             this.Path = path;
  18.             this.Version = version;
  19.             this.Arch = arch;
  20.         }
复制代码


SOFTWARE节点下操作方法:
  1. public static Dictionary<string,string> GetJavaRegisterPath(RegistryKey key)
  2.         {
  3.             Dictionary<string, string> jres = new Dictionary<string, string>();
  4.             var oldKey = key?.OpenSubKey("JavaSoft")?.OpenSubKey("Java Runtime Environment");
  5.             var newKey = key?.OpenSubKey("JavaSoft")?.OpenSubKey("JRE");
  6.             //oldJre
  7.             if (oldKey != null)
  8.             {
  9.                 foreach (var verStr in oldKey.GetSubKeyNames())
  10.                 {
  11.                     if (verStr.Length > 3)
  12.                     {
  13.                         string path = oldKey.OpenSubKey(verStr).GetValue("JavaHome")?.ToString() + @"\bin\javaw.exe";
  14.                         if (File.Exists(path))
  15.                         {
  16.                             jres.Add(verStr, path);
  17.                         }
  18.                     }
  19.                 }
  20.             }
  21.             //newJre
  22.             if (newKey != null)
  23.             {
  24.                 foreach (var verStr in newKey.GetSubKeyNames())
  25.                 {
  26.                     if (verStr.Length > 3)
  27.                     {
  28.                         string path = newKey.OpenSubKey(verStr).GetValue("JavaHome")?.ToString() + @"\bin\javaw.exe";
  29.                         if (File.Exists(path))
  30.                         {
  31.                             jres.Add(verStr, path);
  32.                         }
  33.                     }
  34.                 }
  35.             }
  36.             return jres;
  37.         }
复制代码


全局方法:
  1. /// <summary>
  2.         /// 从注册表寻找本机JAVA列表
  3.         /// </summary>
  4.         /// <returns></returns>
  5.         public static List<Java> GetJavaList()
  6.         {
  7.             List<Java> javas = new List<Java>();
  8.             RegistryKey localMachine = Registry.LocalMachine.OpenSubKey("SOFTWARE");
  9.             switch (SystemTools.GetSystemArch())
  10.             {
  11.                 case ArchEnum.x32:
  12.                     var jres = GetJavaRegisterPath(localMachine);
  13.                     javas.AddRange(jres.Select(x => new Java(x.Value, x.Key, ArchEnum.x32)));
  14.                     break;
  15.                 case ArchEnum.x64:
  16.                     var jres64 = GetJavaRegisterPath(localMachine);
  17.                     javas.AddRange(jres64.Select(x => new Java(x.Value, x.Key, ArchEnum.x64)));
  18.                     var jres32 = GetJavaRegisterPath(localMachine.OpenSubKey("Wow6432Node"));
  19.                     javas.AddRange(jres32.Select(x => new Java(x.Value, x.Key, ArchEnum.x32)));
  20.                     break;
  21.             }
  22.             return javas;
  23.         }
复制代码


。—。 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
12584
钻石
性别
保密
注册时间
2012-12-16
查看详细资料
发表于 2018-8-22 10:19:00 | 显示全部楼层
Oracle应该把写过的注册表项整理出一个文档来的……
回复

使用道具 举报

gamerteam 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
17263
钻石
性别
保密
注册时间
2014-3-7
查看详细资料
发表于 2018-8-22 11:59:06 | 显示全部楼层
然后遇到绿色版的Java……完蛋
如果你要允许用户自己自定义Java位置的话,我还是建议写一个Java程序进行检测,而且这个效率也低不到哪里去(我就不信他电脑装几十个Java!哼唧!)

评分

参与人数 2金粒 +2 收起 理由
海螺螺 + 1 萝莉球
gooding300 + 1 大师球

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册(register)

本版积分规则

Archiver|小黑屋|Mcbbs.net ( 京ICP备15023768号-1 ) | 京公网安备 11010502037624号 | 手机版

GMT+8, 2020-2-19 00:07 , Processed in 0.041769 second(s), Total 11, Slave 10 queries, Release: Build.2020.01.19.1840, Gzip On, MemCached On.

"Minecraft"以及"我的世界"为Mojang Synergies AB的商标 本站与Mojang以及微软公司没有从属关系

© 2010-2020 我的世界中文论坛 版权所有 本站原创图文内容版权属于原创作者,未经许可不得转载

快速回复 返回顶部 返回列表