public IRegistryKey CreateKey(string keyPath, RegistryKeyPermissionCheck permissionCheck = default) { IRegistryKey cleanUpKey = null; if (!keyPath.Contains(RegistryPathDelimiter)) { throw new ArgumentException("Can not create a root key itself", nameof(keyPath)); } try { IRegistryKey root = GetCorrespondingRoot(keyPath); string openKeyName = keyPath.MustEndWith(RegistryPathDelimiter).Remove(root.Name.MustEndWith(RegistryPathDelimiter)); cleanUpKey = root; if (openKeyName.IsNullOrWhitespace()) { throw new ArgumentException("Can not create a root key itself", nameof(keyPath)); } IRegistryKey key = root.CreateSubKey(openKeyName, permissionCheck); return(key); } finally { cleanUpKey?.Dispose(); } }
public IRegistryKey OpenKey(string keyPath, RegistryKeyPermissionCheck permissionCheck = default, RegistryRights rights = default) { IRegistryKey cleanUpKey = null; try { IRegistryKey root = GetCorrespondingRoot(keyPath); string openKeyName = keyPath.MustEndWith(RegistryPathDelimiter).Remove(root.Name.MustEndWith(RegistryPathDelimiter)); if (openKeyName.IsNullOrWhitespace()) { return(root); } cleanUpKey = root; IRegistryKey key = root.OpenSubKey(openKeyName, permissionCheck, rights); return(key); } finally { cleanUpKey?.Dispose(); } }
/// <summary> /// Tries to obtaining the path to the latest version of the SQL LocalDB /// native API DLL for the currently executing process. /// </summary> /// <param name="fileName"> /// When the method returns, contains the path to the SQL Local DB API /// to use, if found; otherwise <see langword="null"/>. /// </param> /// <returns> /// <see langword="true"/> if the native API path was successfully found; /// otherwise <see langword="false"/>. /// </returns> internal bool TryGetLocalDbApiPath(out string fileName) { fileName = null; string keyName = DeriveLocalDbRegistryKey(); IRegistryKey key = Registry.OpenSubKey(keyName); if (key == null) { Logger.RegistryKeyNotFound(keyName); return(false); } Version latestVersion = null; Version overrideVersion = null; string path = null; try { // Is there a setting overriding the version to load? string overrideVersionString = ApiVersion; foreach (string versionString in key.GetSubKeyNames()) { if (!Version.TryParse(versionString, out Version version)) { Logger.InvalidRegistryKey(versionString); continue; } if (!string.IsNullOrEmpty(overrideVersionString) && overrideVersion == null && string.Equals(versionString, overrideVersionString, StringComparison.OrdinalIgnoreCase)) { Logger.NativeApiVersionOverriddenByUser(version); overrideVersion = version; } if (latestVersion == null || latestVersion < version) { latestVersion = version; } } if (!string.IsNullOrEmpty(overrideVersionString) && overrideVersion == null) { Logger.NativeApiVersionOverrideNotFound(overrideVersionString); } Version versionToUse = overrideVersion ?? latestVersion; if (versionToUse != null) { using (IRegistryKey subkey = key.OpenSubKey(versionToUse.ToString())) { path = subkey.GetValue("InstanceAPIPath"); } NativeApiVersion = versionToUse; } } finally { key.Dispose(); } if (string.IsNullOrEmpty(path)) { Logger.NativeApiNotFound(); return(false); } if (!File.Exists(path)) { Logger.NativeApiLibraryNotFound(path); return(false); } fileName = Path.GetFullPath(path); return(true); }
/// <summary> /// Tries to obtaining the path to the latest version of the SQL LocalDB /// native API DLL for the currently executing process. /// </summary> /// <param name="fileName"> /// When the method returns, contains the path to the SQL Local DB API /// to use, if found; otherwise <see langword="null"/>. /// </param> /// <returns> /// <see langword="true"/> if the native API path was successfully found; /// otherwise <see langword="false"/>. /// </returns> internal static bool TryGetLocalDbApiPath(out string fileName) { fileName = null; bool isWow64Process = Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess; // Open the appropriate Registry key if running as a 32-bit process on a 64-bit machine string keyName = string.Format( CultureInfo.InvariantCulture, @"SOFTWARE\{0}Microsoft\Microsoft SQL Server Local DB\Installed Versions", isWow64Process ? @"Wow6432Node\" : string.Empty); IRegistryKey key = Registry.OpenSubKey(keyName); if (key == null) { Logger.Warning(Logger.TraceEvent.RegistryKeyNotFound, SR.NativeMethods_RegistryKeyNotFoundFormat, keyName); return(false); } Version latestVersion = null; Version overrideVersion = null; string path = null; try { // Is there a setting overriding the version to load? string overrideVersionString = SqlLocalDbConfig.NativeApiOverrideVersionString; foreach (string versionString in key.GetSubKeyNames()) { Version version; try { version = new Version(versionString); } catch (ArgumentException) { Logger.Warning(Logger.TraceEvent.InvalidRegistryKey, SR.NativeMethods_InvalidRegistryKeyNameFormat, versionString); continue; } catch (FormatException) { Logger.Warning(Logger.TraceEvent.InvalidRegistryKey, SR.NativeMethods_InvalidRegistryKeyNameFormat, versionString); continue; } catch (OverflowException) { Logger.Warning(Logger.TraceEvent.InvalidRegistryKey, SR.NativeMethods_InvalidRegistryKeyNameFormat, versionString); continue; } if (!string.IsNullOrEmpty(overrideVersionString) && overrideVersion == null && string.Equals(versionString, overrideVersionString, StringComparison.OrdinalIgnoreCase)) { Logger.Verbose(Logger.TraceEvent.NativeApiVersionOverriddenByUser, SR.NativeMethods_ApiVersionOverriddenByUserFormat, version); overrideVersion = version; } if (latestVersion == null || latestVersion < version) { latestVersion = version; } } if (!string.IsNullOrEmpty(overrideVersionString) && overrideVersion == null) { Logger.Warning( Logger.TraceEvent.NativeApiVersionOverrideNotFound, SR.NativeMethods_OverrideVersionNotFoundFormat, overrideVersionString, Environment.MachineName, latestVersion); } Version versionToUse = overrideVersion ?? latestVersion; if (versionToUse != null) { using (var subkey = key.OpenSubKey(versionToUse.ToString())) { path = subkey.GetValue("InstanceAPIPath"); } NativeApiVersion = versionToUse; } } finally { key.Dispose(); } if (string.IsNullOrEmpty(path)) { Logger.Warning(Logger.TraceEvent.NoNativeApiFound, SR.NativeMethods_NoNativeApiFound); return(false); } if (!File.Exists(path)) { Logger.Error(Logger.TraceEvent.NativeApiPathNotFound, SR.NativeMethods_NativeApiNotFoundFormat, path); return(false); } fileName = Path.GetFullPath(path); return(true); }