potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

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:この記事は別のブログで投稿した記事を移動したものです。