potisanのプログラミングメモ

プログラミング素人です。昔の自分を育ててくれたネット情報に少しでも貢献できるよう、情報を貯めていこうと思っています。Windows環境のC++やC#がメインです。

C# 4.5 レジストリに登録されたJavaのバージョン情報とパスを取得する

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Win32;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            var javaInstallInfo = new JavaInstallationInfo();

            Console.WriteLine("JDK CurrentVersions");
            Console.WriteLine(string.Join("\r\n",
                javaInstallInfo.QueryJDKCurrentVersions().Select(
                    pair => pair.Key + ": " + pair.Value)));
            Console.WriteLine();

            Console.WriteLine("JRE CurrentVersions");
            Console.WriteLine(string.Join("\r\n",
                javaInstallInfo.QueryJRECurrentVersions().Select(
                    pair => pair.Key + ": " + pair.Value)));
            Console.WriteLine();

            Console.WriteLine("JRE BrowserJavaVersion");
            Console.WriteLine(string.Join("\r\n",
                javaInstallInfo.QueryJREBrowserJavaVersions().Select(
                    pair => pair.Key + ": " + pair.Value)));
            Console.WriteLine();

            Console.WriteLine("JDK HomePath for each environment");
            Console.WriteLine(string.Join("\r\n",
                javaInstallInfo.QueryJDKCurrentVersionHomePaths().Select(
                    pair => pair.Key + ": " + pair.Value)));
            Console.WriteLine();

            Console.WriteLine("JRE HomePath for each environment");
            Console.WriteLine(string.Join("\r\n",
                javaInstallInfo.QueryJRECurrentVersionHomePaths().Select(
                    pair => pair.Key + ": " + pair.Value)));
            Console.WriteLine();

            Console.WriteLine("JRE BrowserJava HomePath for each environment");
            Console.WriteLine(string.Join("\r\n",
                javaInstallInfo.QueryJREBrowserJavaVersionHomePaths().Select(
                    pair => pair.Key + ": " + pair.Value)));
            Console.WriteLine();

            Console.ReadKey();
        }
    }

    /// <summary>
    /// RegistryViewに関する追加機能を提供します。
    /// </summary>
    public static partial class RegistryViewUtility
    {
        /// <summary>
        /// 各RegistryViewに対応するキーが存在するかどうかを確認します。
        /// </summary>
        public static Dictionary<RegistryView, bool> QueryKeyExists(
            RegistryView[] views,
            RegistryHive hive,
            string name)
        {
            var result = new Dictionary<RegistryView, bool>();
            foreach (var view in views)
            {
                using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
                {
                    using (var key = baseKey.OpenSubKey(name))
                    {
                        result.Add(view, key != null);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 各RegistryViewに対応するキーの値を取得します。
        /// </summary>
        public static Dictionary<RegistryView, T> QueryKeyValues<T>(
            RegistryView[] views,
            RegistryHive hive,
            string name,
            string value,
            object defaultValue)
        {
            var result = new Dictionary<RegistryView, T>();
            foreach (var view in views)
            {
                using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
                {
                    using (var key = baseKey.OpenSubKey(name))
                    {
                        result.Add(view, (T)((key != null)
                            ? key.GetValue(value, defaultValue) : defaultValue));
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 各RegistryViewとキー名のセットに対応するキーの値を取得します。
        /// </summary>
        public static Dictionary<RegistryView, T> QueryViewKeyNamePairValues<T>(
            Dictionary<RegistryView, string> viewKeyNames,
            RegistryHive hive,
            string value,
            object defaultValue)
        {
            var result = new Dictionary<RegistryView, T>();
            foreach (var viewKeyName in viewKeyNames)
            {
                using (var baseKey = RegistryKey.OpenBaseKey(hive, viewKeyName.Key))
                {
                    using (var key = baseKey.OpenSubKey(viewKeyName.Value))
                    {
                        result.Add(viewKeyName.Key, (T)((key != null)
                            ? key.GetValue(value, defaultValue) : defaultValue));
                    }
                }
            }
            return result;
        }
    }

    /// <summary>
    /// Javaのインストール情報を取得する機能を提供します。
    /// </summary>
    public sealed class JavaInstallationInfo
    {
        public JavaInstallationInfo()
        {
            if (Environment.Is64BitProcess)
            {
                this.RegistryViews = new RegistryView[] {
                    RegistryView.Registry64,
                    RegistryView.Default,
                    RegistryView.Registry32};
            }
            else
            {
                this.RegistryViews = new RegistryView[] {
                    RegistryView.Registry32,
                    RegistryView.Default,
                    RegistryView.Registry64};
            }
        }

        public JavaInstallationInfo(RegistryView[] registryViews)
        {
            this.RegistryViews = registryViews;
        }

        public const string JavaSoftKeyName = @"Software\JavaSoft";
        public const string JDKKeyName = @"Software\JavaSoft\Java Development Kit";
        public const string JREKeyName = @"Software\JavaSoft\Java Runtime Environment";
        public const string JavaPluginKeyName = @"Software\JavaSoft\Java Plug-in";

        /// <summary>
        /// 各RegistryViewに対してJavaSoftキーが登録されているかどうかを確認します。
        /// </summary>
        public Dictionary<RegistryView, bool> QueryJavaSoftKeyExists()
        {
            return RegistryViewUtility.QueryKeyExists(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JavaSoftKeyName);
        }

        /// <summary>
        /// 各RegistryViewに対してJDKキーが登録されているかどうかを確認します。
        /// </summary>
        public Dictionary<RegistryView, bool> QueryJDKKeyExists()
        {
            return RegistryViewUtility.QueryKeyExists(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JDKKeyName);
        }

        /// <summary>
        /// 各RegistryViewに対してJREキーが登録されているかどうかを確認します。
        /// </summary>
        public Dictionary<RegistryView, bool> QueryJREKeyExists()
        {
            return RegistryViewUtility.QueryKeyExists(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JREKeyName);
        }

        public Dictionary<RegistryView, string> QueryJDKCurrentVersions()
        {
            return RegistryViewUtility.QueryKeyValues<string>(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JDKKeyName,
                "CurrentVersion",
                null);
        }

        public Dictionary<RegistryView, string> QueryJRECurrentVersions()
        {
            return RegistryViewUtility.QueryKeyValues<string>(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JREKeyName,
                "CurrentVersion",
                null);
        }

        public Dictionary<RegistryView, string> QueryJREBrowserJavaVersions()
        {
            return RegistryViewUtility.QueryKeyValues<string>(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JREKeyName,
                "BrowserJavaVersion",
                null);
        }

        public Dictionary<RegistryView, string> QueryJDKCurrentVersionHomePaths()
        {
            var pairs = RegistryViewUtility.QueryKeyValues<string>(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JDKKeyName,
                "CurrentVersion",
                null);
            pairs = pairs.Keys.ToDictionary(
                view => view,
                view => JDKKeyName + "\\" + pairs[view]);
            return RegistryViewUtility.QueryViewKeyNamePairValues<string>(
                pairs, RegistryHive.LocalMachine, "JavaHome", null);
        }

        public Dictionary<RegistryView, string> QueryJRECurrentVersionHomePaths()
        {
            var pairs = RegistryViewUtility.QueryKeyValues<string>(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JREKeyName,
                "CurrentVersion",
                null);
            pairs = pairs.Keys.ToDictionary(
                view => view,
                view => JREKeyName + "\\" + pairs[view]);
            return RegistryViewUtility.QueryViewKeyNamePairValues<string>(
                pairs, RegistryHive.LocalMachine, "JavaHome", null);
        }

        public Dictionary<RegistryView, string> QueryJREBrowserJavaVersionHomePaths()
        {
            var pairs = RegistryViewUtility.QueryKeyValues<string>(
                this.RegistryViews,
                RegistryHive.LocalMachine,
                JREKeyName,
                "BrowserJavaVersion",
                null);
            pairs = pairs.Keys.ToDictionary(
                view => view,
                view => JavaPluginKeyName + "\\" + pairs[view]);
            return RegistryViewUtility.QueryViewKeyNamePairValues<string>(
                pairs, RegistryHive.LocalMachine, "JavaHome", null);
        }

        public RegistryView[] RegistryViews { get; set; }
    }
}

2021/3/10:この記事は別のブログで投稿した記事を移動したものです。