+}
diff --git a/samples/TodoApp/Views/Shared/_Layout.cshtml b/samples/TodoApp/Views/Shared/_Layout.cshtml
new file mode 100644
index 00000000..5fab3c78
--- /dev/null
+++ b/samples/TodoApp/Views/Shared/_Layout.cshtml
@@ -0,0 +1,39 @@
+
+
+
+
+
+ @ViewData["Title"] - TodoApp
+
+
+
+
+
+
+ @RenderBody()
+
+
+
+
+
+
+
+ @RenderSection("Scripts", required: false)
+
+
diff --git a/samples/TodoApp/Views/_ViewImports.cshtml b/samples/TodoApp/Views/_ViewImports.cshtml
new file mode 100644
index 00000000..652222cc
--- /dev/null
+++ b/samples/TodoApp/Views/_ViewImports.cshtml
@@ -0,0 +1,3 @@
+@using TodoApp
+@using TodoApp.Models
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/samples/TodoApp/Views/_ViewStart.cshtml b/samples/TodoApp/Views/_ViewStart.cshtml
new file mode 100644
index 00000000..a5f10045
--- /dev/null
+++ b/samples/TodoApp/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "_Layout";
+}
diff --git a/samples/TodoApp/appsettings.Development.json b/samples/TodoApp/appsettings.Development.json
new file mode 100644
index 00000000..d76d68ea
--- /dev/null
+++ b/samples/TodoApp/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Debug",
+ "System": "Warning",
+ "Microsoft": "Warning"
+ }
+ }
+}
diff --git a/samples/TodoApp/appsettings.json b/samples/TodoApp/appsettings.json
new file mode 100644
index 00000000..fd10c22b
--- /dev/null
+++ b/samples/TodoApp/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "SqlLocalDbInstance": "SqlLocalDb-TodoApp"
+}
diff --git a/samples/TodoApp/bundleconfig.json b/samples/TodoApp/bundleconfig.json
new file mode 100644
index 00000000..2aee0e7f
--- /dev/null
+++ b/samples/TodoApp/bundleconfig.json
@@ -0,0 +1,14 @@
+[
+ {
+ "outputFileName": "wwwroot/css/site.min.css",
+ "inputFiles": [
+ "wwwroot/css/site.css"
+ ]
+ },
+ {
+ "outputFileName": "wwwroot/js/site.min.js",
+ "inputFiles": [
+ "wwwroot/js/site.js"
+ ]
+ }
+]
diff --git a/samples/TodoApp/wwwroot/css/site.css b/samples/TodoApp/wwwroot/css/site.css
new file mode 100644
index 00000000..42f2c6cf
--- /dev/null
+++ b/samples/TodoApp/wwwroot/css/site.css
@@ -0,0 +1,15 @@
+html {
+ font-size: 16px;
+}
+
+a {
+ color: #0060C7;
+}
+
+.body-content {
+ padding-top: 10px;
+}
+
+.navbar-dark .navbar-nav .nav-link {
+ color: #B0B0B0;
+}
diff --git a/samples/TodoApp/wwwroot/favicon.ico b/samples/TodoApp/wwwroot/favicon.ico
new file mode 100644
index 00000000..a3a79998
Binary files /dev/null and b/samples/TodoApp/wwwroot/favicon.ico differ
diff --git a/samples/TodoApp/wwwroot/js/site.js b/samples/TodoApp/wwwroot/js/site.js
new file mode 100644
index 00000000..7671a033
--- /dev/null
+++ b/samples/TodoApp/wwwroot/js/site.js
@@ -0,0 +1,13 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+const text = document.querySelector('#new-item-text');
+const button = document.querySelector('#add-new-item');
+
+text.addEventListener('input', () => {
+ if (text.value.length === 0) {
+ button.setAttribute('disabled', '');
+ } else {
+ button.removeAttribute('disabled');
+ }
+});
diff --git a/src/SqlLocalDb/Configuration/SqlLocalDbConfigurationSection.cs b/src/SqlLocalDb/Configuration/SqlLocalDbConfigurationSection.cs
deleted file mode 100644
index bbc7f632..00000000
--- a/src/SqlLocalDb/Configuration/SqlLocalDbConfigurationSection.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// SqlLocalDbConfigurationSection.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-using System.ComponentModel;
-using System.Configuration;
-using System.Globalization;
-
-namespace System.Data.SqlLocalDb.Configuration
-{
- ///
- /// A class representing the configuration section for the System.Data.SqlLocalDb assembly.
- /// This class cannot be inherited.
- ///
- public sealed class SqlLocalDbConfigurationSection : ConfigurationSection
- {
- ///
- /// The name of the SQL LocalDB configuration section.
- ///
- public const string SectionName = "system.data.sqlLocalDb";
-
- ///
- /// The name of the configuration attribute.
- ///
- private const string AutomaticallyDeleteInstanceFilesAttributeName = "automaticallyDeleteInstanceFiles";
-
- ///
- /// The name of the configuration attribute.
- ///
- private const string LanguageAttributeName = "language";
-
- ///
- /// The name of the configuration attribute.
- ///
- private const string LoggerTypeAttributeName = "loggerType";
-
- ///
- /// The name of the configuration attribute.
- ///
- private const string NativeApiOverrideVersionAttributeName = "overrideVersion";
-
- ///
- /// The name of the configuration attribute.
- ///
- private const string StopOptionsAttributeName = "stopOptions";
-
- ///
- /// The name of the configuration attribute.
- ///
- private const string StopTimeoutAttributeName = "stopTimeout";
-
- ///
- /// Initializes a new instance of the class.
- ///
- public SqlLocalDbConfigurationSection()
- : base()
- {
- }
-
- ///
- /// Gets or sets a value indicating whether to automatically delete the
- /// files associated with SQL LocalDB instances when they are deleted.
- ///
- [ConfigurationProperty(AutomaticallyDeleteInstanceFilesAttributeName, IsRequired = false, DefaultValue = false)]
- public bool AutomaticallyDeleteInstanceFiles
- {
- get { return (bool)base[AutomaticallyDeleteInstanceFilesAttributeName]; }
- set { base[AutomaticallyDeleteInstanceFilesAttributeName] = value; }
- }
-
- ///
- /// Gets or sets the override language to use to format error messages.
- ///
- [ConfigurationProperty(LanguageAttributeName, IsRequired = false, DefaultValue = null)]
- [TypeConverter(typeof(CultureInfoConverter))]
- public CultureInfo Language
- {
- get { return base[LanguageAttributeName] as CultureInfo; }
- set { base[LanguageAttributeName] = value; }
- }
-
- ///
- /// Gets or sets the type of the implementation to use, if any.
- ///
- [ConfigurationProperty(LoggerTypeAttributeName, IsRequired = false, DefaultValue = null)]
- [SubclassTypeValidator(typeof(ILogger))]
- [TypeConverter(typeof(TypeNameConverter))]
- public Type LoggerType
- {
- get { return base[LoggerTypeAttributeName] as Type; }
- set { base[LoggerTypeAttributeName] = value; }
- }
-
- ///
- /// Gets or sets the override version string of the native SQL LocalDB API to load, if any.
- ///
- [ConfigurationProperty(NativeApiOverrideVersionAttributeName, IsRequired = false, DefaultValue = "")]
- public string NativeApiOverrideVersion
- {
- get { return base[NativeApiOverrideVersionAttributeName] as string; }
- set { base[NativeApiOverrideVersionAttributeName] = value; }
- }
-
- ///
- /// Gets or sets the options to use when stopping instances of SQL LocalDB.
- ///
- [ConfigurationProperty(StopOptionsAttributeName, IsRequired = false, DefaultValue = StopInstanceOptions.None)]
- public StopInstanceOptions StopOptions
- {
- get { return (StopInstanceOptions)base[StopOptionsAttributeName]; }
- set { base[StopOptionsAttributeName] = value; }
- }
-
- ///
- /// Gets or sets the default timeout to use when stopping instances of SQL LocalDB.
- ///
- [ConfigurationProperty(StopTimeoutAttributeName, IsRequired = false, DefaultValue = "00:01:00")]
- [TimeSpanValidator(MinValueString = "00:00:00")]
- public TimeSpan StopTimeout
- {
- get { return (TimeSpan)base[StopTimeoutAttributeName]; }
- set { base[StopTimeoutAttributeName] = value; }
- }
-
- ///
- /// Gets a value indicating whether is set by the application configuration file.
- ///
- internal bool IsAutomaticallyDeleteInstanceFilesSpecified => IsPropertySetInConfigurationFile(AutomaticallyDeleteInstanceFilesAttributeName);
-
- ///
- /// Gets a value indicating whether is set by the application configuration file.
- ///
- internal bool IsNativeApiOverrideVersionSpecified => IsPropertySetInConfigurationFile(NativeApiOverrideVersionAttributeName);
-
- ///
- /// Returns the from the current application configuration file.
- ///
- ///
- /// An instance of read from the current application configuration file.
- ///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Design",
- "CA1024:UsePropertiesWhereAppropriate",
- Justification = "Requires loading the entire configuration file, which may be non-trivial.")]
- public static SqlLocalDbConfigurationSection GetSection()
- {
- SqlLocalDbConfigurationSection section = ConfigurationManager.GetSection(SectionName) as SqlLocalDbConfigurationSection;
-
- if (section == null)
- {
- section = new SqlLocalDbConfigurationSection();
- }
-
- return section;
- }
-
- ///
- /// Returns whether the configuration property with the specified name gets its
- /// value from it being explicitly set by the user in the application configuration file.
- ///
- /// The name of the configuration attribute.
- ///
- /// if the configuration property value is defined in the
- /// application configuration file; otherwise .
- ///
- private bool IsPropertySetInConfigurationFile(string propertyName) => ElementInformation.Properties[propertyName].ValueOrigin == PropertyValueOrigin.SetHere;
- }
-}
diff --git a/src/SqlLocalDb/ErrorHelper.cs b/src/SqlLocalDb/ErrorHelper.cs
deleted file mode 100644
index 537b3cad..00000000
--- a/src/SqlLocalDb/ErrorHelper.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// ErrorHelper.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-using System;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-namespace System.Data.SqlLocalDb
-{
- ///
- /// A class containing helper methods for error handling. This class cannot be inherited.
- ///
- internal static class ErrorHelper
- {
- ///
- /// Determines whether the specified exception is fatal.
- ///
- /// The exception to test.
- ///
- /// if the specified exception is fatal; otherwise, .
- ///
- internal static bool IsFatal(Exception exception)
- {
- while (exception != null)
- {
- if (((exception is OutOfMemoryException) && !(exception is InsufficientMemoryException)) ||
- (((exception is ThreadAbortException) ||
- (exception is AccessViolationException)) ||
- (exception is StackOverflowException) ||
- (exception is SEHException)))
- {
- return true;
- }
-
- if (!(exception is TypeInitializationException) && !(exception is TargetInvocationException))
- {
- break;
- }
-
- exception = exception.InnerException;
- }
-
- return false;
- }
- }
-}
diff --git a/src/SqlLocalDb/EventIds.cs b/src/SqlLocalDb/EventIds.cs
new file mode 100644
index 00000000..aec8c238
--- /dev/null
+++ b/src/SqlLocalDb/EventIds.cs
@@ -0,0 +1,305 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using Microsoft.Extensions.Logging;
+
+namespace MartinCostello.SqlLocalDb
+{
+ ///
+ /// A class containing trace event Ids. This class cannot be inherited.
+ ///
+ internal static class EventIds
+ {
+ //// Add new events to the end of the class to preserve the Ids.
+
+ ///
+ /// The for when the SQL LocalDB Instance API is loaded. This field is read-only.
+ ///
+ internal static readonly EventId NativeApiLoaded = new EventId(++Id, nameof(NativeApiLoaded));
+
+ ///
+ /// The for when the SQL LocalDB Instance API fails to load. This field is read-only.
+ ///
+ internal static readonly EventId NativeApiLoadFailed = new EventId(++Id, nameof(NativeApiLoadFailed));
+
+ ///
+ /// The for when the SQL LocalDB Instance API is not loaded. This field is read-only.
+ ///
+ internal static readonly EventId NativeApiNotLoaded = new EventId(++Id, nameof(NativeApiNotLoaded));
+
+ ///
+ /// The for when the SQL LocalDB Instance API version is overridden. This field is read-only.
+ ///
+ internal static readonly EventId NativeApiVersionOverriddenByUser = new EventId(++Id, nameof(NativeApiVersionOverriddenByUser));
+
+ ///
+ /// The for when the SQL LocalDB Instance API version specified as an override cannot be found. This field is read-only.
+ ///
+ internal static readonly EventId NativeApiVersionOverrideNotFound = new EventId(++Id, nameof(NativeApiVersionOverrideNotFound));
+
+ ///
+ /// The for when the SQL LocalDB Instance API cannot be found. This field is read-only.
+ ///
+ internal static readonly EventId NoNativeApiFound = new EventId(++Id, nameof(NoNativeApiFound));
+
+ ///
+ /// The for when the SQL LocalDB Instance API path configured in the registry cannot be found. This field is read-only.
+ ///
+ internal static readonly EventId NativeApiPathNotFound = new EventId(++Id, nameof(NativeApiPathNotFound));
+
+ ///
+ /// The for when a native function export from the SQL LocalDB Instance API cannot be found. This field is read-only.
+ ///
+ internal static readonly EventId NativeFunctionNotFound = new EventId(++Id, nameof(NativeFunctionNotFound));
+
+ ///
+ /// The for when the SQL LocalDB Instance API is not installed. This field is read-only.
+ ///
+ internal static readonly EventId NotInstalled = new EventId(++Id, nameof(NotInstalled));
+
+ ///
+ /// The for when a SQL LocalDB instance is being created. This field is read-only.
+ ///
+ internal static readonly EventId CreatingInstance = new EventId(++Id, nameof(CreatingInstance));
+
+ ///
+ /// The for when creating a SQL LocalDB instance fails. This field is read-only.
+ ///
+ internal static readonly EventId CreatingInstanceFailed = new EventId(++Id, nameof(CreatingInstanceFailed));
+
+ ///
+ /// The for when a SQL LocalDB instance has been created. This field is read-only.
+ ///
+ internal static readonly EventId CreatedInstance = new EventId(++Id, nameof(CreatedInstance));
+
+ ///
+ /// The for when a SQL LocalDB instance is being deleted. This field is read-only.
+ ///
+ internal static readonly EventId DeletingInstance = new EventId(++Id, nameof(DeletingInstance));
+
+ ///
+ /// The for when deleting a SQL LocalDB instance fails. This field is read-only.
+ ///
+ internal static readonly EventId DeletingInstanceFailed = new EventId(++Id, nameof(DeletingInstanceFailed));
+
+ ///
+ /// The for when deleting a SQL LocalDB instance fails because it cannot be found. This field is read-only.
+ ///
+ internal static readonly EventId DeletingInstanceFailedAsCannotBeNotFound = new EventId(++Id, nameof(DeletingInstanceFailedAsCannotBeNotFound));
+
+ ///
+ /// The for when deleting a SQL LocalDB instance fails because it is in use. This field is read-only.
+ ///
+ internal static readonly EventId DeletingInstanceFailedAsInUse = new EventId(++Id, nameof(DeletingInstanceFailedAsInUse));
+
+ ///
+ /// The for when a SQL LocalDB instance has been deleted. This field is read-only.
+ ///
+ internal static readonly EventId DeletedInstance = new EventId(++Id, nameof(DeletedInstance));
+
+ ///
+ /// The for when the files for a SQL LocalDB instance are being deleted. This field is read-only.
+ ///
+ internal static readonly EventId DeletingInstanceFiles = new EventId(++Id, nameof(DeletingInstanceFiles));
+
+ ///
+ /// The for when the files for a SQL LocalDB instance fail to be deleted. This field is read-only.
+ ///
+ internal static readonly EventId DeletingInstanceFilesFailed = new EventId(++Id, nameof(DeletingInstanceFilesFailed));
+
+ ///
+ /// The for when the files for a SQL LocalDB instance have been deleted. This field is read-only.
+ ///
+ internal static readonly EventId DeletedInstanceFiles = new EventId(++Id, nameof(DeletedInstanceFiles));
+
+ ///
+ /// The for when getting information about a SQL LocalDB instance. This field is read-only.
+ ///
+ internal static readonly EventId GettingInstanceInfo = new EventId(++Id, nameof(GettingInstanceInfo));
+
+ ///
+ /// The for when getting information about a SQL LocalDB instance fails. This field is read-only.
+ ///
+ internal static readonly EventId GettingInstanceInfoFailed = new EventId(++Id, nameof(GettingInstanceInfoFailed));
+
+ ///
+ /// The for when information about a SQL LocalDB instance was retrieved. This field is read-only.
+ ///
+ internal static readonly EventId GotInstanceInfo = new EventId(++Id, nameof(GotInstanceInfo));
+
+ ///
+ /// The for when getting SQL LocalDB instance names. This field is read-only.
+ ///
+ internal static readonly EventId GettingInstanceNames = new EventId(++Id, nameof(GettingInstanceNames));
+
+ ///
+ /// The for when getting SQL LocalDB instance names fails. This field is read-only.
+ ///
+ internal static readonly EventId GettingInstanceNamesFailed = new EventId(++Id, nameof(GettingInstanceNamesFailed));
+
+ ///
+ /// The for when SQL LocalDB instance names are retrieved. This field is read-only.
+ ///
+ internal static readonly EventId GotInstanceNames = new EventId(++Id, nameof(GotInstanceNames));
+
+ ///
+ /// The for when getting information about a SQL LocalDB version. This field is read-only.
+ ///
+ internal static readonly EventId GettingVersionInfo = new EventId(++Id, nameof(GettingVersionInfo));
+
+ ///
+ /// The for when getting information about a SQL LocalDB version fails. This field is read-only.
+ ///
+ internal static readonly EventId GettingVersionInfoFailed = new EventId(++Id, nameof(GettingVersionInfoFailed));
+
+ ///
+ /// The for when information about a SQL LocalDB version was retrieved. This field is read-only.
+ ///
+ internal static readonly EventId GotVersionInfo = new EventId(++Id, nameof(GotVersionInfo));
+
+ ///
+ /// The for when getting SQL LocalDB versions. This field is read-only.
+ ///
+ internal static readonly EventId GettingVersions = new EventId(++Id, nameof(GettingVersions));
+
+ ///
+ /// The for when getting SQL LocalDB versions fails. This field is read-only.
+ ///
+ internal static readonly EventId GettingVersionsFailed = new EventId(++Id, nameof(GettingVersionsFailed));
+
+ ///
+ /// The for when SQL LocalDB instance versions are retrieved. This field is read-only.
+ ///
+ internal static readonly EventId GotVersions = new EventId(++Id, nameof(GotVersions));
+
+ ///
+ /// The for when a specified Language Id is invalid. This field is read-only.
+ ///
+ internal static readonly EventId InvalidLanguageId = new EventId(++Id, nameof(InvalidLanguageId));
+
+ ///
+ /// The for when a specified registry key name is invalid. This field is read-only.
+ ///
+ internal static readonly EventId InvalidRegistryKey = new EventId(++Id, nameof(InvalidRegistryKey));
+
+ ///
+ /// The for when a registry key cannot be found. This field is read-only.
+ ///
+ internal static readonly EventId RegistryKeyNotFound = new EventId(++Id, nameof(RegistryKeyNotFound));
+
+ ///
+ /// The for when a SQL LocalDB instance is starting. This field is read-only.
+ ///
+ internal static readonly EventId StartingInstance = new EventId(++Id, nameof(StartingInstance));
+
+ ///
+ /// The for when a SQL LocalDB instance fails to start. This field is read-only.
+ ///
+ internal static readonly EventId StartingInstanceFailed = new EventId(++Id, nameof(StartingInstanceFailed));
+
+ ///
+ /// The for when a SQL LocalDB instance has started. This field is read-only.
+ ///
+ internal static readonly EventId StartedInstance = new EventId(++Id, nameof(StartedInstance));
+
+ ///
+ /// The for when a SQL LocalDB instance is stopping. This field is read-only.
+ ///
+ internal static readonly EventId StoppingInstance = new EventId(++Id, nameof(StoppingInstance));
+
+ ///
+ /// The for when a SQL LocalDB instance fails to stop. This field is read-only.
+ ///
+ internal static readonly EventId StoppingInstanceFailed = new EventId(++Id, nameof(StoppingInstanceFailed));
+
+ ///
+ /// The for when a SQL LocalDB instance has stopped. This field is read-only.
+ ///
+ internal static readonly EventId StoppedInstance = new EventId(++Id, nameof(StoppedInstance));
+
+ ///
+ /// The for when SQL LocalDB API tracing is starting. This field is read-only.
+ ///
+ internal static readonly EventId StartingTracing = new EventId(++Id, nameof(StartingTracing));
+
+ ///
+ /// The for when tracing for SQL LocalDB API fails to start. This field is read-only.
+ ///
+ internal static readonly EventId StartingTracingFailed = new EventId(++Id, nameof(StartingTracingFailed));
+
+ ///
+ /// The for when SQL LocalDB API tracing is started. This field is read-only.
+ ///
+ internal static readonly EventId StartedTracing = new EventId(++Id, nameof(StartedTracing));
+
+ ///
+ /// The for when SQL LocalDB API tracing is stopping. This field is read-only.
+ ///
+ internal static readonly EventId StoppedTracing = new EventId(++Id, nameof(StoppedTracing));
+
+ ///
+ /// The for when tracing for SQL LocalDB API fails to stop. This field is read-only.
+ ///
+ internal static readonly EventId StoppingTracingFailed = new EventId(++Id, nameof(StoppingTracingFailed));
+
+ ///
+ /// The for when SQL LocalDB API tracing is stopped. This field is read-only.
+ ///
+ internal static readonly EventId StoppingTracing = new EventId(++Id, nameof(StoppingTracing));
+
+ ///
+ /// The for when a temporary SQL LocalDB API instance fails to stop. This field is read-only.
+ ///
+ internal static readonly EventId StopTemporaryInstanceFailed = new EventId(++Id, nameof(StopTemporaryInstanceFailed));
+
+ ///
+ /// The for when a SQL LocalDB instance is being shared. This field is read-only.
+ ///
+ internal static readonly EventId SharingInstance = new EventId(++Id, nameof(SharingInstance));
+
+ ///
+ /// The for when sharing a SQL LocalDB instance fails. This field is read-only.
+ ///
+ internal static readonly EventId SharingInstanceFailed = new EventId(++Id, nameof(SharingInstanceFailed));
+
+ ///
+ /// The for when a SQL LocalDB instance has been shared. This field is read-only.
+ ///
+ internal static readonly EventId SharedInstance = new EventId(++Id, nameof(SharedInstance));
+
+ ///
+ /// The for when a SQL LocalDB instance is being unshared. This field is read-only.
+ ///
+ internal static readonly EventId UnsharingInstance = new EventId(++Id, nameof(UnsharingInstance));
+
+ ///
+ /// The for when unsharing a SQL LocalDB instance fails. This field is read-only.
+ ///
+ internal static readonly EventId UnsharingInstanceFailed = new EventId(++Id, nameof(UnsharingInstanceFailed));
+
+ ///
+ /// The for when a SQL LocalDB instance has been unshared. This field is read-only.
+ ///
+ internal static readonly EventId UnsharedInstance = new EventId(++Id, nameof(UnsharedInstance));
+
+ ///
+ /// The for when the SQL LocalDB Instance API is unloaded. This field is read-only.
+ ///
+ internal static readonly EventId NativeApiUnloaded = new EventId(++Id, nameof(NativeApiUnloaded));
+
+ ///
+ /// The for when the SQL LocalDB Instance API returns a generic error. This field is read-only.
+ ///
+ internal static readonly EventId GenericError = new EventId(++Id, nameof(GenericError));
+
+ ///
+ /// The base Id for the event Ids.
+ ///
+ private const int BaseId = 0;
+
+ ///
+ /// Gets or sets the current Id for assigning event Ids.
+ ///
+ private static int Id { get; set; } = BaseId;
+ }
+}
diff --git a/src/SqlLocalDb/Extensions.cs b/src/SqlLocalDb/Extensions.cs
deleted file mode 100644
index 387adb73..00000000
--- a/src/SqlLocalDb/Extensions.cs
+++ /dev/null
@@ -1,678 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// Extensions.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Configuration;
-using System.Data.Common;
-using System.Data.SqlClient;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-
-namespace System.Data.SqlLocalDb
-{
- ///
- /// A class containing extension methods for use with SQL LocalDB instances. This class cannot be inherited.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static class Extensions
- {
- ///
- /// The connection string keyword for the attached database file name.
- ///
- private const string AttachDBFilenameKeywordName = "AttachDBFilename";
-
- ///
- /// The assembly-qualified name of the type to use for entity connection string builders.
- ///
- private const string EntityConnectionStringBuilderTypeName = "System.Data.EntityClient.EntityConnectionStringBuilder, System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
-
- ///
- /// The assembly-qualified name of the type to use for entity connections.
- ///
- private const string EntityConnectionTypeName = "System.Data.EntityClient.EntityConnection, System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
-
- ///
- /// The connection string keyword for the Initial Catalog.
- ///
- private const string InitialCatalogKeywordName = "Initial Catalog";
-
- ///
- /// The connection string keyword for the Provider Connection String.
- ///
- private const string ProviderConnectionStringKeywordName = "Provider Connection String";
-
- ///
- /// The for the type with the name specified by .
- ///
- private static Type _entityConnectionStringBuilderType;
-
- ///
- /// The for the type with the name specified by .
- ///
- private static Type _entityConnectionType;
-
- ///
- /// The for the ProviderConnectionString property of the type specified by .
- ///
- private static PropertyInfo _providerConnectionStringProperty;
-
- ///
- /// Creates an instance of that can be used to connect to the SQL LocalDB instance
- /// using the only connection string configured in the current application configuration file.
- ///
- /// The to get the connection string builder for.
- ///
- /// The created instance of .
- ///
- ///
- /// is .
- ///
- ///
- /// No connection strings are configured in the application configuration file or more than one
- /// connection string is configured in the application configuration file.
- ///
- ///
- /// Connection strings may be inherited from outside the current application's configuration file, such as from
- /// machine.config. To use this overload it is recommended that, unless otherwise needed, a <clear/>
- /// element is added to the <connectionStrings> section of your application configuration file to
- /// prevent the default connection strings from being inherited.
- ///
- public static DbConnection GetConnectionForDefaultModel(this ISqlLocalDbInstance instance)
- {
- DbConnectionStringBuilder builder = instance.GetConnectionStringForDefaultModel();
- return CreateConnection(builder.ConnectionString);
- }
-
- ///
- /// Creates an instance of that can be used to connect to the SQL LocalDB instance
- /// using the only connection string configured in the current application configuration file.
- ///
- /// The to get the connection string builder for.
- /// The optional name to use for the Initial Catalog in the provider connection string to override the default, if present.
- ///
- /// The created instance of .
- ///
- ///
- /// is .
- ///
- ///
- /// No connection strings are configured in the application configuration file or more than one
- /// connection string is configured in the application configuration file.
- ///
- ///
- /// Connection strings may be inherited from outside the current application's configuration file, such as from
- /// machine.config. To use this overload it is recommended that, unless otherwise needed, a <clear/>
- /// element is added to the <connectionStrings> section of your application configuration file to
- /// prevent the default connection strings from being inherited.
- ///
- public static DbConnection GetConnectionForDefaultModel(this ISqlLocalDbInstance instance, string initialCatalog)
- {
- DbConnectionStringBuilder builder = instance.GetConnectionStringForDefaultModel(initialCatalog);
- return CreateConnection(builder.ConnectionString);
- }
-
- ///
- /// Creates an instance of that can be used to connect to the SQL LocalDB instance.
- ///
- /// The to get the connection string builder for.
- /// The name of the connection string for the model in the application configuration file.
- ///
- /// The created instance of .
- ///
- ///
- /// No connection string with the name specified by can be found in the application configuration file.
- ///
- ///
- /// is .
- ///
- public static DbConnection GetConnectionForModel(this ISqlLocalDbInstance instance, string modelConnectionStringName)
- {
- DbConnectionStringBuilder builder = instance.GetConnectionStringForModel(modelConnectionStringName);
- return CreateConnection(builder.ConnectionString);
- }
-
- ///
- /// Creates an instance of that can be used to connect to the SQL LocalDB instance.
- ///
- /// The to get the connection string builder for.
- /// The name of the connection string for the model in the application configuration file.
- /// The optional name to use for the Initial Catalog in the provider connection string to override the default, if present.
- ///
- /// The created instance of .
- ///
- ///
- /// No connection string with the name specified by can be found in the application configuration file.
- ///
- ///
- /// is .
- ///
- public static DbConnection GetConnectionForModel(this ISqlLocalDbInstance instance, string modelConnectionStringName, string initialCatalog)
- {
- DbConnectionStringBuilder builder = instance.GetConnectionStringForModel(modelConnectionStringName, initialCatalog);
- return CreateConnection(builder.ConnectionString);
- }
-
- ///
- /// Creates an instance of that can be used to connect to the SQL LocalDB instance
- /// using the only connection string configured in the current application configuration file.
- ///
- /// The to get the connection string builder for.
- ///
- /// The created instance of .
- ///
- ///
- /// is .
- ///
- ///
- /// No connection strings are configured in the application configuration file or more than one
- /// connection string is configured in the application configuration file.
- ///
- ///
- /// Connection strings may be inherited from outside the current application's configuration file, such as from
- /// machine.config. To use this overload it is recommended that, unless otherwise needed, a <clear/>
- /// element is added to the <connectionStrings> section of your application configuration file to
- /// prevent the default connection strings from being inherited.
- ///
- public static DbConnectionStringBuilder GetConnectionStringForDefaultModel(this ISqlLocalDbInstance instance) => instance.GetConnectionStringForDefaultModel(null);
-
- ///
- /// Creates an instance of that can be used to connect to the SQL LocalDB instance
- /// using the only connection string configured in the current application configuration file.
- ///
- /// The to get the connection string builder for.
- /// The optional name to use for the Initial Catalog in the provider connection string to override the default, if present.
- ///
- /// The created instance of .
- ///
- ///
- /// is .
- ///
- ///
- /// No connection strings are configured in the application configuration file, more than one
- /// connection string is configured in the application configuration file or the value of the
- /// property of is
- /// or the empty string.
- ///
- ///
- /// Connection strings may be inherited from outside the current application's configuration file, such as from
- /// machine.config. To use this overload it is recommended that, unless otherwise needed, a <clear/>
- /// element is added to the <connectionStrings> section of your application configuration file to
- /// prevent the default connection strings from being inherited.
- ///
- public static DbConnectionStringBuilder GetConnectionStringForDefaultModel(this ISqlLocalDbInstance instance, string initialCatalog)
- {
- if (instance == null)
- {
- throw new ArgumentNullException(nameof(instance));
- }
-
- var connectionStrings = ConfigurationManager.ConnectionStrings
- .OfType()
- .ToList();
-
- if (connectionStrings.Count < 1)
- {
- throw new InvalidOperationException(SR.Extensions_NoConnectionStrings);
- }
- else if (connectionStrings.Count > 1)
- {
- throw new InvalidOperationException(SR.Extensions_NoSingleConnectionString);
- }
-
- return CreateBuilder(connectionStrings[0], instance.NamedPipe, initialCatalog);
- }
-
- ///
- /// Creates an instance of that can be used to connect to the SQL LocalDB instance.
- ///
- /// The to get the connection string builder for.
- /// The name of the connection string for the model in the application configuration file.
- ///
- /// The created instance of .
- ///
- ///
- /// No connection string with the name specified by can be found in the application configuration file.
- ///
- ///
- /// is .
- ///
- public static DbConnectionStringBuilder GetConnectionStringForModel(this ISqlLocalDbInstance instance, string modelConnectionStringName) => instance.GetConnectionStringForModel(modelConnectionStringName, null);
-
- ///
- /// Creates an instance of that can be used to connect to the SQL LocalDB instance.
- ///
- /// The to get the connection string builder for.
- /// The name of the connection string for the model in the application configuration file.
- /// The optional name to use for the Initial Catalog in the provider connection string to override the default, if present.
- ///
- /// The created instance of .
- ///
- ///
- /// No connection string with the name specified by can be found in the application configuration file.
- ///
- ///
- /// is .
- ///
- ///
- /// The value of the property of is or the empty string.
- ///
- public static DbConnectionStringBuilder GetConnectionStringForModel(this ISqlLocalDbInstance instance, string modelConnectionStringName, string initialCatalog)
- {
- if (instance == null)
- {
- throw new ArgumentNullException(nameof(instance));
- }
-
- var connectionStringSettings = ConfigurationManager.ConnectionStrings
- .OfType()
- .Where((p) => string.Equals(p.Name, modelConnectionStringName, StringComparison.Ordinal))
- .FirstOrDefault();
-
- if (connectionStringSettings == null)
- {
- throw new ArgumentException(SRHelper.Format(SR.Extensions_NoConnectionStringFormat, modelConnectionStringName), nameof(modelConnectionStringName));
- }
-
- return CreateBuilder(connectionStringSettings, instance.NamedPipe, initialCatalog);
- }
-
- ///
- /// Gets the default SQL Local DB instance.
- ///
- /// The to use to get the default instance.
- ///
- /// The default SQL Local DB instance.
- ///
- ///
- /// is .
- ///
- public static ISqlLocalDbInstance GetDefaultInstance(this ISqlLocalDbProvider value) => value.GetOrCreateInstance(SqlLocalDbApi.DefaultInstanceName);
-
- ///
- /// Gets the Initial Catalog name from the specified , if present.
- ///
- /// The to extract the Initial Catalog name from.
- ///
- /// The name of the Initial Catalog present in , if any; otherwise .
- ///
- ///
- /// is .
- ///
- public static string GetInitialCatalogName(this DbConnectionStringBuilder value) => value.ExtractStringValueFromConnectionString(InitialCatalogKeywordName);
-
- ///
- /// Gets the physical file name from the specified , if present.
- ///
- /// The to extract the physical file name from.
- ///
- /// The name of the physical file name present in , if any; otherwise .
- ///
- ///
- /// is .
- ///
- public static string GetPhysicalFileName(this DbConnectionStringBuilder value) => value.ExtractStringValueFromConnectionString(AttachDBFilenameKeywordName);
-
- ///
- /// Gets an SQL Local DB instance with the specified name if it exists, otherwise a new instance with the specified name is created.
- ///
- /// The to use to get or create the instance.
- /// The name of the SQL Server LocalDB instance to get or create.
- ///
- /// An SQL Local DB instance with the name specified by .
- ///
- ///
- /// or is .
- ///
- ///
- /// returns when queried for instances.
- ///
- public static ISqlLocalDbInstance GetOrCreateInstance(this ISqlLocalDbProvider value, string instanceName)
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- if (instanceName == null)
- {
- throw new ArgumentNullException(nameof(instanceName));
- }
-
- bool instanceExists = false;
-
- if (SqlLocalDbApi.IsDefaultInstanceName(instanceName))
- {
- // The default instance is always listed, even if it does not exist,
- // so need to query that separately to verify whether to get or create.
- instanceExists = SqlLocalDbApi.GetInstanceInfo(instanceName).Exists;
- }
- else
- {
- // This approach is used otherwise for testability
- IList instances = value.GetInstances();
-
- if (instances != null)
- {
- // Instance names in SQL Local DB are case-insensitive
- instanceExists = instances
- .Where((p) => p != null)
- .Where((p) => string.Equals(p.Name, instanceName, StringComparison.OrdinalIgnoreCase))
- .Any();
- }
- }
-
- if (instanceExists)
- {
- return value.GetInstance(instanceName);
- }
- else
- {
- return value.CreateInstance(instanceName);
- }
- }
-
- ///
- /// Restarts the specified instance.
- ///
- /// The instance to restart.
- ///
- /// is .
- ///
- public static void Restart(this ISqlLocalDbInstance instance)
- {
- if (instance == null)
- {
- throw new ArgumentNullException(nameof(instance));
- }
-
- instance.Stop();
- instance.Start();
- }
-
- ///
- /// Sets the Initial Catalog name in the specified .
- ///
- /// The to set the Initial Catalog name for.
- /// The name of the Initial Catalog to set.
- ///
- /// is .
- ///
- public static void SetInitialCatalogName(this DbConnectionStringBuilder value, string initialCatalog)
- {
- value.SetKeywordValueAsString(InitialCatalogKeywordName, initialCatalog);
- }
-
- ///
- /// Sets the physical database file name in the specified .
- ///
- /// The to set the physical database file name for.
- /// The physical file name to set.
- ///
- /// is or invalid.
- ///
- ///
- /// references the Data Directory for the current but
- /// the Data Directory for the current has no value set.
- ///
- public static void SetPhysicalFileName(this DbConnectionStringBuilder value, string fileName)
- {
- string fullPath = null;
-
- if (fileName != null)
- {
- fullPath = ExpandDataDirectoryIfPresent(fileName);
-
- try
- {
- // Only full file paths are supported, so ensure that the path is fully qualified before it is set
- fullPath = Path.GetFullPath(fullPath);
- }
- catch (ArgumentException ex)
- {
- throw new ArgumentException(SRHelper.Format(SR.Extensions_InvalidPathFormat, ex.Message), nameof(fileName), ex);
- }
- catch (NotSupportedException ex)
- {
- throw new ArgumentException(SRHelper.Format(SR.Extensions_InvalidPathFormat, ex.Message), nameof(fileName), ex);
- }
- }
-
- value.SetKeywordValueAsString(AttachDBFilenameKeywordName, fullPath);
- }
-
- ///
- /// Creates an instance of using the specified base
- /// connection string, SQL Local DB named pipe and optional Initial Catalog name.
- ///
- /// The connection string settings for the base connection string.
- /// The SQL Local DB named pipe to use as the data source.
- /// The optional name to use for the Initial Catalog in the provider connection string to override the default, if present.
- ///
- /// The created instance of .
- ///
- private static DbConnectionStringBuilder CreateBuilder(
- ConnectionStringSettings connectionStringSettings,
- string namedPipe,
- string initialCatalog)
- {
- Debug.Assert(connectionStringSettings != null, "connectionStringSettings cannot be null.");
-
- if (string.IsNullOrEmpty(namedPipe))
- {
- throw new InvalidOperationException(SR.Extensions_NoNamedPipe);
- }
-
- if (_entityConnectionStringBuilderType == null)
- {
- _entityConnectionStringBuilderType = Type.GetType(EntityConnectionStringBuilderTypeName);
- }
-
- Debug.Assert(_entityConnectionStringBuilderType != null, "Could not find the EntityConnectionStringBuilder type.");
-
- DbConnectionStringBuilder entityBuilder = Activator.CreateInstance(
- _entityConnectionStringBuilderType,
- new object[] { connectionStringSettings.ConnectionString }) as DbConnectionStringBuilder;
-
- if (_providerConnectionStringProperty == null)
- {
- _providerConnectionStringProperty = _entityConnectionStringBuilderType.GetProperty("ProviderConnectionString");
- }
-
- Debug.Assert(_providerConnectionStringProperty != null, "Could not find the ProviderConnectionString property of the EntityConnectionStringBuilder type.");
- string providerConnectionString = _providerConnectionStringProperty.GetValue(entityBuilder, null) as string;
-
- SqlConnectionStringBuilder providerBuilder = new SqlConnectionStringBuilder(providerConnectionString)
- {
- DataSource = namedPipe,
- };
-
- if (!string.IsNullOrEmpty(initialCatalog))
- {
- providerBuilder.InitialCatalog = initialCatalog;
- }
-
- _providerConnectionStringProperty.SetValue(entityBuilder, providerBuilder.ConnectionString, null);
-
- return entityBuilder;
- }
-
- ///
- /// Creates a for an entity connection.
- ///
- /// The connection string to use to create the connection.
- ///
- /// The created instance of .
- ///
- private static DbConnection CreateConnection(string connectionString)
- {
- if (_entityConnectionType == null)
- {
- _entityConnectionType = Type.GetType(EntityConnectionTypeName);
- }
-
- Debug.Assert(_entityConnectionType != null, "The EntityConnection type could not be found.");
- return Activator.CreateInstance(_entityConnectionType, new object[] { connectionString }) as DbConnection;
- }
-
- ///
- /// Expands any reference to the Data Directory for the current .
- ///
- /// The file name to expand.
- ///
- /// The expanded representation of if the Data Directory for
- /// the current is referenced and set; otherwise .
- ///
- ///
- /// The Data Directory is not set for the current .
- ///
- private static string ExpandDataDirectoryIfPresent(string fileName)
- {
- const string DataDirectorySubstitution = "|DataDirectory|";
-
- if (fileName.Contains(DataDirectorySubstitution))
- {
- string dataDirectoryPath = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
-
- if (dataDirectoryPath == null)
- {
- throw new NotSupportedException(SR.Extensions_NoAppDomainDataDirectory);
- }
-
- fileName = fileName.Replace(DataDirectorySubstitution, dataDirectoryPath);
- }
-
- return fileName;
- }
-
- ///
- /// Extracts the value of the specified keyword from the specified .
- ///
- /// The to extract the value from.
- /// The keyword to extract the value of.
- ///
- /// The value of the keyword specified by present in , if any; otherwise .
- ///
- ///
- /// is .
- ///
- private static string ExtractStringValueFromConnectionString(this DbConnectionStringBuilder value, string keyword)
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- // N.B. Keywords are used here rather than the strongly-typed derived classes
- // of DbConnectionStringBuilder. This is so that custom derived classes can be
- // used and also so that both of the following entity connection string builders
- // can be used without using reflection and hard-coded type names:
- // 1) System.Data.EntityClient.EntityClientConnectionStringBuilder (System.Data.Entity.dll)
- // 2) System.Data.Entity.Core.EntityClient.EntityClientConnectionStringBuilder (EntityFramework.dll)
-
- // First assume it's an SQL connection string
- string result = null;
-
- if (value.TryGetValue(keyword, out object resultAsObject))
- {
- result = resultAsObject as string;
- }
-
- if (!string.IsNullOrEmpty(result))
- {
- return result;
- }
-
- string providerConnectionString = null;
-
- // If it wasn't SQL, see if it's an entity connection string
- // by trying to extract the provider connection string
- if (value.TryGetValue(ProviderConnectionStringKeywordName, out object providerConnectionStringAsObject))
- {
- // It wasn't an entity connection string, nothing further to try
- providerConnectionString = providerConnectionStringAsObject as string;
- }
-
- if (!string.IsNullOrEmpty(providerConnectionString))
- {
- // Build a connection string from the provider connection string
- DbConnectionStringBuilder builder = new DbConnectionStringBuilder()
- {
- ConnectionString = providerConnectionString,
- };
-
- // Try and extract the initial catalog from the provider's connection string
- if (builder.TryGetValue(keyword, out object resultFromProviderAsObject))
- {
- result = resultFromProviderAsObject as string;
- }
- }
-
- // Derived types of DbConnectionStringBuilder may return the empty string instead of null
- // if they key is missing/not set, so in those cases explicitly return null instead.
- if (string.IsNullOrEmpty(result))
- {
- return null;
- }
-
- return result;
- }
-
- ///
- /// Sets the specified keyword's value to the specified value in the specified .
- ///
- /// The to set the keyword value for.
- /// The keyword to set the value for.
- /// The value to set the keyword to.
- ///
- /// is .
- ///
- private static void SetKeywordValueAsString(this DbConnectionStringBuilder value, string keyword, string keywordValue)
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- // N.B. Keywords are used here rather than the strongly-typed derived classes
- // of DbConnectionStringBuilder. This is so that custom derived classes can be
- // used and also so that both of the following entity connection string builders
- // can be used without using reflection and hard-coded type names:
- // 1) System.Data.EntityClient.EntityClientConnectionStringBuilder (System.Data.Entity.dll)
- // 2) System.Data.Entity.Core.EntityClient.EntityClientConnectionStringBuilder (EntityFramework.dll)
- if (value.TryGetValue(ProviderConnectionStringKeywordName, out object providerConnectionStringAsObject))
- {
- string providerConnectionString = providerConnectionStringAsObject as string;
-
- if (!string.IsNullOrEmpty(providerConnectionString))
- {
- // Build a connection string from the provider connection string
- DbConnectionStringBuilder builder = new DbConnectionStringBuilder()
- {
- ConnectionString = providerConnectionString,
- };
-
- // Set the keyword value in the Provider Connection String and replace
- // the initial Provider Connection String with the updated one
- builder[keyword] = keywordValue;
- value[ProviderConnectionStringKeywordName] = builder.ConnectionString;
- }
- }
- else
- {
- value[keyword] = keywordValue;
- }
- }
- }
-}
diff --git a/src/SqlLocalDb/ILogger.cs b/src/SqlLocalDb/ILogger.cs
deleted file mode 100644
index 713f6958..00000000
--- a/src/SqlLocalDb/ILogger.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// ILogger.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
-namespace System.Data.SqlLocalDb
-{
- ///
- /// Defines a logger.
- ///
- public interface ILogger
- {
- ///
- /// Writes an error trace event.
- ///
- /// A numeric identifier for the event.
- ///
- /// A composite format string that contains text intermixed with zero or more
- /// format items, which correspond to objects in the args array.
- ///
- ///
- /// An object array containing zero or more objects to format.
- ///
- void WriteError(int id, string format, params object[] args);
-
- ///
- /// Writes an informational trace event.
- ///
- /// A numeric identifier for the event.
- ///
- /// A composite format string that contains text intermixed with zero or more
- /// format items, which correspond to objects in the args array.
- ///
- ///
- /// An object array containing zero or more objects to format.
- ///
- void WriteInformation(int id, string format, params object[] args);
-
- ///
- /// Writes a verbose trace event.
- ///
- /// A numeric identifier for the event.
- ///
- /// A composite format string that contains text intermixed with zero or more
- /// format items, which correspond to objects in the args array.
- ///
- ///
- /// An object array containing zero or more objects to format.
- ///
- void WriteVerbose(int id, string format, params object[] args);
-
- ///
- /// Writes a warning trace event.
- ///
- /// A numeric identifier for the event.
- ///
- /// A composite format string that contains text intermixed with zero or more
- /// format items, which correspond to objects in the args array.
- ///
- ///
- /// An object array containing zero or more objects to format.
- ///
- void WriteWarning(int id, string format, params object[] args);
- }
-}
diff --git a/src/SqlLocalDb/ILoggerExtensions.cs b/src/SqlLocalDb/ILoggerExtensions.cs
new file mode 100644
index 00000000..ffbdc313
--- /dev/null
+++ b/src/SqlLocalDb/ILoggerExtensions.cs
@@ -0,0 +1,727 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using System;
+using System.Globalization;
+using Microsoft.Extensions.Logging;
+
+namespace MartinCostello.SqlLocalDb
+{
+ ///
+ /// A class containing extension methods for the interface. This class cannot be inherited.
+ ///
+ internal static class ILoggerExtensions
+ {
+ ///
+ /// Logging delegate for when a SQL LocalDB instance has been created.
+ ///
+ private static readonly Action _createdInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.CreatedInstance,
+ SR.ILoggerExtensions_CreatedInstanceFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance is being created.
+ ///
+ private static readonly Action _creatingInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.CreatingInstance,
+ SR.ILoggerExtensions_CreatingInstanceFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance has been deleted.
+ ///
+ private static readonly Action _deletedInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.DeletedInstance,
+ SR.ILoggerExtensions_DeletedInstanceFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance is being deleting.
+ ///
+ private static readonly Action _deletingInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.DeletingInstance,
+ SR.ILoggerExtensions_DeletingFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance that could not be deleted.
+ ///
+ private static readonly Action _deletingInstanceFailed = LoggerMessage.Define(
+ LogLevel.Error,
+ EventIds.DeletingInstanceFailed,
+ SR.ILoggerExtensions_DeleteFailedFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance that could not be deleted as it is still in use.
+ ///
+ private static readonly Action _deletingInstanceFailedAsInUse = LoggerMessage.Define(
+ LogLevel.Warning,
+ EventIds.DeletingInstanceFailedAsInUse,
+ SR.ILoggerExtensions_DeleteFailedAsInUseFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance that could not be deleted because it could not be found.
+ ///
+ private static readonly Action _deletingInstanceFailedAsInstanceNotFound = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.DeletingInstanceFailedAsCannotBeNotFound,
+ SR.ILoggerExtensions_InstanceDoesNotExistFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance files have been deleted.
+ ///
+ private static readonly Action _deletedInstanceFiles = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.DeletedInstanceFiles,
+ SR.ILoggerExtensions_DeletedInstanceFilesFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance files are being deleted.
+ ///
+ private static readonly Action _deletingInstanceFiles = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.DeletingInstanceFiles,
+ SR.ILoggerExtensions_DeletingInstanceFilesFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance files could not be deleted.
+ ///
+ private static readonly Action _deletingInstanceFilesFailed = LoggerMessage.Define(
+ LogLevel.Error,
+ EventIds.DeletingInstanceFilesFailed,
+ SR.ILoggerExtensions_DeletingInstanceFilesFailedFormat);
+
+ ///
+ /// Logging delegate for when getting information about a SQL LocalDB instance.
+ ///
+ private static readonly Action _gettingInstanceInfo = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.GettingInstanceInfo,
+ SR.ILoggerExtensions_GettingInfoFormat);
+
+ ///
+ /// Logging delegate for when information about a SQL LocalDB instance was got.
+ ///
+ private static readonly Action _gotInstanceInfo = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.GotInstanceInfo,
+ SR.ILoggerExtensions_GotInfoFormat);
+
+ ///
+ /// Logging delegate for when getting SQL LocalDB instance names.
+ ///
+ private static readonly Action _gettingInstanceNames = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.GettingInstanceNames,
+ SR.ILoggerExtensions_GetInstances);
+
+ ///
+ /// Logging delegate for when SQL LocalDB instance names were got.
+ ///
+ private static readonly Action _gotInstanceNames = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.GotInstanceNames,
+ SR.ILoggerExtensions_GotInstancesFormat);
+
+ ///
+ /// Logging delegate for when getting information about a SQL LocalDB version.
+ ///
+ private static readonly Action _gettingVersionInfo = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.GettingVersionInfo,
+ SR.ILoggerExtensions_GetVersionInfoFormat);
+
+ ///
+ /// Logging delegate for when information about a SQL LocalDB version was got.
+ ///
+ private static readonly Action _gotVersionInfo = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.GotVersionInfo,
+ SR.ILoggerExtensions_GotVersionInfoFormat);
+
+ ///
+ /// Logging delegate for when getting SQL LocalDB versions.
+ ///
+ private static readonly Action _gettingVersions = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.GettingVersions,
+ SR.ILoggerExtensions_GetVersions);
+
+ ///
+ /// Logging delegate for when SQL LocalDB versions were got.
+ ///
+ private static readonly Action _gotVersions = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.GotVersions,
+ SR.ILoggerExtensions_GotVersionsFormat);
+
+ ///
+ /// Logging delegate for when a invalid Language Id is used.
+ ///
+ private static readonly Action _invalidLanguageId = LoggerMessage.Define(
+ LogLevel.Warning,
+ EventIds.InvalidLanguageId,
+ SR.ILoggerExtensions_InvalidLanguageIdFormat);
+
+ ///
+ /// Logging delegate for when a invalid SQL LocalDB Instance API registry key was found.
+ ///
+ private static readonly Action _invalidRegistryKey = LoggerMessage.Define(
+ LogLevel.Warning,
+ EventIds.InvalidRegistryKey,
+ SR.ILoggerExtensions_InvalidRegistryKeyNameFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB Instance API function could not be found.
+ ///
+ private static readonly Action _nativeApiFunctionNotFound = LoggerMessage.Define(
+ LogLevel.Error,
+ EventIds.NativeFunctionNotFound,
+ SR.ILoggerExtensions_FunctionNotFoundFormat);
+
+ ///
+ /// Logging delegate for when the SQL LocalDB Instance API DLL was loaded.
+ ///
+ private static readonly Action _nativeApiLoaded = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.NativeApiLoaded,
+ SR.ILoggerExtensions_NativeApiLoadedFormat);
+
+ ///
+ /// Logging delegate for when the SQL LocalDB Instance API DLL could not loaded.
+ ///
+ private static readonly Action _nativeApiLoadFailed = LoggerMessage.Define(
+ LogLevel.Error,
+ EventIds.NativeApiLoadFailed,
+ SR.ILoggerExtensions_NativeApiLoadFailedFormat);
+
+ ///
+ /// Logging delegate for when the SQL LocalDB Instance API could not be found.
+ ///
+ private static readonly Action _nativeApiNotFound = LoggerMessage.Define(
+ LogLevel.Warning,
+ EventIds.NoNativeApiFound,
+ SR.ILoggerExtensions_NoNativeApiFound);
+
+ ///
+ /// Logging delegate for when the SQL LocalDB Instance API DLL was not loaded.
+ ///
+ private static readonly Action _nativeApiNotLoaded = LoggerMessage.Define(
+ LogLevel.Warning,
+ EventIds.NativeApiNotLoaded,
+ SR.ILoggerExtensions_NativeApiNotLoaded);
+
+ ///
+ /// Logging delegate for when the SQL LocalDB Instance API DLL could not be found at the configured path.
+ ///
+ private static readonly Action _nativeApiPathNotFound = LoggerMessage.Define(
+ LogLevel.Error,
+ EventIds.NativeApiPathNotFound,
+ SR.ILoggerExtensions_NativeApiNotFoundFormat);
+
+ ///
+ /// Logging delegate for when the SQL LocalDB Instance API DLL was unloaded.
+ ///
+ private static readonly Action _nativeApiUnloaded = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.NativeApiUnloaded,
+ SR.ILoggerExtensions_NativeApiUnloadedFormat);
+
+ ///
+ /// Logging delegate for when the version of the SQL LocalDB Instance API to use was overridden by the user.
+ ///
+ private static readonly Action _nativeApiVersionOverriddenByUser = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.NativeApiVersionOverriddenByUser,
+ SR.ILoggerExtensions_NativeApiVersionOverriddenByUserFormat);
+
+ ///
+ /// Logging delegate for when the version of the SQL LocalDB Instance API specified by the user could not be found.
+ ///
+ private static readonly Action _nativeApiVersionOverrideNotFound = LoggerMessage.Define(
+ LogLevel.Warning,
+ EventIds.NativeApiVersionOverrideNotFound,
+ SR.ILoggerExtensions_OverrideVersionNotFoundFormat);
+
+ ///
+ /// Logging delegate for when SQL LocalDB is not installed.
+ ///
+ private static readonly Action _notInstalled = LoggerMessage.Define(
+ LogLevel.Warning,
+ EventIds.NotInstalled,
+ SR.ILoggerExtensions_NotInstalled);
+
+ ///
+ /// Logging delegate for when the SQL LocalDB Instance API registry key cannot be found.
+ ///
+ private static readonly Action _registryKeyNotFound = LoggerMessage.Define(
+ LogLevel.Warning,
+ EventIds.RegistryKeyNotFound,
+ SR.ILoggerExtensions_RegistryKeyNotFoundFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance was shared.
+ ///
+ private static readonly Action _sharedInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.SharedInstance,
+ SR.ILoggerExtensions_SharedInstanceFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance is shared.
+ ///
+ private static readonly Action _sharingInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.SharingInstance,
+ SR.ILoggerExtensions_SharingInstanceFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance is starting.
+ ///
+ private static readonly Action _startedInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.StartedInstance,
+ SR.ILoggerExtensions_StartedFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance is starting.
+ ///
+ private static readonly Action _startingInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.StartingInstance,
+ SR.ILoggerExtensions_StartingFormat);
+
+ ///
+ /// Logging delegate for when SQL LocalDB tracing has started.
+ ///
+ private static readonly Action _startedTracing = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.StartedTracing,
+ SR.ILoggerExtensions_StartedTracing);
+
+ ///
+ /// Logging delegate for when SQL LocalDB tracing is starting.
+ ///
+ private static readonly Action _startingTracing = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.StartingTracing,
+ SR.ILoggerExtensions_StartTracing);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance was stopped.
+ ///
+ private static readonly Action _stoppedInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.StoppedInstance,
+ SR.ILoggerExtensions_StoppedFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance is stopping.
+ ///
+ private static readonly Action _stoppingInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.StoppingInstance,
+ SR.ILoggerExtensions_StoppingFormat);
+
+ ///
+ /// Logging delegate for when a temporary SQL LocalDB instance failed to stop.
+ ///
+ private static readonly Action _stoppingTemporaryInstanceFailed = LoggerMessage.Define(
+ LogLevel.Error,
+ EventIds.StopTemporaryInstanceFailed,
+ SR.ILoggerExtensions_StopFailedFormat);
+
+ ///
+ /// Logging delegate for when SQL LocalDB instance is stopped.
+ ///
+ private static readonly Action _stoppedTracing = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.StoppedTracing,
+ SR.ILoggerExtensions_StoppedTracing);
+
+ ///
+ /// Logging delegate for when SQL LocalDB instance is stopping.
+ ///
+ private static readonly Action _stoppingTracing = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.StoppingTracing,
+ SR.ILoggerExtensions_StoppingTracing);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance was unshared.
+ ///
+ private static readonly Action _unsharedInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.UnsharedInstance,
+ SR.ILoggerExtensions_StoppedSharingFormat);
+
+ ///
+ /// Logging delegate for when a SQL LocalDB instance is unshared.
+ ///
+ private static readonly Action _unsharingInstance = LoggerMessage.Define(
+ LogLevel.Debug,
+ EventIds.UnsharingInstance,
+ SR.ILoggerExtensions_StoppingSharingFormat);
+
+ ///
+ /// Logs that a SQL LocalDB instance has been created.
+ ///
+ /// The logger to use.
+ /// The name of the instance that was created.
+ /// The LocalDB version the instance that was created with.
+ internal static void CreatedInstance(this ILogger logger, string instanceName, string version)
+ => _createdInstance(logger, instanceName, version, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance is being created.
+ ///
+ /// The logger to use.
+ /// The name of the instance that is being created.
+ /// The LocalDB version to create the instance with.
+ internal static void CreatingInstance(this ILogger logger, string instanceName, string version)
+ => _creatingInstance(logger, instanceName, version, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance has been deleted.
+ ///
+ /// The logger to use.
+ /// The name of the instance that was created.
+ internal static void DeletedInstance(this ILogger logger, string instanceName)
+ => _deletedInstance(logger, instanceName, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance is being deleted.
+ ///
+ /// The logger to use.
+ /// The name of the instance that is being deleted.
+ internal static void DeletingInstance(this ILogger logger, string instanceName)
+ => _deletingInstance(logger, instanceName, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance could not be deleted.
+ ///
+ /// The logger to use.
+ /// The name of the instance that could not be deleted.
+ /// The error code.
+ internal static void DeletingInstanceFailed(this ILogger logger, string instanceName, int error)
+ => _deletingInstanceFailed(logger, instanceName, error.ToString("X", CultureInfo.InvariantCulture), null);
+
+ ///
+ /// Logs that a SQL LocalDB instance could not be deleted because it is still in use.
+ ///
+ /// The logger to use.
+ /// The exception that was thrown.
+ /// The name of the instance that could not be deleted.
+ internal static void DeletingInstanceFailedAsInUse(this ILogger logger, Exception exception, string instanceName)
+ => _deletingInstanceFailedAsInUse(logger, instanceName, exception);
+
+ ///
+ /// Logs that a SQL LocalDB instance could not be deleted because it could not be found.
+ ///
+ /// The logger to use.
+ /// The name of the instance that could not be deleted.
+ internal static void DeletingInstanceFailedAsNotFound(this ILogger logger, string instanceName)
+ => _deletingInstanceFailedAsInstanceNotFound(logger, instanceName, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance's files have been deleted.
+ ///
+ /// The logger to use.
+ /// The name of the instance whose files were deleted.
+ /// The path of the files that were deleted.
+ internal static void DeletedInstanceFiles(this ILogger logger, string instanceName, string instancePath)
+ => _deletedInstanceFiles(logger, instanceName, instancePath, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance's files are being deleted.
+ ///
+ /// The logger to use.
+ /// The name of the instance whose files are being deleted.
+ /// The path of the files to be deleted.
+ internal static void DeletingInstanceFiles(this ILogger logger, string instanceName, string instancePath)
+ => _deletingInstanceFiles(logger, instanceName, instancePath, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance's files could not be deleted.
+ ///
+ /// The logger to use.
+ /// The name of the instance whose files could not be deleted.
+ /// The path of the files that failed to be deleted.
+ internal static void DeletingInstanceFilesFailed(this ILogger logger, string instanceName, string instancePath)
+ => _deletingInstanceFilesFailed(logger, instanceName, instancePath, null);
+
+ ///
+ /// Logs that information about a SQL LocalDB instance is being retrieved.
+ ///
+ /// The logger to use.
+ /// The name of the instance information is being retrieved for.
+ internal static void GettingInstanceInfo(this ILogger logger, string instanceName)
+ => _gettingInstanceInfo(logger, instanceName, null);
+
+ ///
+ /// Logs that information about a SQL LocalDB instance was retrieved.
+ ///
+ /// The logger to use.
+ /// The name of the instance information was retrieved for.
+ internal static void GotInstanceInfo(this ILogger logger, string instanceName)
+ => _gotInstanceInfo(logger, instanceName, null);
+
+ ///
+ /// Logs that SQL LocalDB instance names are being retrieved.
+ ///
+ /// The logger to use.
+ internal static void GettingInstanceNames(this ILogger logger)
+ => _gettingInstanceNames(logger, null);
+
+ ///
+ /// Logs that SQL LocalDB instance names were retrieved.
+ ///
+ /// The logger to use.
+ /// The number of SQL LocalDB instances retrieved.
+ internal static void GotInstanceNames(this ILogger logger, int count)
+ => _gotInstanceNames(logger, count, null);
+
+ ///
+ /// Logs that information about a SQL LocalDB version is being retrieved.
+ ///
+ /// The logger to use.
+ /// The version information is being retrieved for.
+ internal static void GettingVersionInfo(this ILogger logger, string version)
+ => _gettingVersionInfo(logger, version, null);
+
+ ///
+ /// Logs that information about a SQL LocalDB version was retrieved.
+ ///
+ /// The logger to use.
+ /// The version information was retrieved for.
+ internal static void GotVersionInfo(this ILogger logger, string version)
+ => _gotVersionInfo(logger, version, null);
+
+ ///
+ /// Logs that SQL LocalDB versions are being retrieved.
+ ///
+ /// The logger to use.
+ internal static void GettingVersions(this ILogger logger)
+ => _gettingVersions(logger, null);
+
+ ///
+ /// Logs that SQL LocalDB versions were retrieved.
+ ///
+ /// The logger to use.
+ /// The number of SQL LocalDB versions retrieved.
+ internal static void GotVersions(this ILogger logger, int count)
+ => _gotVersions(logger, count, null);
+
+ ///
+ /// Logs that an invalid Language Id is configured.
+ ///
+ /// The logger to use.
+ /// The version used.
+ internal static void InvalidLanguageId(this ILogger logger, int languageId)
+ => _invalidLanguageId(logger, languageId, null);
+
+ ///
+ /// Logs that an invalid SQL LocalDB Instance API registry key was found.
+ ///
+ /// The logger to use.
+ /// The version used.
+ internal static void InvalidRegistryKey(this ILogger logger, string version)
+ => _invalidRegistryKey(logger, version, null);
+
+ ///
+ /// Logs that a SQL LocalDB Instance API function could not be found.
+ ///
+ /// The logger to use.
+ /// The name of the function that could not be found.
+ internal static void NativeApiFunctionNotFound(this ILogger logger, string functionName)
+ => _nativeApiFunctionNotFound(logger, functionName, null);
+
+ ///
+ /// Logs that the SQL LocalDB Instance API DLL could not be found at the configured path.
+ ///
+ /// The logger to use.
+ /// The path to the file that could not be found.
+ internal static void NativeApiLibraryNotFound(this ILogger logger, string path)
+ => _nativeApiPathNotFound(logger, path, null);
+
+ ///
+ /// Logs that the SQL LocalDB Instance API DLL was loaded.
+ ///
+ /// The logger to use.
+ /// The full path to the DLL that was loaded.
+ internal static void NativeApiLoaded(this ILogger logger, string fileName)
+ => _nativeApiLoaded(logger, fileName, null);
+
+ ///
+ /// Logs that the SQL LocalDB Instance API DLL could not loaded.
+ ///
+ /// The logger to use.
+ /// The full path to the DLL that could not be loaded.
+ /// The error code.
+ internal static void NativeApiLoadFailed(this ILogger logger, string fileName, int error)
+ => _nativeApiLoadFailed(logger, fileName, error, null);
+
+ ///
+ /// Logs that the SQL LocalDB Instance API could not be found.
+ ///
+ /// The logger to use.
+ internal static void NativeApiNotFound(this ILogger logger)
+ => _nativeApiNotFound(logger, null);
+
+ ///
+ /// Logs that the SQL LocalDB Instance API DLL was not loaded.
+ ///
+ /// The logger to use.
+ internal static void NativeApiNotLoaded(this ILogger logger)
+ => _nativeApiNotLoaded(logger, null);
+
+ ///
+ /// Logs that the SQL LocalDB Instance API DLL was unloaded.
+ ///
+ /// The logger to use.
+ /// The full path to the DLL that was unloaded.
+ internal static void NativeApiUnloaded(this ILogger logger, string fileName)
+ => _nativeApiUnloaded(logger, fileName, null);
+
+ ///
+ /// Logs that the version of the SQL LocalDB Instance API to use was overridden by the user.
+ ///
+ /// The logger to use.
+ /// The version used.
+ internal static void NativeApiVersionOverriddenByUser(this ILogger logger, Version version)
+ => _nativeApiVersionOverriddenByUser(logger, version, null);
+
+ ///
+ /// Logs that the version of the SQL LocalDB Instance API specified by the user could not be found.
+ ///
+ /// The logger to use.
+ /// The version specified to be used.
+ internal static void NativeApiVersionOverrideNotFound(this ILogger logger, string version)
+ => _nativeApiVersionOverrideNotFound(logger, version, null);
+
+ ///
+ /// Logs that SQL LocalDB is not installed.
+ ///
+ /// The logger to use.
+ internal static void NotInstalled(this ILogger logger)
+ => _notInstalled(logger, null);
+
+ ///
+ /// Logs that the SQL LocalDB Instance API registry key cannot be found.
+ ///
+ /// The logger to use.
+ /// The name of the registry key that was not found.
+ internal static void RegistryKeyNotFound(this ILogger logger, string keyName)
+ => _registryKeyNotFound(logger, keyName, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance is being shared.
+ ///
+ /// The logger to use.
+ /// The name of the instance that is being shared.
+ /// The SID of the instance owner.
+ /// The shared name for the LocalDB instance to share as.
+ internal static void SharingInstance(this ILogger logger, string instanceName, string ownerSid, string sharedInstanceName)
+ => _sharingInstance(logger, instanceName, ownerSid, sharedInstanceName, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance was shared.
+ ///
+ /// The logger to use.
+ /// The name of the instance that was shared.
+ /// The SID of the instance owner.
+ /// The shared name for the LocalDB instance to share as.
+ internal static void SharedInstance(this ILogger logger, string instanceName, string ownerSid, string sharedInstanceName)
+ => _sharedInstance(logger, instanceName, ownerSid, sharedInstanceName, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance was started.
+ ///
+ /// The logger to use.
+ /// The name of the instance that was started.
+ /// The named pipe the instance is listening on.
+ internal static void StartedInstance(this ILogger logger, string instanceName, string namedPipe)
+ => _startedInstance(logger, instanceName, namedPipe, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance is starting.
+ ///
+ /// The logger to use.
+ /// The name of the instance that is starting.
+ internal static void StartingInstance(this ILogger logger, string instanceName)
+ => _startingInstance(logger, instanceName, null);
+
+ ///
+ /// Logs that SQL LocalDB tracing was started.
+ ///
+ /// The logger to use.
+ internal static void StartedTracing(this ILogger logger)
+ => _startedTracing(logger, null);
+
+ ///
+ /// Logs that SQL LocalDB tracing is starting.
+ ///
+ /// The logger to use.
+ internal static void StartingTracing(this ILogger logger)
+ => _startingTracing(logger, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance was stopped.
+ ///
+ /// The logger to use.
+ /// The name of the instance that was stopped.
+ /// The time taken for the instance to stop.
+ internal static void StoppedInstance(this ILogger logger, string instanceName, TimeSpan elapsed)
+ => _stoppedInstance(logger, instanceName, elapsed, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance is stopping.
+ ///
+ /// The logger to use.
+ /// The name of the instance that is stopping.
+ /// The timeout used.
+ /// The stop options used.
+ internal static void StoppingInstance(this ILogger logger, string instanceName, TimeSpan timeout, StopInstanceOptions options)
+ => _stoppingInstance(logger, instanceName, timeout, options, null);
+
+ ///
+ /// Logs that a temporary SQL LocalDB instance failed to stop.
+ ///
+ /// The logger to use.
+ /// The name of the instance that failed to stop.
+ /// The error code.
+ internal static void StoppingTemporaryInstanceFailed(this ILogger logger, string instanceName, int error)
+ => _stoppingTemporaryInstanceFailed(logger, instanceName, error.ToString("X", CultureInfo.InvariantCulture), null);
+
+ ///
+ /// Logs that SQL LocalDB tracing was stopped.
+ ///
+ /// The logger to use.
+ internal static void StoppedTracing(this ILogger logger)
+ => _stoppedTracing(logger, null);
+
+ ///
+ /// Logs that SQL LocalDB tracing is stopping.
+ ///
+ /// The logger to use.
+ internal static void StoppingTracing(this ILogger logger)
+ => _stoppingTracing(logger, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance is being unshared.
+ ///
+ /// The logger to use.
+ /// The name of the instance that is being shared.
+ internal static void UnsharingInstance(this ILogger logger, string instanceName)
+ => _unsharingInstance(logger, instanceName, null);
+
+ ///
+ /// Logs that a SQL LocalDB instance was shared.
+ ///
+ /// The logger to use.
+ /// The name of the instance that was shared.
+ internal static void UnsharedInstance(this ILogger logger, string instanceName)
+ => _unsharedInstance(logger, instanceName, null);
+ }
+}
diff --git a/src/SqlLocalDb/ISqlLocalDbApi.cs b/src/SqlLocalDb/ISqlLocalDbApi.cs
index 8863e17e..d82b5cd8 100644
--- a/src/SqlLocalDb/ISqlLocalDbApi.cs
+++ b/src/SqlLocalDb/ISqlLocalDbApi.cs
@@ -1,46 +1,40 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// ISqlLocalDbApi.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+using System;
using System.Collections.Generic;
-namespace System.Data.SqlLocalDb
+namespace MartinCostello.SqlLocalDb
{
///
- /// Defines the interface to the SQL LocalDB API.
+ /// Defines the interface to the SQL LocalDB Instance API.
///
public interface ISqlLocalDbApi
{
+ ///
+ /// Gets the name of the default SQL LocalDB instance.
+ ///
+ string DefaultInstanceName { get; }
+
///
/// Gets the version string for the latest installed version of SQL Server LocalDB.
///
- string LatestVersion
- {
- get;
- }
+ string LatestVersion { get; }
///
- /// Gets an of containing the available version(s) of SQL LocalDB.
+ /// Gets an of containing the available version(s) of SQL LocalDB.
///
- IList Versions
- {
- get;
- }
+ IReadOnlyList Versions { get; }
///
/// Creates a new instance of SQL Server LocalDB.
///
/// The name of the LocalDB instance.
/// The version of SQL Server LocalDB to use.
- void CreateInstance(string instanceName, string version);
+ ///
+ /// An containing information about the instance that was created.
+ ///
+ ISqlLocalDbInstanceInfo CreateInstance(string instanceName, string version);
///
/// Deletes the specified SQL Server LocalDB instance.
@@ -66,11 +60,7 @@ IList Versions
///
/// The names of the the SQL Server LocalDB instances for the current user.
///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Design",
- "CA1024:UsePropertiesWhereAppropriate",
- Justification = "Requires enumerating the API which is non-trivial.")]
- IList GetInstanceNames();
+ IReadOnlyList GetInstanceNames();
///
/// Returns information about the specified LocalDB version.
@@ -82,6 +72,16 @@ IList Versions
///
ISqlLocalDbVersionInfo GetVersionInfo(string version);
+ ///
+ /// Returns whether the specified LocalDB instance exists.
+ ///
+ /// The name of the LocalDB instance to check for existence.
+ ///
+ /// if the LocalDB instance specified by
+ /// exists; otherwise .
+ ///
+ bool InstanceExists(string instanceName);
+
///
/// Returns whether SQL LocalDB is installed on the current machine.
///
@@ -122,19 +122,14 @@ IList Versions
/// The name of the LocalDB instance to stop.
///
///
- /// The amount of time to give the LocalDB instance to stop.
- /// If the value is , the method will
- /// return immediately and not wait for the instance to stop.
+ /// The optional amount of time to give the LocalDB instance to stop.
///
- void StopInstance(string instanceName, TimeSpan timeout);
+ void StopInstance(string instanceName, TimeSpan? timeout);
///
/// Disables tracing of native API calls for all the SQL Server
/// LocalDB instances owned by the current Windows user.
///
- ///
- /// Tracing could not be disabled.
- ///
void StopTracing();
///
@@ -143,11 +138,6 @@ IList Versions
///
/// The private name for the LocalDB instance to stop sharing.
///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Naming",
- "CA1704:IdentifiersShouldBeSpelledCorrectly",
- MessageId = "Unshare",
- Justification = "Matches the name of the native LocalDB API function.")]
void UnshareInstance(string instanceName);
}
}
diff --git a/src/SqlLocalDb/ISqlLocalDbApiAdapter.cs b/src/SqlLocalDb/ISqlLocalDbApiAdapter.cs
new file mode 100644
index 00000000..51fb7237
--- /dev/null
+++ b/src/SqlLocalDb/ISqlLocalDbApiAdapter.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+namespace MartinCostello.SqlLocalDb
+{
+ ///
+ /// Defines an interface implemented by objects that can provide an instance.
+ ///
+ public interface ISqlLocalDbApiAdapter
+ {
+ ///
+ /// Gets the instance.
+ ///
+ ISqlLocalDbApi LocalDb { get; }
+ }
+}
diff --git a/src/SqlLocalDb/ISqlLocalDbApiExtensions.cs b/src/SqlLocalDb/ISqlLocalDbApiExtensions.cs
new file mode 100644
index 00000000..a18486f7
--- /dev/null
+++ b/src/SqlLocalDb/ISqlLocalDbApiExtensions.cs
@@ -0,0 +1,201 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Security.Principal;
+
+namespace MartinCostello.SqlLocalDb
+{
+ ///
+ /// A class containing extension methods for the interface. This class cannot be inherited.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static class ISqlLocalDbApiExtensions
+ {
+ ///
+ /// Creates a new instance of with a randomly assigned name.
+ ///
+ /// The to use to create the temporary instance.
+ /// An optional value indicating whether to delete the file(s) associated with the SQL LocalDB instance when it is deleted.
+ ///
+ /// The created instance of .
+ ///
+ ///
+ /// is .
+ ///
+ public static TemporarySqlLocalDbInstance CreateTemporaryInstance(this ISqlLocalDbApi api, bool deleteFiles = false) => new TemporarySqlLocalDbInstance(api, deleteFiles);
+
+ ///
+ /// Gets the default SQL Local DB instance.
+ ///
+ /// The to use to get the default instance.
+ ///
+ /// The default SQL Local DB instance.
+ ///
+ ///
+ /// is .
+ ///
+ public static ISqlLocalDbInstanceInfo GetDefaultInstance(this ISqlLocalDbApi api)
+ {
+ if (api == null)
+ {
+ throw new ArgumentNullException(nameof(api));
+ }
+
+ return api.GetOrCreateInstance(api.DefaultInstanceName);
+ }
+
+ ///
+ /// Returns information about the available SQL Server LocalDB instances.
+ ///
+ /// The to use to enumerate the instances.
+ ///
+ /// An containing information
+ /// about the available SQL Server LocalDB instances on the current machine.
+ ///
+ ///
+ /// is .
+ ///
+ public static IReadOnlyList GetInstances(this ISqlLocalDbApi api)
+ {
+ if (api == null)
+ {
+ throw new ArgumentNullException(nameof(api));
+ }
+
+ IReadOnlyList instanceNames = api.GetInstanceNames();
+
+ var instances = new List(instanceNames?.Count ?? 0);
+
+ if (instanceNames != null)
+ {
+ foreach (string name in instanceNames)
+ {
+ ISqlLocalDbInstanceInfo info = api.GetInstanceInfo(name);
+ instances.Add(info);
+ }
+ }
+
+ return instances;
+ }
+
+ ///
+ /// Returns information about the installed SQL Server LocalDB version(s).
+ ///
+ /// The to use to enumerate the installed versions.
+ ///
+ /// An containing information
+ /// about the SQL Server LocalDB version(s) installed on the current machine.
+ ///
+ ///
+ /// is .
+ ///
+ public static IReadOnlyList GetVersions(this ISqlLocalDbApi api)
+ {
+ if (api == null)
+ {
+ throw new ArgumentNullException(nameof(api));
+ }
+
+ IReadOnlyList versionNames = api.Versions;
+ var versions = new List(versionNames?.Count ?? 0);
+
+ if (versionNames != null)
+ {
+ foreach (string version in versionNames)
+ {
+ ISqlLocalDbVersionInfo info = api.GetVersionInfo(version);
+ versions.Add(info);
+ }
+ }
+
+ return versions;
+ }
+
+ ///
+ /// Gets a SQL Local DB instance with the specified name if it exists, otherwise a new instance with the specified name is created.
+ ///
+ /// The to use to get or create the instance.
+ /// The name of the SQL Server LocalDB instance to get or create.
+ ///
+ /// A SQL Local DB instance with the name specified by .
+ ///
+ ///
+ /// or is .
+ ///
+ public static ISqlLocalDbInstanceInfo GetOrCreateInstance(this ISqlLocalDbApi api, string instanceName)
+ {
+ if (api == null)
+ {
+ throw new ArgumentNullException(nameof(api));
+ }
+
+ if (instanceName == null)
+ {
+ throw new ArgumentNullException(nameof(instanceName));
+ }
+
+ // Instance names in SQL Local DB are case-insensitive
+ if (string.Equals(api.DefaultInstanceName, instanceName, StringComparison.OrdinalIgnoreCase) ||
+ SqlLocalDbApi.IsDefaultInstanceName(instanceName))
+ {
+ // The default instance is always listed, even if it does not exist,
+ // so need to query that separately to verify whether to get or create.
+ ISqlLocalDbInstanceInfo info = api.GetInstanceInfo(instanceName);
+
+ if (info != null)
+ {
+ // If it exists (or it's a default instance), we can't create
+ // it so just return the information about it immediately.
+ if (info.Exists || info.IsAutomatic)
+ {
+ return info;
+ }
+ }
+ }
+
+ if (api.InstanceExists(instanceName))
+ {
+ return api.GetInstanceInfo(instanceName);
+ }
+ else
+ {
+ return api.CreateInstance(instanceName, api.LatestVersion);
+ }
+ }
+
+ ///
+ /// Shares the specified SQL Server LocalDB instance with other users of the computer,
+ /// using the specified shared name for the current Windows user.
+ ///
+ /// The to use to share the instance.
+ /// The private name for the LocalDB instance to share.
+ /// The shared name for the LocalDB instance to share.
+ ///
+ /// , or is .
+ ///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
+ public static void ShareInstance(this ISqlLocalDbApi api, string instanceName, string sharedInstanceName)
+ {
+ if (api == null)
+ {
+ throw new ArgumentNullException(nameof(api));
+ }
+
+ SqlLocalDbApi.EnsurePlatformSupported();
+
+ string ownerSid;
+
+ using (var identity = WindowsIdentity.GetCurrent())
+ {
+ ownerSid = identity.User.Value;
+ }
+
+ api.ShareInstance(ownerSid, instanceName, sharedInstanceName);
+ }
+ }
+}
diff --git a/src/SqlLocalDb/ISqlLocalDbInstance.cs b/src/SqlLocalDb/ISqlLocalDbInstance.cs
deleted file mode 100644
index 94d3865f..00000000
--- a/src/SqlLocalDb/ISqlLocalDbInstance.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// ISqlLocalDbInstance.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-using System.Data.SqlClient;
-
-namespace System.Data.SqlLocalDb
-{
- ///
- /// Defines an SQL Server LocalDB instance.
- ///
- public interface ISqlLocalDbInstance
- {
- ///
- /// Gets the name of the LocalDB instance.
- ///
- string Name
- {
- get;
- }
-
- ///
- /// Gets the named pipe that should be used
- /// to connect to the LocalDB instance.
- ///
- string NamedPipe
- {
- get;
- }
-
- ///
- /// Creates a connection to the LocalDB instance.
- ///
- ///
- /// An instance of that
- /// can be used to connect to the LocalDB instance.
- ///
- SqlConnection CreateConnection();
-
- ///
- /// Creates an instance of containing
- /// the default SQL connection string to connect to the LocalDB instance.
- ///
- ///
- /// An instance of containing
- /// the default SQL connection string to connect to the LocalDB instance.
- ///
- SqlConnectionStringBuilder CreateConnectionStringBuilder();
-
- ///
- /// Returns information about the LocalDB instance.
- ///
- ///
- /// An instance of containing
- /// information about the LocalDB instance.
- ///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Design",
- "CA1024:UsePropertiesWhereAppropriate",
- Justification = "Requires querying the LocalDB native API.")]
- ISqlLocalDbInstanceInfo GetInstanceInfo();
-
- ///
- /// Shares the LocalDB instance using the specified name.
- ///
- /// The name to use to share the instance.
- void Share(string sharedName);
-
- ///
- /// Starts the LocalDB instance.
- ///
- void Start();
-
- ///
- /// Stops the LocalDB instance.
- ///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Naming",
- "CA1716:IdentifiersShouldNotMatchKeywords",
- MessageId = "Stop",
- Justification = "Matches the name of the LocalDB native API function.")]
- void Stop();
-
- ///
- /// Stops sharing the LocalDB instance.
- ///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Naming",
- "CA1704:IdentifiersShouldBeSpelledCorrectly",
- MessageId = "Unshare",
- Justification = "Matches the name of the LocalDB native API function.")]
- void Unshare();
- }
-}
diff --git a/src/SqlLocalDb/ISqlLocalDbInstanceInfo.cs b/src/SqlLocalDb/ISqlLocalDbInstanceInfo.cs
index 04e65f32..b96cfd61 100644
--- a/src/SqlLocalDb/ISqlLocalDbInstanceInfo.cs
+++ b/src/SqlLocalDb/ISqlLocalDbInstanceInfo.cs
@@ -1,16 +1,9 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// ISqlLocalDbInstanceInfo.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
-namespace System.Data.SqlLocalDb
+using System;
+
+namespace MartinCostello.SqlLocalDb
{
///
/// Defines information about a SQL Server LocalDB instance.
@@ -20,89 +13,56 @@ public interface ISqlLocalDbInstanceInfo
///
/// Gets a value indicating whether the Registry configuration is corrupt.
///
- bool ConfigurationCorrupt
- {
- get;
- }
+ bool ConfigurationCorrupt { get; }
///
/// Gets a value indicating whether the instance's files exist on disk.
///
- bool Exists
- {
- get;
- }
+ bool Exists { get; }
///
/// Gets a value indicating whether the instance is automatic.
///
- bool IsAutomatic
- {
- get;
- }
+ bool IsAutomatic { get; }
///
/// Gets a value indicating whether the instance is currently running.
///
- bool IsRunning
- {
- get;
- }
+ bool IsRunning { get; }
///
/// Gets a value indicating whether the instance is shared.
///
- bool IsShared
- {
- get;
- }
+ bool IsShared { get; }
///
/// Gets the UTC date and time the instance was last started.
///
- DateTime LastStartTimeUtc
- {
- get;
- }
+ DateTime LastStartTimeUtc { get; }
///
/// Gets the LocalDB version for the instance.
///
- Version LocalDbVersion
- {
- get;
- }
+ Version LocalDbVersion { get; }
///
/// Gets the name of the instance.
///
- string Name
- {
- get;
- }
+ string Name { get; }
///
/// Gets the named pipe that should be used to communicate with the instance.
///
- string NamedPipe
- {
- get;
- }
+ string NamedPipe { get; }
///
/// Gets the SID of the LocalDB instance owner if the instance is shared.
///
- string OwnerSid
- {
- get;
- }
+ string OwnerSid { get; }
///
/// Gets the shared name of the LocalDB instance if the instance is shared.
///
- string SharedName
- {
- get;
- }
+ string SharedName { get; }
}
}
diff --git a/src/SqlLocalDb/ISqlLocalDbInstanceInfoExtensions.cs b/src/SqlLocalDb/ISqlLocalDbInstanceInfoExtensions.cs
new file mode 100644
index 00000000..58cfe183
--- /dev/null
+++ b/src/SqlLocalDb/ISqlLocalDbInstanceInfoExtensions.cs
@@ -0,0 +1,117 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using System;
+using System.ComponentModel;
+using System.Data.SqlClient;
+
+namespace MartinCostello.SqlLocalDb
+{
+ ///
+ /// A class containing extension methods for the interface. This class cannot be inherited.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static class ISqlLocalDbInstanceInfoExtensions
+ {
+ ///
+ /// Creates a connection to the LocalDB instance.
+ ///
+ /// The SQL LocalDB instance to create a connection to.
+ ///
+ /// An instance of that can be used to connect to the LocalDB instance.
+ ///
+ ///
+ /// is .
+ ///
+ ///
+ /// The SQL LocalDB instance specified by is not running.
+ ///
+ public static SqlConnection CreateConnection(this ISqlLocalDbInstanceInfo instance)
+ {
+ SqlConnectionStringBuilder builder = instance.CreateConnectionStringBuilder();
+ return new SqlConnection(builder.ConnectionString);
+ }
+
+ ///
+ /// Creates an instance of containing
+ /// the default SQL connection string to connect to the LocalDB instance.
+ ///
+ /// The SQL LocalDB instance to create a connection string builder for.
+ ///
+ /// An instance of containing
+ /// the default SQL connection string to connect to the LocalDB instance.
+ ///
+ ///
+ /// is .
+ ///
+ ///
+ /// The SQL LocalDB instance specified by is not running.
+ ///
+ public static SqlConnectionStringBuilder CreateConnectionStringBuilder(this ISqlLocalDbInstanceInfo instance)
+ {
+ if (instance == null)
+ {
+ throw new ArgumentNullException(nameof(instance));
+ }
+
+ if (!instance.IsRunning)
+ {
+ string message = SRHelper.Format(SR.ISqlLocalDbInstanceInfoExtensions_NotRunningFormat, instance.Name);
+ throw new InvalidOperationException(message);
+ }
+
+ return new SqlConnectionStringBuilder()
+ {
+ DataSource = instance.NamedPipe,
+ };
+ }
+
+ ///
+ /// Gets the default SQL connection string to connect to the LocalDB instance.
+ ///
+ /// The SQL LocalDB instance to get the default connection string for.
+ ///
+ /// The default SQL connection string to connect to the LocalDB instance.
+ ///
+ ///
+ /// is .
+ ///
+ ///
+ /// The SQL LocalDB instance specified by is not running.
+ ///
+ public static string GetConnectionString(this ISqlLocalDbInstanceInfo instance) => instance.CreateConnectionStringBuilder().ConnectionString;
+
+ ///
+ /// Returns an that can be used to manage the instance.
+ ///
+ /// The to manage.
+ ///
+ /// An that can be used to manage the SQL LocalDB instance.
+ ///
+ ///
+ /// is .
+ ///
+ ///
+ /// does not implement .
+ ///
+ public static ISqlLocalDbInstanceManager Manage(this ISqlLocalDbInstanceInfo instance)
+ {
+ if (instance == null)
+ {
+ throw new ArgumentNullException(nameof(instance));
+ }
+
+ if (instance is ISqlLocalDbApiAdapter adapter)
+ {
+ return new SqlLocalDbInstanceManager(instance, adapter.LocalDb);
+ }
+
+ string message = SRHelper.Format(
+ SR.ISqlLocalDbInstanceInfoExtensions_DoesNotImplementAdapterFormat,
+ nameof(ISqlLocalDbInstanceInfo),
+ nameof(ISqlLocalDbApiAdapter));
+
+ throw new ArgumentException(message, nameof(instance));
+ }
+ }
+}
diff --git a/src/SqlLocalDb/ISqlLocalDbInstanceManager.cs b/src/SqlLocalDb/ISqlLocalDbInstanceManager.cs
new file mode 100644
index 00000000..7923851f
--- /dev/null
+++ b/src/SqlLocalDb/ISqlLocalDbInstanceManager.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+namespace MartinCostello.SqlLocalDb
+{
+ ///
+ /// Defines an interface for managing instances of SQL LocalDB.
+ ///
+ public interface ISqlLocalDbInstanceManager
+ {
+ ///
+ /// Gets the name of the LocalDB instance.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the named pipe that should be used to connect to the LocalDB instance.
+ ///
+ string NamedPipe { get; }
+
+ ///
+ /// Gets the current state of the instance.
+ ///
+ ///
+ /// An representing the current state of the instance being managed.
+ ///
+ ISqlLocalDbInstanceInfo GetInstanceInfo();
+
+ ///
+ /// Shares the LocalDB instance using the specified name.
+ ///
+ /// The name to use to share the instance.
+ void Share(string sharedName);
+
+ ///
+ /// Starts the LocalDB instance.
+ ///
+ void Start();
+
+ ///
+ /// Stops the LocalDB instance.
+ ///
+#pragma warning disable CA1716 // Identifiers should not match keywords
+ void Stop();
+#pragma warning restore CA1716 // Identifiers should not match keywords
+
+ ///
+ /// Stops sharing the LocalDB instance.
+ ///
+ void Unshare();
+ }
+}
diff --git a/src/SqlLocalDb/ISqlLocalDbInstanceManagerExtensions.cs b/src/SqlLocalDb/ISqlLocalDbInstanceManagerExtensions.cs
new file mode 100644
index 00000000..da3beee8
--- /dev/null
+++ b/src/SqlLocalDb/ISqlLocalDbInstanceManagerExtensions.cs
@@ -0,0 +1,54 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using System;
+using System.ComponentModel;
+using System.Data.SqlClient;
+
+namespace MartinCostello.SqlLocalDb
+{
+ ///
+ /// A class containing extension methods for the interface. This class cannot be inherited.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static class ISqlLocalDbInstanceManagerExtensions
+ {
+ ///
+ /// Creates a connection to the LocalDB instance.
+ ///
+ /// The associated with the instance to create a connection to.
+ ///
+ /// An instance of that can be used to connect to the LocalDB instance.
+ ///
+ ///
+ /// is .
+ ///
+ public static SqlConnection CreateConnection(this ISqlLocalDbInstanceManager manager)
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException(nameof(manager));
+ }
+
+ return manager.GetInstanceInfo().CreateConnection();
+ }
+
+ ///
+ /// Restarts the specified instance.
+ ///
+ /// The associated with the instance to restart.
+ ///
+ /// is .
+ ///
+ public static void Restart(this ISqlLocalDbInstanceManager manager)
+ {
+ if (manager == null)
+ {
+ throw new ArgumentNullException(nameof(manager));
+ }
+
+ manager.Stop();
+ manager.Start();
+ }
+ }
+}
diff --git a/src/SqlLocalDb/ISqlLocalDbProvider.cs b/src/SqlLocalDb/ISqlLocalDbProvider.cs
deleted file mode 100644
index 4eb7ed18..00000000
--- a/src/SqlLocalDb/ISqlLocalDbProvider.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// ISqlLocalDbProvider.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-using System.Collections.Generic;
-
-namespace System.Data.SqlLocalDb
-{
- ///
- /// Defines methods for obtaining instances of .
- ///
- public interface ISqlLocalDbProvider
- {
- ///
- /// Creates a new instance of .
- ///
- /// The name of the SQL Server LocalDB instance to create.
- ///
- /// The created instance of .
- ///
- ISqlLocalDbInstance CreateInstance(string instanceName);
-
- ///
- /// Returns an existing instance of .
- ///
- /// The name of the SQL Server LocalDB instance to return.
- ///
- /// The existing instance of .
- ///
- ISqlLocalDbInstance GetInstance(string instanceName);
-
- ///
- /// Returns information about the available SQL Server LocalDB instances.
- ///
- ///
- /// An containing information
- /// about the available SQL Server LocalDB instances on the current machine.
- ///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Design",
- "CA1024:UsePropertiesWhereAppropriate",
- Justification = "Requires querying the native LocalDB API.")]
- IList GetInstances();
-
- ///
- /// Returns information about the installed SQL Server LocalDB version(s).
- ///
- ///
- /// An containing information
- /// about the SQL Server LocalDB version(s) installed on the current machine.
- ///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Design",
- "CA1024:UsePropertiesWhereAppropriate",
- Justification = "Requires querying the native LocalDB API.")]
- IList GetVersions();
- }
-}
diff --git a/src/SqlLocalDb/ISqlLocalDbVersionInfo.cs b/src/SqlLocalDb/ISqlLocalDbVersionInfo.cs
index 207c22e0..970f0049 100644
--- a/src/SqlLocalDb/ISqlLocalDbVersionInfo.cs
+++ b/src/SqlLocalDb/ISqlLocalDbVersionInfo.cs
@@ -1,16 +1,9 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// ISqlLocalDbVersionInfo.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
-namespace System.Data.SqlLocalDb
+using System;
+
+namespace MartinCostello.SqlLocalDb
{
///
/// Defines information about a version of SQL Server LocalDB.
@@ -20,25 +13,16 @@ public interface ISqlLocalDbVersionInfo
///
/// Gets a value indicating whether the instance files exist on disk.
///
- bool Exists
- {
- get;
- }
+ bool Exists { get; }
///
/// Gets the version name.
///
- string Name
- {
- get;
- }
+ string Name { get; }
///
/// Gets the version.
///
- Version Version
- {
- get;
- }
+ Version Version { get; }
}
}
diff --git a/src/SqlLocalDb/Interop/IRegistry.cs b/src/SqlLocalDb/Interop/IRegistry.cs
new file mode 100644
index 00000000..06ad7c49
--- /dev/null
+++ b/src/SqlLocalDb/Interop/IRegistry.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+namespace MartinCostello.SqlLocalDb.Interop
+{
+ ///
+ /// Defines a method for opening a registry sub-key.
+ ///
+ internal interface IRegistry
+ {
+ ///
+ /// Retrieves a sub-key as read-only.
+ ///
+ /// The name or path of the sub-key to open as read-only.
+ ///
+ /// The sub-key requested, or if the operation failed.
+ ///
+ IRegistryKey OpenSubKey(string keyName);
+ }
+}
diff --git a/src/SqlLocalDb/Interop/IRegistryKey.cs b/src/SqlLocalDb/Interop/IRegistryKey.cs
new file mode 100644
index 00000000..9040b3ec
--- /dev/null
+++ b/src/SqlLocalDb/Interop/IRegistryKey.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using System;
+
+namespace MartinCostello.SqlLocalDb.Interop
+{
+ ///
+ /// Defines a registry sub-key.
+ ///
+ internal interface IRegistryKey : IRegistry, IDisposable
+ {
+ ///
+ /// Retrieves an array of strings that contains all the sub-key names.
+ ///
+ ///
+ /// An array of strings that contains the names of the sub-keys for the current key.
+ ///
+ string[] GetSubKeyNames();
+
+ ///
+ /// Retrieves the value associated with the specified name.
+ ///
+ /// The name of the value to retrieve. This string is not case-sensitive.
+ ///
+ /// The value associated with , or if is not found.
+ ///
+ string GetValue(string name);
+ }
+}
diff --git a/src/SqlLocalDb/NativeMethods.cs b/src/SqlLocalDb/Interop/LocalDbInstanceApi.cs
similarity index 69%
rename from src/SqlLocalDb/NativeMethods.cs
rename to src/SqlLocalDb/Interop/LocalDbInstanceApi.cs
index 75c6186c..3b91c29d 100644
--- a/src/SqlLocalDb/NativeMethods.cs
+++ b/src/SqlLocalDb/Interop/LocalDbInstanceApi.cs
@@ -1,212 +1,192 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// NativeMethods.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
-using System.Security;
using System.Text;
-using Microsoft.Win32;
+using Microsoft.Extensions.Logging;
-namespace System.Data.SqlLocalDb
+namespace MartinCostello.SqlLocalDb.Interop
{
///
- /// A class containing native P/Invoke methods. This class cannot be inherited.
+ /// A class containing methods for interop with the SQL LocalDB Instance API. This class cannot be inherited.
///
- [SecurityCritical]
- internal static class NativeMethods
+ internal sealed class LocalDbInstanceApi : IDisposable
{
///
/// The maximum size of SQL Server LocalDB connection string.
///
- internal const int LOCALDB_MAX_SQLCONNECTION_BUFFER_SIZE = 260;
+ internal const int MaximumSqlConnectionStringBufferLength = 260;
///
/// The maximum size of SQL Server LocalDB instance names.
///
- internal const int MAX_LOCALDB_INSTANCE_NAME_LENGTH = 128;
+ internal const int MaximumInstanceNameLength = 128;
///
- /// The maximum size of an SQL Server LocalDB version string.
+ /// The maximum size of a SQL Server LocalDB version string.
///
- internal const int MAX_LOCALDB_VERSION_LENGTH = 43;
+ internal const int MaximumInstanceVersionLength = 43;
///
/// The maximum length of a SID string.
///
- internal const int MAX_STRING_SID_LENGTH = 186;
+ internal const int MaximumSidStringLength = 186;
///
/// Specifies that error messages that are too long should be truncated.
///
- private const int LOCALDB_TRUNCATE_ERR_MESSAGE = 1;
+ private const int LocalDbTruncateErrorMessage = 1;
///
- /// This value represents the recommended maximum number of directories an application should include in its DLL search path.
+ /// An array containing the null character. This field is read-only.
///
- ///
- /// Only supported on Windows Vista, 7, Server 2008 and Server 2008 R2 with KB2533623.
- /// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179%28v=vs.85%29.aspx.
- ///
- private const int LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000;
+ private static readonly char[] _nullArray = new char[] { '\0' };
///
- /// The name of the Windows Kernel library.
+ /// Synchronization object to protect loading the native library and its functions. This field is read-only.
///
- private const string KernelLibName = "kernel32.dll";
+ private readonly object _syncRoot = new object();
///
- /// An array containing the '\0' character. This field is read-only.
+ /// Whether the instance has been disposed of.
///
- private static readonly char[] _nullArray = new char[] { '\0' };
+ private bool _disposed;
///
- /// Synchronization object to protect loading the native library and its functions.
+ /// The path of the library that was loaded.
///
- private static readonly object _syncRoot = new object();
+ private string _libraryPath;
///
/// The handle to the native SQL LocalDB API.
///
- private static SafeLibraryHandle _localDB;
+ private SafeLibraryHandle _handle;
///
/// The delegate to the LocalDBCreateInstance LocalDB API function.
///
- private static Functions.LocalDBCreateInstance _localDBCreateInstance;
+ private Functions.LocalDBCreateInstance _localDBCreateInstance;
///
/// The delegate to the LocalDBDeleteInstance LocalDB API function.
///
- private static Functions.LocalDBDeleteInstance _localDBDeleteInstance;
+ private Functions.LocalDBDeleteInstance _localDBDeleteInstance;
///
/// The delegate to the LocalDBFormatMessage LocalDB API function.
///
- private static Functions.LocalDBFormatMessage _localDBFormatMessage;
+ private Functions.LocalDBFormatMessage _localDBFormatMessage;
///
/// The delegate to the LocalDBGetInstanceInfo LocalDB API function.
///
- private static Functions.LocalDBGetInstanceInfo _localDBGetInstanceInfo;
+ private Functions.LocalDBGetInstanceInfo _localDBGetInstanceInfo;
///
/// The delegate to the LocalDBGetInstances LocalDB API function.
///
- private static Functions.LocalDBGetInstances _localDBGetInstances;
+ private Functions.LocalDBGetInstances _localDBGetInstances;
///
/// The delegate to the LocalDBGetVersionInfo LocalDB API function.
///
- private static Functions.LocalDBGetVersionInfo _localDBGetVersionInfo;
+ private Functions.LocalDBGetVersionInfo _localDBGetVersionInfo;
///
/// The delegate to the LocalDBGetVersions LocalDB API function.
///
- private static Functions.LocalDBGetVersions _localDBGetVersions;
+ private Functions.LocalDBGetVersions _localDBGetVersions;
///
/// The delegate to the LocalDBShareInstance LocalDB API function.
///
- private static Functions.LocalDBShareInstance _localDBShareInstance;
+ private Functions.LocalDBShareInstance _localDBShareInstance;
///
/// The delegate to the LocalDBStartInstance LocalDB API function.
///
- private static Functions.LocalDBStartInstance _localDBStartInstance;
+ private Functions.LocalDBStartInstance _localDBStartInstance;
///
/// The delegate to the LocalDBStartTracing LocalDB API function.
///
- private static Functions.LocalDBStartTracing _localDBStartTracing;
+ private Functions.LocalDBStartTracing _localDBStartTracing;
///
/// The delegate to the LocalDBStopInstance LocalDB API function.
///
- private static Functions.LocalDBStopInstance _localDBStopInstance;
+ private Functions.LocalDBStopInstance _localDBStopInstance;
///
/// The delegate to the LocalDBStopTracing LocalDB API function.
///
- private static Functions.LocalDBStopTracing _localDBStopTracing;
+ private Functions.LocalDBStopTracing _localDBStopTracing;
///
/// The delegate to the LocalDBUnshareInstance LocalDB API function.
///
- private static Functions.LocalDBUnshareInstance _localDBUnshareInstance;
+ private Functions.LocalDBUnshareInstance _localDBUnshareInstance;
///
- /// The to use.
+ /// Initializes a new instance of the class.
///
- private static IRegistry _registry;
+ /// The version of the SQL LocalDB Instance API to load.
+ /// The to use.
+ /// The logger to use.
+ internal LocalDbInstanceApi(string apiVersion, IRegistry registry, ILogger logger)
+ {
+ ApiVersion = apiVersion;
+ Registry = registry;
+ Logger = logger;
+ }
///
- /// Defines a method for opening a registry sub-key.
+ /// Finalizes an instance of the class.
///
- internal interface IRegistry
- {
- ///
- /// Retrieves a sub-key as read-only.
- ///
- /// The name or path of the sub-key to open as read-only.
- ///
- /// The sub-key requested, or if the operation failed.
- ///
- IRegistryKey OpenSubKey(string keyName);
- }
+ ~LocalDbInstanceApi() => Dispose(false);
///
- /// Defines a registry sub-key.
+ /// Gets the version of the SQL LocalDB native API loaded, if any.
///
- internal interface IRegistryKey : IRegistry, IDisposable
- {
- ///
- /// Retrieves an array of strings that contains all the sub-key names.
- ///
- ///
- /// An array of strings that contains the names of the sub-keys for the current key.
- ///
- string[] GetSubKeyNames();
+ internal Version NativeApiVersion { get; private set; }
- ///
- /// Retrieves the value associated with the specified name.
- ///
- /// The name of the value to retrieve. This string is not case-sensitive.
- ///
- /// The value associated with , or if is not found.
- ///
- string GetValue(string name);
- }
+ ///
+ /// Gets the API version to use.
+ ///
+ private string ApiVersion { get; }
///
- /// Gets the version of the SQL LocalDB native API loaded, if any.
+ /// Gets the to use.
+ ///
+ private ILogger Logger { get; }
+
+ ///
+ /// Gets the to use.
///
- internal static Version NativeApiVersion
+ private IRegistry Registry { get; }
+
+ ///
+ public void Dispose()
{
- get;
- private set;
+ Dispose(true);
+ GC.SuppressFinalize(this);
}
///
- /// Gets or sets the to use.
+ /// Marshals the specified of to a .
///
- ///
- /// Used for unit testing.
- ///
- internal static IRegistry Registry
+ /// The array to marshal as a .
+ ///
+ /// A representation of .
+ ///
+ internal static string MarshalString(byte[] bytes)
{
- get { return _registry ?? WindowsRegistry.Instance; }
- set { _registry = value; }
+ Debug.Assert(bytes != null, "bytes cannot be null.");
+ return Encoding.Unicode.GetString(bytes).TrimEnd(_nullArray);
}
///
@@ -216,7 +196,7 @@ internal static IRegistry Registry
/// The name for the LocalDB instance to create.
/// Reserved for future use. Currently should be set to 0.
/// The HRESULT returned by the LocalDB API.
- internal static int CreateInstance(string wszVersion, string pInstanceName, int dwFlags)
+ internal int CreateInstance(string wszVersion, string pInstanceName, int dwFlags)
{
return EnsureFunctionAndInvoke(
"LocalDBCreateInstance",
@@ -230,7 +210,7 @@ internal static int CreateInstance(string wszVersion, string pInstanceName, int
/// The name of the LocalDB instance to delete.
/// Reserved for future use. Currently should be set to 0.
/// The HRESULT returned by the LocalDB API.
- internal static int DeleteInstance(string pInstanceName, int dwFlags)
+ internal int DeleteInstance(string pInstanceName, int dwFlags)
{
return EnsureFunctionAndInvoke(
"LocalDBDeleteInstance",
@@ -238,16 +218,6 @@ internal static int DeleteInstance(string pInstanceName, int dwFlags)
(function) => function(pInstanceName, dwFlags));
}
- ///
- /// Frees a specified library.
- ///
- /// The handle to the module to free.
- /// Whether the library was successfully unloaded.
- [DllImport(KernelLibName)]
- [return: MarshalAs(UnmanagedType.Bool)]
- [SecurityCritical]
- internal static extern bool FreeLibrary(IntPtr handle);
-
///
/// Returns information for the specified SQL Server Express LocalDB instance,
/// such as whether it exists, the LocalDB version it uses, whether it is running,
@@ -257,7 +227,7 @@ internal static int DeleteInstance(string pInstanceName, int dwFlags)
/// The buffer to store the information about the LocalDB instance.
/// Holds the size of the InstanceInfo buffer.
/// The HRESULT returned by the LocalDB API.
- internal static int GetInstanceInfo(string wszInstanceName, IntPtr pInstanceInfo, int dwInstanceInfoSize)
+ internal int GetInstanceInfo(string wszInstanceName, IntPtr pInstanceInfo, int dwInstanceInfoSize)
{
return EnsureFunctionAndInvoke(
"LocalDBGetInstanceInfo",
@@ -278,7 +248,7 @@ internal static int GetInstanceInfo(string wszInstanceName, IntPtr pInstanceInfo
/// of LocalDB instances found on the user’s workstation.
///
/// The HRESULT returned by the LocalDB API.
- internal static int GetInstanceNames(IntPtr pInstanceNames, ref int lpdwNumberOfInstances)
+ internal int GetInstanceNames(IntPtr pInstanceNames, ref int lpdwNumberOfInstances)
{
var function = EnsureFunction("LocalDBGetInstances", ref _localDBGetInstances);
@@ -303,7 +273,7 @@ internal static int GetInstanceNames(IntPtr pInstanceNames, ref int lpdwNumberOf
/// excluding any trailing nulls.
///
/// The HRESULT returned by the LocalDB API.
- internal static int GetLocalDbError(int hrLocalDB, int dwLanguageId, StringBuilder wszMessage, ref int lpcchMessage)
+ internal int GetLocalDbError(int hrLocalDB, int dwLanguageId, StringBuilder wszMessage, ref int lpcchMessage)
{
var function = EnsureFunction("LocalDBFormatMessage", ref _localDBFormatMessage);
@@ -312,7 +282,7 @@ internal static int GetLocalDbError(int hrLocalDB, int dwLanguageId, StringBuild
return SqlLocalDbErrors.NotInstalled;
}
- return function(hrLocalDB, LOCALDB_TRUNCATE_ERR_MESSAGE, dwLanguageId, wszMessage, ref lpcchMessage);
+ return function(hrLocalDB, LocalDbTruncateErrorMessage, dwLanguageId, wszMessage, ref lpcchMessage);
}
///
@@ -324,7 +294,7 @@ internal static int GetLocalDbError(int hrLocalDB, int dwLanguageId, StringBuild
/// The buffer to store the information about the LocalDB version.
/// Holds the size of the VersionInfo buffer.
/// The HRESULT returned by the LocalDB API.
- internal static int GetVersionInfo(string wszVersionName, IntPtr pVersionInfo, int dwVersionInfoSize)
+ internal int GetVersionInfo(string wszVersionName, IntPtr pVersionInfo, int dwVersionInfoSize)
{
return EnsureFunctionAndInvoke(
"LocalDBGetVersionInfo",
@@ -341,7 +311,7 @@ internal static int GetVersionInfo(string wszVersionName, IntPtr pVersionInfo, i
/// buffer. On output, holds the number of existing LocalDB versions.
///
/// The HRESULT returned by the LocalDB API.
- internal static int GetVersions(IntPtr pVersion, ref int lpdwNumberOfVersions)
+ internal int GetVersions(IntPtr pVersion, ref int lpdwNumberOfVersions)
{
var function = EnsureFunction("LocalDBGetVersions", ref _localDBGetVersions);
@@ -362,7 +332,7 @@ internal static int GetVersions(IntPtr pVersion, ref int lpdwNumberOfVersions)
/// The shared name for the LocalDB instance to share.
/// Reserved for future use. Currently should be set to 0.
/// The HRESULT returned by the LocalDB API.
- internal static int ShareInstance(IntPtr pOwnerSID, string pInstancePrivateName, string pInstanceSharedName, int dwFlags)
+ internal int ShareInstance(IntPtr pOwnerSID, string pInstancePrivateName, string pInstanceSharedName, int dwFlags)
{
return EnsureFunctionAndInvoke(
"LocalDBShareInstance",
@@ -382,7 +352,7 @@ internal static int ShareInstance(IntPtr pOwnerSID, string pInstancePrivateName,
/// too small, contains the required buffer size in characters, including any trailing nulls.
///
/// The HRESULT returned by the LocalDB API.
- internal static int StartInstance(string pInstanceName, int dwFlags, StringBuilder wszSqlConnection, ref int lpcchSqlConnection)
+ internal int StartInstance(string pInstanceName, int dwFlags, StringBuilder wszSqlConnection, ref int lpcchSqlConnection)
{
var function = EnsureFunction("LocalDBStartInstance", ref _localDBStartInstance);
@@ -399,7 +369,7 @@ internal static int StartInstance(string pInstanceName, int dwFlags, StringBuild
/// LocalDB instances owned by the current Windows user.
///
/// The HRESULT returned by the LocalDB API.
- internal static int StartTracing()
+ internal int StartTracing()
{
return EnsureFunctionAndInvoke(
"LocalDBStartTracing",
@@ -417,7 +387,7 @@ internal static int StartTracing()
/// value is 0, this function will return immediately without waiting for the LocalDB instance to stop.
///
/// The HRESULT returned by the LocalDB API.
- internal static int StopInstance(string pInstanceName, StopInstanceOptions options, int ulTimeout)
+ internal int StopInstance(string pInstanceName, StopInstanceOptions options, int ulTimeout)
{
return EnsureFunctionAndInvoke(
"LocalDBStopInstance",
@@ -430,7 +400,7 @@ internal static int StopInstance(string pInstanceName, StopInstanceOptions optio
/// instances owned by the current Windows user.
///
/// The HRESULT returned by the LocalDB API.
- internal static int StopTracing()
+ internal int StopTracing()
{
return EnsureFunctionAndInvoke(
"LocalDBStopTracing",
@@ -448,7 +418,7 @@ internal static int StopTracing()
/// Reserved for future use. Currently should be set to 0.
///
/// The HRESULT returned by the LocalDB API.
- internal static int UnshareInstance(string pInstanceName, int dwFlags)
+ internal int UnshareInstance(string pInstanceName, int dwFlags)
{
return EnsureFunctionAndInvoke(
"LocalDBUnshareInstance",
@@ -456,19 +426,6 @@ internal static int UnshareInstance(string pInstanceName, int dwFlags)
(function) => function(pInstanceName, dwFlags));
}
- ///
- /// Marshals the specified of to a .
- ///
- /// The array to marshal as a .
- ///
- /// A representation of .
- ///
- internal static string MarshalString(byte[] bytes)
- {
- Debug.Assert(bytes != null, "bytes cannot be null.");
- return Encoding.Unicode.GetString(bytes).TrimEnd(_nullArray);
- }
-
///
/// Tries to obtaining the path to the latest version of the SQL LocalDB
/// native API DLL for the currently executing process.
@@ -481,23 +438,16 @@ internal static string MarshalString(byte[] bytes)
/// if the native API path was successfully found;
/// otherwise .
///
- internal static bool TryGetLocalDbApiPath(out string fileName)
+ internal 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);
-
+ string keyName = DeriveLocalDbRegistryKey();
IRegistryKey key = Registry.OpenSubKey(keyName);
if (key == null)
{
- Logger.Warning(Logger.TraceEvent.RegistryKeyNotFound, SR.NativeMethods_RegistryKeyNotFoundFormat, keyName);
+ Logger.RegistryKeyNotFound(keyName);
return false;
}
@@ -508,29 +458,13 @@ internal static bool TryGetLocalDbApiPath(out string fileName)
try
{
// Is there a setting overriding the version to load?
- string overrideVersionString = SqlLocalDbConfig.NativeApiOverrideVersionString;
+ string overrideVersionString = ApiVersion;
foreach (string versionString in key.GetSubKeyNames())
{
- Version version;
-
- try
- {
- version = new Version(versionString);
- }
- catch (ArgumentException)
+ if (!Version.TryParse(versionString, out Version version))
{
- 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);
+ Logger.InvalidRegistryKey(versionString);
continue;
}
@@ -538,7 +472,7 @@ internal static bool TryGetLocalDbApiPath(out string fileName)
overrideVersion == null &&
string.Equals(versionString, overrideVersionString, StringComparison.OrdinalIgnoreCase))
{
- Logger.Verbose(Logger.TraceEvent.NativeApiVersionOverriddenByUser, SR.NativeMethods_ApiVersionOverriddenByUserFormat, version);
+ Logger.NativeApiVersionOverriddenByUser(version);
overrideVersion = version;
}
@@ -551,19 +485,14 @@ internal static bool TryGetLocalDbApiPath(out string fileName)
if (!string.IsNullOrEmpty(overrideVersionString) && overrideVersion == null)
{
- Logger.Warning(
- Logger.TraceEvent.NativeApiVersionOverrideNotFound,
- SR.NativeMethods_OverrideVersionNotFoundFormat,
- overrideVersionString,
- Environment.MachineName,
- latestVersion);
+ Logger.NativeApiVersionOverrideNotFound(overrideVersionString);
}
Version versionToUse = overrideVersion ?? latestVersion;
if (versionToUse != null)
{
- using (var subkey = key.OpenSubKey(versionToUse.ToString()))
+ using (IRegistryKey subkey = key.OpenSubKey(versionToUse.ToString()))
{
path = subkey.GetValue("InstanceAPIPath");
}
@@ -578,13 +507,13 @@ internal static bool TryGetLocalDbApiPath(out string fileName)
if (string.IsNullOrEmpty(path))
{
- Logger.Warning(Logger.TraceEvent.NoNativeApiFound, SR.NativeMethods_NoNativeApiFound);
+ Logger.NativeApiNotFound();
return false;
}
if (!File.Exists(path))
{
- Logger.Error(Logger.TraceEvent.NativeApiPathNotFound, SR.NativeMethods_NativeApiNotFoundFormat, path);
+ Logger.NativeApiLibraryNotFound(path);
return false;
}
@@ -593,43 +522,21 @@ internal static bool TryGetLocalDbApiPath(out string fileName)
}
///
- /// Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).
+ /// Derives the name of the Windows registry key name to use to locate the SQL LocalDB Instance API.
///
- /// A handle to the DLL module that contains the function or variable.
- /// The function or variable name, or the function's ordinal value.
///
- /// If the function succeeds, the return value is the address of the exported function or variable.
- /// If the function fails, the return value is .
+ /// The registry key name to use for the current process.
///
- ///
- /// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx.
- ///
- [DllImport(KernelLibName, BestFitMapping = false, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true)]
- private static extern IntPtr GetProcAddress(
- SafeLibraryHandle hModule,
- [MarshalAs(UnmanagedType.LPStr)]
- string lpProcName);
+ private static string DeriveLocalDbRegistryKey()
+ {
+ // Open the appropriate Registry key if running as a 32-bit process on a 64-bit machine
+ bool isWow64Process = Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess;
- ///
- /// Loads the specified module into the address space of the calling process.
- /// The specified module may cause other modules to be loaded.
- ///
- /// The name of the module.
- /// This parameter is reserved for future use. It must be .
- /// The action to be taken when loading the module.
- ///
- /// If the function succeeds, the return value is a handle to the module.
- /// If the function fails, the return value is .
- ///
- ///
- /// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179%28v=vs.85%29.aspx.
- ///
- [DllImport(KernelLibName, BestFitMapping = false, CharSet = CharSet.Ansi, SetLastError = true, ThrowOnUnmappableChar = true)]
- private static extern SafeLibraryHandle LoadLibraryEx(
- [MarshalAs(UnmanagedType.LPStr)]
- string lpFileName,
- IntPtr hFile,
- int dwFlags);
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ @"SOFTWARE\{0}Microsoft\Microsoft SQL Server Local DB\Installed Versions",
+ isWow64Process ? @"Wow6432Node\" : string.Empty);
+ }
///
/// Ensures that the specified delegate to an unmanaged function is initialized.
@@ -641,8 +548,8 @@ private static extern SafeLibraryHandle LoadLibraryEx(
/// An instance of that points to the specified unmanaged
/// function, if found; otherwise .
///
- private static T EnsureFunction(string functionName, ref T function)
- where T : class
+ private T EnsureFunction(string functionName, ref T function)
+ where T : Delegate
{
Debug.Assert(functionName != null, "functionName cannot be null.");
@@ -671,8 +578,8 @@ private static T EnsureFunction(string functionName, ref T function)
/// The result of invoking , if the function was
/// initialized; otherwise the value of is returned.
///
- private static int EnsureFunctionAndInvoke(string functionName, ref T function, Func callback)
- where T : class
+ private int EnsureFunctionAndInvoke(string functionName, ref T function, Func callback)
+ where T : Delegate
{
Debug.Assert(callback != null, "callback cannot be null.");
@@ -688,13 +595,13 @@ private static int EnsureFunctionAndInvoke(string functionName, ref T functio
/// A pointing to the loaded
/// SQL LocalDB API, if successful; otherwise .
///
- private static SafeLibraryHandle EnsureLocalDBLoaded()
+ private SafeLibraryHandle EnsureLocalDBLoaded()
{
- if (_localDB == null)
+ if (_handle == null)
{
lock (_syncRoot)
{
- if (_localDB == null)
+ if (_handle == null)
{
if (!TryGetLocalDbApiPath(out string fileName))
{
@@ -707,36 +614,36 @@ private static SafeLibraryHandle EnsureLocalDBLoaded()
// to use the more secure flags when calling LoadLibraryEx
bool hasKB2533623;
- using (var hModule = LoadLibraryEx(KernelLibName, IntPtr.Zero, 0))
+ using (var hModule = NativeMethods.LoadLibraryEx(NativeMethods.KernelLibName, IntPtr.Zero, 0))
{
// If the AddDllDirectory function is found then the flags are supported
- hasKB2533623 = GetProcAddress(hModule, "AddDllDirectory") != IntPtr.Zero;
+ hasKB2533623 = NativeMethods.GetProcAddress(hModule, "AddDllDirectory") != IntPtr.Zero;
}
if (hasKB2533623)
{
// If KB2533623 is installed then specify the more secure LOAD_LIBRARY_SEARCH_DEFAULT_DIRS in dwFlags
- dwFlags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS;
+ dwFlags = NativeMethods.LOAD_LIBRARY_SEARCH_DEFAULT_DIRS;
}
- _localDB = LoadLibraryEx(fileName, IntPtr.Zero, dwFlags);
+ _handle = NativeMethods.LoadLibraryEx(fileName, IntPtr.Zero, dwFlags);
- if (_localDB == null ||
- _localDB.IsInvalid)
+ if (_handle == null || _handle.IsInvalid)
{
int error = Marshal.GetLastWin32Error();
- Logger.Error(Logger.TraceEvent.NativeApiLoadFailed, SR.NativeMethods_NativeApiLoadFailedFormat, fileName, error);
- _localDB = null;
+ Logger.NativeApiLoadFailed(fileName, error);
+ _handle = null;
}
else
{
- Logger.Verbose(Logger.TraceEvent.NativeApiLoaded, SR.NativeMethods_NativeApiLoadedFormat, fileName);
+ Logger.NativeApiLoaded(fileName);
+ _libraryPath = fileName;
}
}
}
}
- return _localDB;
+ return _handle;
}
///
@@ -748,8 +655,8 @@ private static SafeLibraryHandle EnsureLocalDBLoaded()
/// An instance of that points to the specified unmanaged
/// function, if found; otherwise .
///
- private static T GetDelegate(string functionName)
- where T : class
+ private T GetDelegate(string functionName)
+ where T : Delegate
{
Debug.Assert(functionName != null, "functionName cannot be null.");
@@ -757,21 +664,51 @@ private static T GetDelegate(string functionName)
if (handle == null)
{
- Logger.Warning(Logger.TraceEvent.NativeApiNotLoaded, SR.NativeMethods_NativeApiNotLoaded);
+ Logger.NativeApiNotLoaded();
return null;
}
- IntPtr ptr = GetProcAddress(handle, functionName);
+ IntPtr ptr = NativeMethods.GetProcAddress(handle, functionName);
if (ptr == IntPtr.Zero)
{
- Logger.Error(Logger.TraceEvent.FunctionNotFound, SR.NativeMethods_FunctionNotFoundFormat, functionName);
+ Logger.NativeApiFunctionNotFound(functionName);
return null;
}
return Marshal.GetDelegateForFunctionPointer(ptr);
}
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ ///
+ /// to release both managed and unmanaged resources;
+ /// to release only unmanaged resources.
+ ///
+ private void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // Dispose of managed resources
+ }
+
+ // Dispose of unmanaged resources
+ if (_handle != null)
+ {
+ _handle.Dispose();
+
+ Logger.NativeApiUnloaded(_libraryPath);
+
+ _libraryPath = null;
+ }
+
+ _disposed = true;
+ }
+ }
+
///
/// A class containing delegates to functions in the SQL LocalDB native API.
///
@@ -846,8 +783,7 @@ internal delegate int LocalDBFormatMessage(
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int LocalDBGetInstanceInfo(
- [MarshalAs(UnmanagedType.LPWStr)]
- string wszInstanceName,
+ [MarshalAs(UnmanagedType.LPWStr)] string wszInstanceName,
IntPtr pInstanceInfo,
int dwInstanceInfoSize);
@@ -884,8 +820,7 @@ internal delegate int LocalDBGetInstanceInfo(
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int LocalDBGetVersionInfo(
- [MarshalAs(UnmanagedType.LPWStr)]
- string wszVersionName,
+ [MarshalAs(UnmanagedType.LPWStr)] string wszVersionName,
IntPtr pVersionInfo,
int dwVersionInfoSize);
@@ -971,8 +906,7 @@ internal delegate int LocalDBStartInstance(
///
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int LocalDBStopInstance(
- [MarshalAs(UnmanagedType.LPWStr)]
- string pInstanceName,
+ [MarshalAs(UnmanagedType.LPWStr)] string pInstanceName,
int dwFlags,
int ulTimeout);
@@ -997,74 +931,8 @@ internal delegate int LocalDBStopInstance(
/// See http://technet.microsoft.com/en-us/library/hh215383.aspx.
///
internal delegate int LocalDBUnshareInstance(
- [MarshalAs(UnmanagedType.LPWStr)]
- string pInstanceName,
+ [MarshalAs(UnmanagedType.LPWStr)] string pInstanceName,
int dwFlags);
}
-
- ///
- /// A class representing an implementation of for the Windows registry. This class cannot be inherited.
- ///
- private sealed class WindowsRegistry : IRegistry
- {
- ///
- /// The singleton instance of . This field is read-only.
- ///
- internal static readonly WindowsRegistry Instance = new WindowsRegistry();
-
- ///
- /// Prevents a default instance of the class from being created.
- ///
- private WindowsRegistry()
- {
- }
-
- ///
- public IRegistryKey OpenSubKey(string keyName)
- {
- var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(keyName, writable: false);
- return key == null ? null : new WindowsRegistryKey(key);
- }
- }
-
- ///
- /// A class representing an implementation of for a Windows registry key. This class cannot be inherited.
- ///
- private sealed class WindowsRegistryKey : IRegistryKey
- {
- ///
- /// The wrapped by the instance. This field is read-only.
- ///
- private readonly RegistryKey _key;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The to wrap.
- internal WindowsRegistryKey(RegistryKey key)
- {
- Debug.Assert(key != null, "key cannot be null.");
- _key = key;
- }
-
- ///
- void IDisposable.Dispose()
- {
- _key.Dispose();
- }
-
- ///
- public string[] GetSubKeyNames() => _key.GetSubKeyNames();
-
- ///
- public string GetValue(string name) => _key.GetValue(name, null, RegistryValueOptions.None) as string;
-
- ///
- public IRegistryKey OpenSubKey(string keyName)
- {
- var key = _key.OpenSubKey(keyName);
- return key == null ? null : new WindowsRegistryKey(key);
- }
- }
}
}
diff --git a/src/SqlLocalDb/LocalDbInstanceInfo.cs b/src/SqlLocalDb/Interop/LocalDbInstanceInfo.cs
similarity index 82%
rename from src/SqlLocalDb/LocalDbInstanceInfo.cs
rename to src/SqlLocalDb/Interop/LocalDbInstanceInfo.cs
index 4b19cdfb..935ce411 100644
--- a/src/SqlLocalDb/LocalDbInstanceInfo.cs
+++ b/src/SqlLocalDb/Interop/LocalDbInstanceInfo.cs
@@ -1,19 +1,11 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// LocalDBInstanceInfo.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
-namespace System.Data.SqlLocalDb
+namespace MartinCostello.SqlLocalDb.Interop
{
///
/// A structure representing information about a SQL Server LocalDB instance.
@@ -46,7 +38,7 @@ internal struct LocalDbInstanceInfo : ISqlLocalDbInstanceInfo
///
[MarshalAs(
UnmanagedType.ByValArray,
- SizeConst = (NativeMethods.MAX_LOCALDB_INSTANCE_NAME_LENGTH + 1) * sizeof(char))]
+ SizeConst = (LocalDbInstanceApi.MaximumInstanceNameLength + 1) * sizeof(char))]
internal byte[] InstanceName;
///
@@ -111,7 +103,7 @@ internal struct LocalDbInstanceInfo : ISqlLocalDbInstanceInfo
///
/// Maps to the ftLastStartUTC member.
///
- internal Runtime.InteropServices.ComTypes.FILETIME LastStartUtc;
+ internal System.Runtime.InteropServices.ComTypes.FILETIME LastStartUtc;
///
/// The named pipe that should be used to communicate with the instance.
@@ -121,7 +113,7 @@ internal struct LocalDbInstanceInfo : ISqlLocalDbInstanceInfo
///
[MarshalAs(
UnmanagedType.ByValArray,
- SizeConst = NativeMethods.LOCALDB_MAX_SQLCONNECTION_BUFFER_SIZE * sizeof(char))]
+ SizeConst = LocalDbInstanceApi.MaximumSqlConnectionStringBufferLength * sizeof(char))]
internal byte[] Connection;
///
@@ -140,7 +132,7 @@ internal struct LocalDbInstanceInfo : ISqlLocalDbInstanceInfo
///
[MarshalAs(
UnmanagedType.ByValArray,
- SizeConst = (NativeMethods.MAX_LOCALDB_INSTANCE_NAME_LENGTH + 1) * sizeof(char))]
+ SizeConst = (LocalDbInstanceApi.MaximumInstanceNameLength + 1) * sizeof(char))]
internal byte[] SharedInstanceName;
///
@@ -151,7 +143,7 @@ internal struct LocalDbInstanceInfo : ISqlLocalDbInstanceInfo
///
[MarshalAs(
UnmanagedType.ByValArray,
- SizeConst = (NativeMethods.MAX_STRING_SID_LENGTH + 1) * sizeof(char))]
+ SizeConst = (LocalDbInstanceApi.MaximumSidStringLength + 1) * sizeof(char))]
internal byte[] OwnerSID;
///
@@ -213,28 +205,28 @@ DateTime ISqlLocalDbInstanceInfo.LastStartTimeUtc
///
/// Gets the name of the instance.
///
- string ISqlLocalDbInstanceInfo.Name => NativeMethods.MarshalString(InstanceName);
+ string ISqlLocalDbInstanceInfo.Name => LocalDbInstanceApi.MarshalString(InstanceName);
///
/// Gets the named pipe that should be used to communicate with the instance.
///
- string ISqlLocalDbInstanceInfo.NamedPipe => NativeMethods.MarshalString(Connection);
+ string ISqlLocalDbInstanceInfo.NamedPipe => LocalDbInstanceApi.MarshalString(Connection);
///
/// Gets the SID of the LocalDB instance owner if the instance is shared.
///
- string ISqlLocalDbInstanceInfo.OwnerSid => NativeMethods.MarshalString(OwnerSID);
+ string ISqlLocalDbInstanceInfo.OwnerSid => LocalDbInstanceApi.MarshalString(OwnerSID);
///
/// Gets the shared name of the LocalDB instance if the instance is shared.
///
- string ISqlLocalDbInstanceInfo.SharedName => NativeMethods.MarshalString(SharedInstanceName);
+ string ISqlLocalDbInstanceInfo.SharedName => LocalDbInstanceApi.MarshalString(SharedInstanceName);
///
/// Gets the name to display in the debugger
///
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- [Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
private string DebuggerDisplayName => ((ISqlLocalDbInstanceInfo)this).Name;
}
}
diff --git a/src/SqlLocalDb/LocalDbVersionInfo.cs b/src/SqlLocalDb/Interop/LocalDbVersionInfo.cs
similarity index 75%
rename from src/SqlLocalDb/LocalDbVersionInfo.cs
rename to src/SqlLocalDb/Interop/LocalDbVersionInfo.cs
index a13ef98e..53919467 100644
--- a/src/SqlLocalDb/LocalDbVersionInfo.cs
+++ b/src/SqlLocalDb/Interop/LocalDbVersionInfo.cs
@@ -1,28 +1,19 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// LocalDBVersionInfo.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
-namespace System.Data.SqlLocalDb
+namespace MartinCostello.SqlLocalDb.Interop
{
///
- /// A structure representing version about an SQL Server LocalDB version.
+ /// A structure representing version about a SQL Server LocalDB version.
///
///
/// See http://msdn.microsoft.com/en-us/library/hh234365.aspx.
///
[DebuggerDisplay("{DebuggerDisplayName}")]
- [Serializable]
[StructLayout(LayoutKind.Sequential)]
internal struct LocalDbVersionInfo : ISqlLocalDbVersionInfo
{
@@ -45,7 +36,7 @@ internal struct LocalDbVersionInfo : ISqlLocalDbVersionInfo
///
/// Maps to the wszVersion member.
///
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = (NativeMethods.MAX_LOCALDB_VERSION_LENGTH + 1) * sizeof(char))]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (LocalDbInstanceApi.MaximumInstanceVersionLength + 1) * sizeof(char))]
internal byte[] Name;
///
@@ -96,7 +87,7 @@ internal struct LocalDbVersionInfo : ISqlLocalDbVersionInfo
///
/// Gets the version name.
///
- string ISqlLocalDbVersionInfo.Name => NativeMethods.MarshalString(Name);
+ string ISqlLocalDbVersionInfo.Name => LocalDbInstanceApi.MarshalString(Name);
///
/// Gets the version.
@@ -107,7 +98,7 @@ internal struct LocalDbVersionInfo : ISqlLocalDbVersionInfo
/// Gets the name to display in the debugger
///
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- [Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
private string DebuggerDisplayName => ((ISqlLocalDbVersionInfo)this).Name;
}
}
diff --git a/src/SqlLocalDb/Interop/NativeMethods.cs b/src/SqlLocalDb/Interop/NativeMethods.cs
new file mode 100644
index 00000000..31a3b69c
--- /dev/null
+++ b/src/SqlLocalDb/Interop/NativeMethods.cs
@@ -0,0 +1,74 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace MartinCostello.SqlLocalDb.Interop
+{
+ ///
+ /// A class containing native P/Invoke methods. This class cannot be inherited.
+ ///
+ internal static class NativeMethods
+ {
+ ///
+ /// This value represents the recommended maximum number of directories an application should include in its DLL search path.
+ ///
+ ///
+ /// Only supported on Windows Vista, 7, Server 2008 and Server 2008 R2 with KB2533623.
+ /// See https://docs.microsoft.com/en-gb/windows/desktop/api/libloaderapi/nf-libloaderapi-loadlibraryexa.
+ ///
+ internal const int LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000;
+
+ ///
+ /// The name of the Windows Kernel library.
+ ///
+ internal const string KernelLibName = "kernel32.dll";
+
+ ///
+ /// Frees a specified library.
+ ///
+ /// The handle to the module to free.
+ /// Whether the library was successfully unloaded.
+ [DllImport(KernelLibName)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static extern bool FreeLibrary(IntPtr handle);
+
+ ///
+ /// Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).
+ ///
+ /// A handle to the DLL module that contains the function or variable.
+ /// The function or variable name, or the function's ordinal value.
+ ///
+ /// If the function succeeds, the return value is the address of the exported function or variable.
+ /// If the function fails, the return value is .
+ ///
+ ///
+ /// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx.
+ ///
+ [DllImport(KernelLibName, BestFitMapping = false, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true)]
+ internal static extern IntPtr GetProcAddress(
+ SafeLibraryHandle hModule,
+ [MarshalAs(UnmanagedType.LPStr)] string lpProcName);
+
+ ///
+ /// Loads the specified module into the address space of the calling process.
+ /// The specified module may cause other modules to be loaded.
+ ///
+ /// The name of the module.
+ /// This parameter is reserved for future use. It must be .
+ /// The action to be taken when loading the module.
+ ///
+ /// If the function succeeds, the return value is a handle to the module.
+ /// If the function fails, the return value is .
+ ///
+ ///
+ /// See https://docs.microsoft.com/en-gb/windows/desktop/api/libloaderapi/nf-libloaderapi-loadlibraryexa.
+ ///
+ [DllImport(KernelLibName, BestFitMapping = false, CharSet = CharSet.Ansi, SetLastError = true, ThrowOnUnmappableChar = true)]
+ internal static extern SafeLibraryHandle LoadLibraryEx(
+ [MarshalAs(UnmanagedType.LPStr)] string lpFileName,
+ IntPtr hFile,
+ int dwFlags);
+ }
+}
diff --git a/src/SqlLocalDb/SafeLibraryHandle.cs b/src/SqlLocalDb/Interop/SafeLibraryHandle.cs
similarity index 60%
rename from src/SqlLocalDb/SafeLibraryHandle.cs
rename to src/SqlLocalDb/Interop/SafeLibraryHandle.cs
index c662f384..3a926061 100644
--- a/src/SqlLocalDb/SafeLibraryHandle.cs
+++ b/src/SqlLocalDb/Interop/SafeLibraryHandle.cs
@@ -1,24 +1,13 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// SafeLibraryHandle.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
-using System.Security;
using Microsoft.Win32.SafeHandles;
-namespace System.Data.SqlLocalDb
+namespace MartinCostello.SqlLocalDb.Interop
{
///
/// A class that represents a handle to a library. This class cannot be inherited.
///
- [SecurityCritical]
internal sealed class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid
{
///
@@ -38,7 +27,6 @@ private SafeLibraryHandle()
/// . In this case, it generates a ReleaseHandleFailed
/// Managed Debugging Assistant.
///
- [SecurityCritical]
protected override bool ReleaseHandle() => NativeMethods.FreeLibrary(handle);
}
}
diff --git a/src/SqlLocalDb/Interop/WindowsRegistry.cs b/src/SqlLocalDb/Interop/WindowsRegistry.cs
new file mode 100644
index 00000000..94c1a74d
--- /dev/null
+++ b/src/SqlLocalDb/Interop/WindowsRegistry.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using Microsoft.Win32;
+
+namespace MartinCostello.SqlLocalDb.Interop
+{
+ ///
+ /// A class representing an implementation of for the Windows registry. This class cannot be inherited.
+ ///
+ internal sealed class WindowsRegistry : IRegistry
+ {
+ ///
+ public IRegistryKey OpenSubKey(string keyName)
+ {
+ RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, writable: false);
+ return key == null ? null : new WindowsRegistryKey(key);
+ }
+ }
+}
diff --git a/src/SqlLocalDb/Interop/WindowsRegistryKey.cs b/src/SqlLocalDb/Interop/WindowsRegistryKey.cs
new file mode 100644
index 00000000..605bc4f5
--- /dev/null
+++ b/src/SqlLocalDb/Interop/WindowsRegistryKey.cs
@@ -0,0 +1,46 @@
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+
+using System;
+using System.Diagnostics;
+using Microsoft.Win32;
+
+namespace MartinCostello.SqlLocalDb.Interop
+{
+ ///
+ /// A class representing an implementation of for a Windows registry key. This class cannot be inherited.
+ ///
+ internal sealed class WindowsRegistryKey : IRegistryKey
+ {
+ ///
+ /// The wrapped by the instance. This field is read-only.
+ ///
+ private readonly RegistryKey _key;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The to wrap.
+ internal WindowsRegistryKey(RegistryKey key)
+ {
+ Debug.Assert(key != null, "key cannot be null.");
+ _key = key;
+ }
+
+ ///
+ void IDisposable.Dispose() => _key.Dispose();
+
+ ///
+ public string[] GetSubKeyNames() => _key.GetSubKeyNames();
+
+ ///
+ public string GetValue(string name) => _key.GetValue(name, null, RegistryValueOptions.None) as string;
+
+ ///
+ public IRegistryKey OpenSubKey(string keyName)
+ {
+ RegistryKey key = _key.OpenSubKey(keyName);
+ return key == null ? null : new WindowsRegistryKey(key);
+ }
+ }
+}
diff --git a/src/SqlLocalDb/Logger.cs b/src/SqlLocalDb/Logger.cs
deleted file mode 100644
index b1d323d8..00000000
--- a/src/SqlLocalDb/Logger.cs
+++ /dev/null
@@ -1,321 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// Logger.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-using System.Diagnostics;
-
-namespace System.Data.SqlLocalDb
-{
- ///
- /// A class that performs logging for the System.Data.SqlLocalDb assembly.
- ///
- [DebuggerStepThrough]
- [Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
- public static class Logger
- {
- ///
- /// The lazily-initialized default to use. This field is read-only.
- ///
- internal static readonly Lazy DefaultLogger = new Lazy(CreateDefaultLogger);
-
- ///
- /// The Trace condition string.
- ///
- private const string TraceCondition = "TRACE";
-
- ///
- /// The to use.
- ///
- private static ILogger _logger;
-
- ///
- /// Gets the current .
- ///
- private static ILogger Current
- {
- get { return _logger ?? DefaultLogger.Value; }
- }
-
- ///
- /// Sets the implementation in use by the assembly.
- ///
- /// The to use, or to use the default implementation.
- [Conditional(TraceCondition)]
- public static void SetLogger(ILogger logger)
- {
- _logger = logger ?? DefaultLogger.Value;
- }
-
- ///
- /// Writes an error trace event to the trace listeners for the assembly's trace source.
- ///
- /// A numeric identifier for the event.
- ///
- /// A composite format string that contains text intermixed with zero or more
- /// format items, which correspond to objects in the args array.
- ///
- ///
- /// An object array containing zero or more objects to format.
- ///
- [Conditional(TraceCondition)]
- public static void Error(int id, string format, params object[] args)
- {
- Current.WriteError(id, format, args);
- }
-
- ///
- /// Writes an informational trace event to the trace listeners for the assembly's trace source.
- ///
- /// A numeric identifier for the event.
- ///
- /// A composite format string that contains text intermixed with zero or more
- /// format items, which correspond to objects in the args array.
- ///
- ///
- /// An object array containing zero or more objects to format.
- ///
- [Conditional(TraceCondition)]
- public static void Information(int id, string format, params object[] args)
- {
- Current.WriteInformation(id, format, args);
- }
-
- ///
- /// Writes a verbose trace event to the trace listeners for the assembly's trace source.
- ///
- /// A numeric identifier for the event.
- ///
- /// A composite format string that contains text intermixed with zero or more
- /// format items, which correspond to objects in the args array.
- ///
- ///
- /// An object array containing zero or more objects to format.
- ///
- [Conditional(TraceCondition)]
- public static void Verbose(int id, string format, params object[] args)
- {
- Current.WriteVerbose(id, format, args);
- }
-
- ///
- /// Writes a warning trace event to the trace listeners for the assembly's trace source.
- ///
- /// A numeric identifier for the event.
- ///
- /// A composite format string that contains text intermixed with zero or more
- /// format items, which correspond to objects in the args array.
- ///
- ///
- /// An object array containing zero or more objects to format.
- ///
- [Conditional(TraceCondition)]
- public static void Warning(int id, string format, params object[] args)
- {
- Current.WriteWarning(id, format, args);
- }
-
- ///
- /// Creates the default implementation to use.
- ///
- ///
- /// The default implementation of .
- ///
- private static ILogger CreateDefaultLogger()
- {
- Type loggerType = SqlLocalDbConfig.LoggerType;
-
- ILogger logger;
-
- if (loggerType == null)
- {
- logger = TraceSourceLogger.Instance;
- }
- else
- {
- try
- {
- // This cast is safe as the configuration section validates that the type implements ILogger
- logger = (ILogger)Activator.CreateInstance(loggerType, nonPublic: true);
- }
- catch (Reflection.TargetInvocationException ex)
- {
- // Log directly to Trace if we cannot create the custom ILogger
- Trace.TraceError(SR.Logger_FailedToCreateCustomLoggerFormat, loggerType.AssemblyQualifiedName, (ex.InnerException ?? ex).Message);
- throw;
- }
- catch (Exception ex)
- {
- // Log directly to Trace if we cannot create the custom ILogger
- Trace.TraceError(SR.Logger_FailedToCreateCustomLoggerFormat, loggerType.AssemblyQualifiedName, ex.Message);
- throw;
- }
- }
-
- return logger;
- }
-
- ///
- /// A class containing trace event Ids. This class cannot be inherited.
- ///
- internal static class TraceEvent
- {
- ///
- /// General usage.
- ///
- internal static readonly int General = 0;
-
- ///
- /// Creating a SQL LocalDB instance.
- ///
- internal static readonly int CreateInstance = 1;
-
- ///
- /// Deleting a SQL LocalDB instance.
- ///
- internal static readonly int DeleteInstance = 2;
-
- ///
- /// Getting information about a SQL LocalDB instance.
- ///
- internal static readonly int GetInstanceInfo = 3;
-
- ///
- /// Getting instance names for SQL LocalDB.
- ///
- internal static readonly int GetInstanceNames = 4;
-
- ///
- /// Getting version information for SQL LocalDB.
- ///
- internal static readonly int GetVersionInfo = 5;
-
- ///
- /// Getting installed versions of SQL LocalDB.
- ///
- internal static readonly int GetVersions = 6;
-
- ///
- /// Sharing a SQL LocalDB instance.
- ///
- internal static readonly int ShareInstance = 7;
-
- ///
- /// Starting a SQL LocalDB instance.
- ///
- internal static readonly int StartInstance = 8;
-
- ///
- /// Starting tracing for a SQL LocalDB.
- ///
- internal static readonly int StartTracing = 9;
-
- ///
- /// Stopping a SQL LocalDB instance.
- ///
- internal static readonly int StopInstance = 10;
-
- ///
- /// Stopping tracing for SQL LocalDB.
- ///
- internal static readonly int StopTracing = 11;
-
- ///
- /// Stopping sharing of an instance of SQL LocalDB.
- ///
- internal static readonly int UnshareInstance = 12;
-
- ///
- /// The SQL LocalDB registry key could not be found or opened.
- ///
- internal static readonly int RegistryKeyNotFound = 13;
-
- ///
- /// An invalid registry key was processed.
- ///
- internal static readonly int InvalidRegistryKey = 14;
-
- ///
- /// An invalid registry key was processed.
- ///
- internal static readonly int NoNativeApiFound = 15;
-
- ///
- /// The native SQL LocalDB API DLL could not be found.
- ///
- internal static readonly int NativeApiPathNotFound = 16;
-
- ///
- /// The native SQL LocalDB API DLL failed to load.
- ///
- internal static readonly int NativeApiLoadFailed = 17;
-
- ///
- /// The native SQL LocalDB API DLL was not loaded.
- ///
- internal static readonly int NativeApiNotLoaded = 18;
-
- ///
- /// The native SQL LocalDB API function could not be found.
- ///
- internal static readonly int FunctionNotFound = 19;
-
- ///
- /// The native SQL LocalDB API was loaded.
- ///
- internal static readonly int NativeApiLoaded = 20;
-
- ///
- /// The version of the native SQL LocalDB API loaded was overridden by the user.
- ///
- internal static readonly int NativeApiVersionOverriddenByUser = 21;
-
- ///
- /// A user instance of SQL LocalDB could not be deleted as it is in use.
- ///
- internal static readonly int DeleteFailedAsInstanceInUse = 22;
-
- ///
- /// The files(s) for a user instance of SQL LocalDB are being deleted.
- ///
- internal static readonly int DeletingInstanceFiles = 23;
-
- ///
- /// The files(s) for a user instance of SQL LocalDB were deleted.
- ///
- internal static readonly int DeletedInstanceFiles = 24;
-
- ///
- /// The files(s) for a user instance of SQL LocalDB could not be deleted.
- ///
- internal static readonly int DeletingInstanceFilesFailed = 25;
-
- ///
- /// The value of the property is invalid.
- ///
- internal static readonly int InvalidLanguageId = 26;
-
- ///
- /// The version of the native SQL LocalDB API specified as the override by the user cannot be found.
- ///
- internal static readonly int NativeApiVersionOverrideNotFound = 27;
-
- ///
- /// A user instance of SQL LocalDB could not be stopped.
- ///
- internal static readonly int StopFailed = 28;
-
- ///
- /// A user instance of SQL LocalDB could not be deleted.
- ///
- internal static readonly int DeleteFailed = 29;
- }
- }
-}
diff --git a/src/SqlLocalDb/MartinCostello.SqlLocalDb.csproj b/src/SqlLocalDb/MartinCostello.SqlLocalDb.csproj
new file mode 100644
index 00000000..262e3951
--- /dev/null
+++ b/src/SqlLocalDb/MartinCostello.SqlLocalDb.csproj
@@ -0,0 +1,27 @@
+
+
+ SQL LocalDB Wrapper
+ full
+ A .NET assembly providing interop with the SQL LocalDB native API from managed code using .NET APIs.
+ true
+ $(NoWarn);CA2235
+ Library
+ MartinCostello.SqlLocalDb
+ MartinCostello.SqlLocalDb
+ $(Description)
+ netstandard2.0
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/SqlLocalDb/Properties/AssemblyInfo.cs b/src/SqlLocalDb/Properties/AssemblyInfo.cs
index cb60e6a4..919cbb67 100644
--- a/src/SqlLocalDb/Properties/AssemblyInfo.cs
+++ b/src/SqlLocalDb/Properties/AssemblyInfo.cs
@@ -1,22 +1,12 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// AssemblyInfo.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-[assembly: CLSCompliant(true)]
[assembly: Guid("963628d3-b23b-4b98-9cec-b0a13b00ddef")]
-[assembly: InternalsVisibleTo("System.Data.SqlLocalDb.TestApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b0b2efbada897147aa03d2076278890aefe2f8023562336d206ec8a719b06e89461c31b43abec615918d509158629f93385930c030494509e418bf396d69ce7dbe0b5b2db1a81543ab42777cb98210677fed69dbeb3237492a7ad69e87a1911ed20eb2d7c300238dc6f6403e3d04a1351c5cb369de4e022b18fbec70f7d21ed")]
-[assembly: InternalsVisibleTo("System.Data.SqlLocalDb.UnitTests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b0b2efbada897147aa03d2076278890aefe2f8023562336d206ec8a719b06e89461c31b43abec615918d509158629f93385930c030494509e418bf396d69ce7dbe0b5b2db1a81543ab42777cb98210677fed69dbeb3237492a7ad69e87a1911ed20eb2d7c300238dc6f6403e3d04a1351c5cb369de4e022b18fbec70f7d21ed")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
+[assembly: InternalsVisibleTo("MartinCostello.SqlLocalDb.TestApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b0b2efbada897147aa03d2076278890aefe2f8023562336d206ec8a719b06e89461c31b43abec615918d509158629f93385930c030494509e418bf396d69ce7dbe0b5b2db1a81543ab42777cb98210677fed69dbeb3237492a7ad69e87a1911ed20eb2d7c300238dc6f6403e3d04a1351c5cb369de4e022b18fbec70f7d21ed")]
+[assembly: InternalsVisibleTo("MartinCostello.SqlLocalDb.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b0b2efbada897147aa03d2076278890aefe2f8023562336d206ec8a719b06e89461c31b43abec615918d509158629f93385930c030494509e418bf396d69ce7dbe0b5b2db1a81543ab42777cb98210677fed69dbeb3237492a7ad69e87a1911ed20eb2d7c300238dc6f6403e3d04a1351c5cb369de4e022b18fbec70f7d21ed")]
diff --git a/src/SqlLocalDb/SR.Designer.cs b/src/SqlLocalDb/SR.Designer.cs
index e64e5140..375afef7 100644
--- a/src/SqlLocalDb/SR.Designer.cs
+++ b/src/SqlLocalDb/SR.Designer.cs
@@ -8,7 +8,7 @@
//
//------------------------------------------------------------------------------
-namespace System.Data.SqlLocalDb {
+namespace MartinCostello.SqlLocalDb {
using System;
@@ -19,7 +19,7 @@ namespace System.Data.SqlLocalDb {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class SR {
@@ -39,7 +39,7 @@ internal SR() {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Data.SqlLocalDb.SR", typeof(SR).Assembly);
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MartinCostello.SqlLocalDb.SR", typeof(SR).Assembly);
resourceMan = temp;
}
return resourceMan;
@@ -61,578 +61,551 @@ internal SR() {
}
///
- /// Looks up a localized string similar to The specified database file name is invalid: {0}.
+ /// Looks up a localized string similar to Created named instance {InstanceName} of SQL LocalDB with version {InstanceVersion}..
///
- internal static string Extensions_InvalidPathFormat {
+ internal static string ILoggerExtensions_CreatedInstanceFormat {
get {
- return ResourceManager.GetString("Extensions_InvalidPathFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_CreatedInstanceFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The current AppDomain has no value set for the Data Directory..
+ /// Looks up a localized string similar to Creating named instance {InstanceName} of SQL LocalDB with version {InstanceVersion}..
///
- internal static string Extensions_NoAppDomainDataDirectory {
+ internal static string ILoggerExtensions_CreatingInstanceFormat {
get {
- return ResourceManager.GetString("Extensions_NoAppDomainDataDirectory", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_CreatingInstanceFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to No connection string named '{0}' can be found in the application configuration file..
+ /// Looks up a localized string similar to Deleted file(s) for SQL LocalDB instance {InstanceName} from {InstanceFilesPath}..
///
- internal static string Extensions_NoConnectionStringFormat {
+ internal static string ILoggerExtensions_DeletedInstanceFilesFormat {
get {
- return ResourceManager.GetString("Extensions_NoConnectionStringFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_DeletedInstanceFilesFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to No connection strings are configured in the application configuration file..
+ /// Looks up a localized string similar to Deleted named instance {InstanceName} of SQL LocalDB..
///
- internal static string Extensions_NoConnectionStrings {
+ internal static string ILoggerExtensions_DeletedInstanceFormat {
get {
- return ResourceManager.GetString("Extensions_NoConnectionStrings", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_DeletedInstanceFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to No named pipe is associated with the specified SQL LocalDB instance..
+ /// Looks up a localized string similar to The SQL LocalDB instance {InstanceName} could not be deleted as it is currently in use..
///
- internal static string Extensions_NoNamedPipe {
+ internal static string ILoggerExtensions_DeleteFailedAsInUseFormat {
get {
- return ResourceManager.GetString("Extensions_NoNamedPipe", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_DeleteFailedAsInUseFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to More than one connection string is configured in the application configuration file. The connection string name must be explicitly specified. Other connection strings may be inherited from higher-level configuration files such as machine.config..
+ /// Looks up a localized string similar to Failed to delete SQL LocalDB instance {InstanceName} with HRESULT {HResult}..
///
- internal static string Extensions_NoSingleConnectionString {
+ internal static string ILoggerExtensions_DeleteFailedFormat {
get {
- return ResourceManager.GetString("Extensions_NoSingleConnectionString", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_DeleteFailedFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Failed to create an instance of type '{0}': {1}.
+ /// Looks up a localized string similar to Deleting named instance {InstanceName} of SQL LocalDB..
///
- internal static string Logger_FailedToCreateCustomLoggerFormat {
+ internal static string ILoggerExtensions_DeletingFormat {
get {
- return ResourceManager.GetString("Logger_FailedToCreateCustomLoggerFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_DeletingFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The SQL LocalDB native API version to load was overridden by the user to {0}..
+ /// Looks up a localized string similar to Failed to delete file(s) for SQL LocalDB instance {InstanceName} from {InstanceFilesPath}..
///
- internal static string NativeMethods_ApiVersionOverriddenByUserFormat {
+ internal static string ILoggerExtensions_DeletingInstanceFilesFailedFormat {
get {
- return ResourceManager.GetString("NativeMethods_ApiVersionOverriddenByUserFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_DeletingInstanceFilesFailedFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The SQL LocalDB function {0} could not be found..
+ /// Looks up a localized string similar to Deleting file(s) for SQL LocalDB instance {InstanceName} from {InstanceFilesPath}..
///
- internal static string NativeMethods_FunctionNotFoundFormat {
+ internal static string ILoggerExtensions_DeletingInstanceFilesFormat {
get {
- return ResourceManager.GetString("NativeMethods_FunctionNotFoundFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_DeletingInstanceFilesFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Ignoring invalid registry key name '{0}'..
+ /// Looks up a localized string similar to The SQL LocalDB function {LocalDBFunctionName} could not be found..
///
- internal static string NativeMethods_InvalidRegistryKeyNameFormat {
+ internal static string ILoggerExtensions_FunctionNotFoundFormat {
get {
- return ResourceManager.GetString("NativeMethods_InvalidRegistryKeyNameFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_FunctionNotFoundFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Loaded SQL LocalDB API from '{0}'..
+ /// Looks up a localized string similar to Obtaining instance names for SQL LocalDB..
///
- internal static string NativeMethods_NativeApiLoadedFormat {
+ internal static string ILoggerExtensions_GetInstances {
get {
- return ResourceManager.GetString("NativeMethods_NativeApiLoadedFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_GetInstances", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Failed to load SQL LocalDB API from '{0}'. Error: {1}..
+ /// Looks up a localized string similar to Obtaining information for SQL LocalDB instance {InstanceName}..
///
- internal static string NativeMethods_NativeApiLoadFailedFormat {
+ internal static string ILoggerExtensions_GettingInfoFormat {
get {
- return ResourceManager.GetString("NativeMethods_NativeApiLoadFailedFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_GettingInfoFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Could not find SQL LocalDB API DLL '{0}'..
+ /// Looks up a localized string similar to Obtaining version information for SQL LocalDB version {Version}..
///
- internal static string NativeMethods_NativeApiNotFoundFormat {
+ internal static string ILoggerExtensions_GetVersionInfoFormat {
get {
- return ResourceManager.GetString("NativeMethods_NativeApiNotFoundFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_GetVersionInfoFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The SQL LocalDB API was not loaded..
+ /// Looks up a localized string similar to Obtaining versions for SQL LocalDB..
///
- internal static string NativeMethods_NativeApiNotLoaded {
+ internal static string ILoggerExtensions_GetVersions {
get {
- return ResourceManager.GetString("NativeMethods_NativeApiNotLoaded", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_GetVersions", resourceCulture);
}
}
///
- /// Looks up a localized string similar to No SQL LocalDB API DLL path could be found..
+ /// Looks up a localized string similar to Obtained information for SQL LocalDB instance {InstanceName}..
///
- internal static string NativeMethods_NoNativeApiFound {
+ internal static string ILoggerExtensions_GotInfoFormat {
get {
- return ResourceManager.GetString("NativeMethods_NoNativeApiFound", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_GotInfoFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The configured SQL LocalDB Instance API override version '{0}' cannot be found on {1}..
+ /// Looks up a localized string similar to Obtained {InstanceCount} instance names for SQL LocalDB..
///
- internal static string NativeMethods_OverrideVersionNotFoundFormat {
+ internal static string ILoggerExtensions_GotInstancesFormat {
get {
- return ResourceManager.GetString("NativeMethods_OverrideVersionNotFoundFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_GotInstancesFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Could not open registry key '{0}'..
+ /// Looks up a localized string similar to Obtained version information for SQL LocalDB version {Version}..
///
- internal static string NativeMethods_RegistryKeyNotFoundFormat {
+ internal static string ILoggerExtensions_GotVersionInfoFormat {
get {
- return ResourceManager.GetString("NativeMethods_RegistryKeyNotFoundFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_GotVersionInfoFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to An error occurred with SQL Server LocalDB. HRESULT = {0:X}.
+ /// Looks up a localized string similar to Obtained {VersionCount} versions for SQL LocalDB..
///
- internal static string SqlLocalDbApi_GenericFailureFormat {
+ internal static string ILoggerExtensions_GotVersionsFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_GenericFailureFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_GotVersionsFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to SQL LocalDB instance '{0}' cannot be found so was not deleted..
+ /// Looks up a localized string similar to SQL LocalDB instance {InstanceName} cannot be found so was not deleted..
///
- internal static string SqlLocalDbApi_InstanceDoesNotExistFormat {
+ internal static string ILoggerExtensions_InstanceDoesNotExistFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_InstanceDoesNotExistFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_InstanceDoesNotExistFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The current value ({0}) of the {1}.LanguageId property is not recognized by SQL LocalDB. Use a valid Windows Locale ID (LCID) or set the value to zero to use the Windows defaults..
+ /// Looks up a localized string similar to The current Language Id {LanguageId} is not recognized by SQL LocalDB. Use a valid Windows Locale ID (LCID) or set the value to zero to use the Windows defaults..
///
- internal static string SqlLocalDbApi_InvalidLanguageIdFormat {
+ internal static string ILoggerExtensions_InvalidLanguageIdFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_InvalidLanguageIdFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_InvalidLanguageIdFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Created named instance of SQL LocalDB. Instance name: '{0}'; version: '{1}'..
+ /// Looks up a localized string similar to Ignoring invalid registry key name {RegistryKeyName}..
///
- internal static string SqlLocalDbApi_LogCreatedFormat {
+ internal static string ILoggerExtensions_InvalidRegistryKeyNameFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogCreatedFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_InvalidRegistryKeyNameFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Creating named instance of SQL LocalDB. Instance name: '{0}'; version: '{1}'..
+ /// Looks up a localized string similar to Loaded SQL LocalDB API from {InstanceApiPath}..
///
- internal static string SqlLocalDbApi_LogCreatingFormat {
+ internal static string ILoggerExtensions_NativeApiLoadedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogCreatingFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_NativeApiLoadedFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Deleted named instance of SQL LocalDB '{0}'..
+ /// Looks up a localized string similar to Failed to load SQL LocalDB API from {InstanceApiPath}. Error: {ErrorCode}..
///
- internal static string SqlLocalDbApi_LogDeletedFormat {
+ internal static string ILoggerExtensions_NativeApiLoadFailedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogDeletedFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_NativeApiLoadFailedFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Deleted file(s) for SQL LocalDB instance '{0}' from '{1}'..
+ /// Looks up a localized string similar to Could not find SQL LocalDB API DLL {InstanceApiPath}..
///
- internal static string SqlLocalDbApi_LogDeletedInstanceFilesFormat {
+ internal static string ILoggerExtensions_NativeApiNotFoundFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogDeletedInstanceFilesFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_NativeApiNotFoundFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The SQL LocalDB instance '{0}' could not be deleted as it is currently in use..
+ /// Looks up a localized string similar to The SQL LocalDB API was not loaded..
///
- internal static string SqlLocalDbApi_LogDeleteFailedAsInUseFormat {
+ internal static string ILoggerExtensions_NativeApiNotLoaded {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogDeleteFailedAsInUseFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_NativeApiNotLoaded", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Deleting named instance of SQL LocalDB '{0}'..
+ /// Looks up a localized string similar to Unloaded SQL LocalDB Instance API library {InstanceApiPath}..
///
- internal static string SqlLocalDbApi_LogDeletingFormat {
+ internal static string ILoggerExtensions_NativeApiUnloadedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogDeletingFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_NativeApiUnloadedFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Failed to delete file(s) for SQL LocalDB instance '{0}' from '{1}': {2}.
+ /// Looks up a localized string similar to The SQL LocalDB native API version to load was overridden by the user to {InstanceApiOverrideVersion}..
///
- internal static string SqlLocalDbApi_LogDeletingInstanceFilesFailedFormat {
+ internal static string ILoggerExtensions_NativeApiVersionOverriddenByUserFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogDeletingInstanceFilesFailedFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_NativeApiVersionOverriddenByUserFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Deleting file(s) for SQL LocalDB instance '{0}' from '{1}'..
+ /// Looks up a localized string similar to No SQL LocalDB API DLL path could be found..
///
- internal static string SqlLocalDbApi_LogDeletingInstanceFilesFormat {
+ internal static string ILoggerExtensions_NoNativeApiFound {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogDeletingInstanceFilesFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_NoNativeApiFound", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Obtaining instance names for SQL LocalDB..
+ /// Looks up a localized string similar to SQL Server LocalDB is not installed..
///
- internal static string SqlLocalDbApi_LogGetInstances {
+ internal static string ILoggerExtensions_NotInstalled {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogGetInstances", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_NotInstalled", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Obtaining information for SQL LocalDB instance '{0}'..
+ /// Looks up a localized string similar to The configured SQL LocalDB Instance API override version {InstanceApiOverrideVersion} cannot be found..
///
- internal static string SqlLocalDbApi_LogGettingInfoFormat {
+ internal static string ILoggerExtensions_OverrideVersionNotFoundFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogGettingInfoFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_OverrideVersionNotFoundFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Obtaining version information for SQL LocalDB version '{0}'..
+ /// Looks up a localized string similar to Could not open registry key {RegistryKeyName}..
///
- internal static string SqlLocalDbApi_LogGetVersionInfoFormat {
+ internal static string ILoggerExtensions_RegistryKeyNotFoundFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogGetVersionInfoFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_RegistryKeyNotFoundFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Obtained information for SQL LocalDB instance '{0}'..
+ /// Looks up a localized string similar to Shared SQL LocalDB instance {InstanceName} for owner SID {OwnerSid} as {SharedInstanceName}..
///
- internal static string SqlLocalDbApi_LogGotInfoFormat {
+ internal static string ILoggerExtensions_SharedInstanceFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogGotInfoFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_SharedInstanceFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Obtained {0} instance names for SQL LocalDB..
+ /// Looks up a localized string similar to Sharing SQL LocalDB instance {InstanceName} for owner SID {OwnerSid} as shared instance name {SharedInstanceName}..
///
- internal static string SqlLocalDbApi_LogGotInstancesFormat {
+ internal static string ILoggerExtensions_SharingInstanceFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogGotInstancesFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_SharingInstanceFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Obtained version information for SQL LocalDB version '{0}'..
+ /// Looks up a localized string similar to Started SQL LocalDB instance {InstanceName} using named pipe {NamedPipe}..
///
- internal static string SqlLocalDbApi_LogGotVersionInfoFormat {
+ internal static string ILoggerExtensions_StartedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogGotVersionInfoFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StartedFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to SQL LocalDB returned HRESULT {0:X}..
+ /// Looks up a localized string similar to Tracing started for SQL LocalDB..
///
- internal static string SqlLocalDbApi_LogNativeResultFormat {
+ internal static string ILoggerExtensions_StartedTracing {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogNativeResultFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StartedTracing", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Shared SQL LocalDB instance '{0}' for owner SID '{1}' as '{2}'..
+ /// Looks up a localized string similar to Starting SQL LocalDB instance {InstanceName}..
///
- internal static string SqlLocalDbApi_LogSharedInstanceFormat {
+ internal static string ILoggerExtensions_StartingFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogSharedInstanceFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StartingFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Sharing SQL LocalDB instance '{0}' for owner SID '{1}'. Shared instance name: '{2}'..
+ /// Looks up a localized string similar to Starting tracing for SQL LocalDB..
///
- internal static string SqlLocalDbApi_LogSharingInstanceFormat {
+ internal static string ILoggerExtensions_StartTracing {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogSharingInstanceFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StartTracing", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Started SQL LocalDB instance '{0}' using named pipe '{1}'..
+ /// Looks up a localized string similar to Failed to stop SQL LocalDB instance {InstanceName} with HRESULT {HResult}..
///
- internal static string SqlLocalDbApi_LogStartedFormat {
+ internal static string ILoggerExtensions_StopFailedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStartedFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StopFailedFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Tracing started for SQL LocalDB..
+ /// Looks up a localized string similar to Stopped SQL LocalDB instance {InstanceName} after {Timeout}..
///
- internal static string SqlLocalDbApi_LogStartedTracing {
+ internal static string ILoggerExtensions_StoppedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStartedTracing", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StoppedFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Starting SQL LocalDB instance '{0}'..
+ /// Looks up a localized string similar to Stopped sharing SQL LocalDB instance {InstanceName}..
///
- internal static string SqlLocalDbApi_LogStartingFormat {
+ internal static string ILoggerExtensions_StoppedSharingFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStartingFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StoppedSharingFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Starting tracing for SQL LocalDB..
+ /// Looks up a localized string similar to Tracing stopped for SQL LocalDB..
///
- internal static string SqlLocalDbApi_LogStartTracing {
+ internal static string ILoggerExtensions_StoppedTracing {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStartTracing", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StoppedTracing", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Stopped SQL LocalDB instance '{0}' after {1}..
+ /// Looks up a localized string similar to Stopping SQL LocalDB instance {InstanceName} with timeout: {Timeout} and option(s) {StopOptions}..
///
- internal static string SqlLocalDbApi_LogStoppedFormat {
+ internal static string ILoggerExtensions_StoppingFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStoppedFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StoppingFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Stopped sharing SQL LocalDB instance '{0}'..
+ /// Looks up a localized string similar to Stopping sharing SQL LocalDB instance {InstanceName}..
///
- internal static string SqlLocalDbApi_LogStoppedSharingFormat {
+ internal static string ILoggerExtensions_StoppingSharingFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStoppedSharingFormat", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StoppingSharingFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Tracing stopped for SQL LocalDB..
+ /// Looks up a localized string similar to Stopping tracing for SQL LocalDB..
///
- internal static string SqlLocalDbApi_LogStoppedTracing {
+ internal static string ILoggerExtensions_StoppingTracing {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStoppedTracing", resourceCulture);
+ return ResourceManager.GetString("ILoggerExtensions_StoppingTracing", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Stopping SQL LocalDB instance '{0}'. Timeout: {1}; Option(s): {2}..
+ /// Looks up a localized string similar to The specified instance of {0} does not implement the {1} interface..
///
- internal static string SqlLocalDbApi_LogStoppingFormat {
+ internal static string ISqlLocalDbInstanceInfoExtensions_DoesNotImplementAdapterFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStoppingFormat", resourceCulture);
+ return ResourceManager.GetString("ISqlLocalDbInstanceInfoExtensions_DoesNotImplementAdapterFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Stopping sharing SQL LocalDB instance '{0}'..
+ /// Looks up a localized string similar to The SQL LocalDB instance '{0}' is not running..
///
- internal static string SqlLocalDbApi_LogStoppingSharingFormat {
+ internal static string ISqlLocalDbInstanceInfoExtensions_NotRunningFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStoppingSharingFormat", resourceCulture);
+ return ResourceManager.GetString("ISqlLocalDbInstanceInfoExtensions_NotRunningFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Stopping tracing for SQL LocalDB..
+ /// Looks up a localized string similar to An error occurred calling the SQL Server LocalDB with HRESULT {0:X}..
///
- internal static string SqlLocalDbApi_LogStoppingTracing {
+ internal static string SqlLocalDbApi_GenericFailureFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_LogStoppingTracing", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_GenericFailureFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to No SQL LocalDB instance name specified..
+ /// Looks up a localized string similar to An error occurred calling the SQL Server LocalDB with HRESULT {HResult}..
///
- internal static string SqlLocalDbApi_NoInstanceName {
+ internal static string SqlLocalDbApi_LogGenericFailureFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_NoInstanceName", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_LogGenericFailureFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to SQL Server LocalDB is not installed on {0}..
+ /// Looks up a localized string similar to SQL LocalDB returned HRESULT {HResult}..
///
- internal static string SqlLocalDbApi_NotInstalledFormat {
+ internal static string SqlLocalDbApi_NativeResultFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_NotInstalledFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_NativeResultFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to No versions of SQL Server LocalDB are installed on {0}..
+ /// Looks up a localized string similar to No SQL LocalDB instance name specified..
///
- internal static string SqlLocalDbApi_NoVersionsFormat {
+ internal static string SqlLocalDbApi_NoInstanceName {
get {
- return ResourceManager.GetString("SqlLocalDbApi_NoVersionsFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_NoInstanceName", resourceCulture);
}
}
///
- /// Looks up a localized string similar to {0} cannot be less than TimeSpan.Zero..
+ /// Looks up a localized string similar to No logger was provided for the {0} instance..
///
- internal static string SqlLocalDbApi_TimeoutTooSmallFormat {
+ internal static string SqlLocalDbApi_NoLoggerFormat {
get {
- return ResourceManager.GetString("SqlLocalDbApi_TimeoutTooSmallFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_NoLoggerFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to An error occurred with a SQL Server LocalDB instance..
+ /// Looks up a localized string similar to SQL Server LocalDB is not installed on {0}..
///
- internal static string SqlLocalDbException_DefaultMessage {
+ internal static string SqlLocalDbApi_NotInstalledFormat {
get {
- return ResourceManager.GetString("SqlLocalDbException_DefaultMessage", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_NotInstalledFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Failed to enumerate the installed versions of SQL LocalDB..
+ /// Looks up a localized string similar to No versions of SQL Server LocalDB are installed on {0}..
///
- internal static string SqlLocalDbException_VersionEnumerationFailed {
+ internal static string SqlLocalDbApi_NoVersionsFormat {
get {
- return ResourceManager.GetString("SqlLocalDbException_VersionEnumerationFailed", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_NoVersionsFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to SQL LocalDB instance '{0}' already exists..
+ /// Looks up a localized string similar to The SQL LocalDB Instance API is not supported on this platform..
///
- internal static string SqlLocalDbFactory_InstanceExistsFormat {
+ internal static string SqlLocalDbApi_PlatformNotSupported {
get {
- return ResourceManager.GetString("SqlLocalDbFactory_InstanceExistsFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_PlatformNotSupported", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Failed to delete SQL LocalDB instance '{0}'..
+ /// Looks up a localized string similar to {0} cannot be less than TimeSpan.Zero..
///
- internal static string SqlLocalDbInstance_DeleteFailedFormat {
+ internal static string SqlLocalDbApi_TimeoutTooSmallFormat {
get {
- return ResourceManager.GetString("SqlLocalDbInstance_DeleteFailedFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_TimeoutTooSmallFormat", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The SQL LocalDB instance '{0}' does not exist..
+ /// Looks up a localized string similar to Failed to enumerate the installed versions of SQL LocalDB..
///
- internal static string SqlLocalDbInstance_InstanceNotFoundFormat {
+ internal static string SqlLocalDbApi_VersionEnumerationFailed {
get {
- return ResourceManager.GetString("SqlLocalDbInstance_InstanceNotFoundFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbApi_VersionEnumerationFailed", resourceCulture);
}
}
///
- /// Looks up a localized string similar to The SQL LocalDB instance '{0}' is not running..
+ /// Looks up a localized string similar to An error occurred with a SQL Server LocalDB instance..
///
- internal static string SqlLocalDbInstance_NotRunningFormat {
+ internal static string SqlLocalDbException_DefaultMessage {
get {
- return ResourceManager.GetString("SqlLocalDbInstance_NotRunningFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbException_DefaultMessage", resourceCulture);
}
}
///
/// Looks up a localized string similar to Failed to share SQL LocalDB instance '{0}'..
///
- internal static string SqlLocalDbInstance_ShareFailedFormat {
+ internal static string SqlLocalDbInstanceManager_ShareFailedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbInstance_ShareFailedFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbInstanceManager_ShareFailedFormat", resourceCulture);
}
}
///
/// Looks up a localized string similar to Failed to start SQL LocalDB instance '{0}'..
///
- internal static string SqlLocalDbInstance_StartFailedFormat {
+ internal static string SqlLocalDbInstanceManager_StartFailedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbInstance_StartFailedFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbInstanceManager_StartFailedFormat", resourceCulture);
}
}
///
/// Looks up a localized string similar to Failed to stop SQL LocalDB instance '{0}'..
///
- internal static string SqlLocalDbInstance_StopFailedFormat {
+ internal static string SqlLocalDbInstanceManager_StopFailedFormat {
get {
- return ResourceManager.GetString("SqlLocalDbInstance_StopFailedFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbInstanceManager_StopFailedFormat", resourceCulture);
}
}
///
/// Looks up a localized string similar to Failed to stop sharing SQL LocalDB instance '{0}'..
///
- internal static string SqlLocalDbInstance_UnshareFailedFormat {
- get {
- return ResourceManager.GetString("SqlLocalDbInstance_UnshareFailedFormat", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No SQL LocalDB instance returned by underlying SQL LocalDB API..
- ///
- internal static string SqlLocalDbProvider_NoInstance {
- get {
- return ResourceManager.GetString("SqlLocalDbProvider_NoInstance", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Failed to delete SQL LocalDB instance '{0}'. HRESULT = {1:X}..
- ///
- internal static string TemporarySqlLocalDbInstance_DeleteFailedFormat {
- get {
- return ResourceManager.GetString("TemporarySqlLocalDbInstance_DeleteFailedFormat", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Failed to stop SQL LocalDB instance '{0}'. HRESULT = {1:X}..
- ///
- internal static string TemporarySqlLocalDbInstance_StopFailedFormat {
+ internal static string SqlLocalDbInstanceManager_UnshareFailedFormat {
get {
- return ResourceManager.GetString("TemporarySqlLocalDbInstance_StopFailedFormat", resourceCulture);
+ return ResourceManager.GetString("SqlLocalDbInstanceManager_UnshareFailedFormat", resourceCulture);
}
}
}
diff --git a/src/SqlLocalDb/SR.en-GB.resx b/src/SqlLocalDb/SR.en-GB.resx
index a98ff2da..91fa975e 100644
--- a/src/SqlLocalDb/SR.en-GB.resx
+++ b/src/SqlLocalDb/SR.en-GB.resx
@@ -112,12 +112,12 @@
2.0
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- The current value ({0}) of the {1}.LanguageId property is not recognised by SQL LocalDB. Use a valid Windows Locale ID (LCID) or set the value to zero to use the Windows defaults.
+
+ The current Language Id {LanguageId} is not recognised by SQL LocalDB. Use a valid Windows Locale ID (LCID) or set the value to zero to use the Windows defaults.
\ No newline at end of file
diff --git a/src/SqlLocalDb/SR.resx b/src/SqlLocalDb/SR.resx
index a529bd1f..8f79e52b 100644
--- a/src/SqlLocalDb/SR.resx
+++ b/src/SqlLocalDb/SR.resx
@@ -118,7 +118,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- An error occurred with SQL Server LocalDB. HRESULT = {0:X}
+ An error occurred calling the SQL Server LocalDB with HRESULT {0:X}.SQL Server LocalDB is not installed on {0}.
@@ -132,181 +132,172 @@
An error occurred with a SQL Server LocalDB instance.
-
+
Failed to enumerate the installed versions of SQL LocalDB.
-
- The SQL LocalDB instance '{0}' does not exist.
-
-
+
The SQL LocalDB instance '{0}' is not running.
-
+
Failed to start SQL LocalDB instance '{0}'.
-
+
Failed to stop SQL LocalDB instance '{0}'.
-
- Failed to delete SQL LocalDB instance '{0}'.
-
-
+
Failed to share SQL LocalDB instance '{0}'.
-
+
Failed to stop sharing SQL LocalDB instance '{0}'.
-
- SQL LocalDB instance '{0}' already exists.
-
No SQL LocalDB instance name specified.
-
- Created named instance of SQL LocalDB. Instance name: '{0}'; version: '{1}'.
+
+ Created named instance {InstanceName} of SQL LocalDB with version {InstanceVersion}.
-
- Creating named instance of SQL LocalDB. Instance name: '{0}'; version: '{1}'.
+
+ Creating named instance {InstanceName} of SQL LocalDB with version {InstanceVersion}.
-
- Deleted named instance of SQL LocalDB '{0}'.
+
+ Deleted named instance {InstanceName} of SQL LocalDB.
-
- Deleting named instance of SQL LocalDB '{0}'.
+
+ Deleting named instance {InstanceName} of SQL LocalDB.
-
+
Obtaining instance names for SQL LocalDB.
-
- Obtaining information for SQL LocalDB instance '{0}'.
+
+ Obtaining information for SQL LocalDB instance {InstanceName}.
-
- Obtaining version information for SQL LocalDB version '{0}'.
+
+ Obtaining version information for SQL LocalDB version {Version}.
-
- Obtained information for SQL LocalDB instance '{0}'.
+
+ Obtained information for SQL LocalDB instance {InstanceName}.
-
- Obtained {0} instance names for SQL LocalDB.
+
+ Obtained {InstanceCount} instance names for SQL LocalDB.
-
- Obtained version information for SQL LocalDB version '{0}'.
+
+ Obtained version information for SQL LocalDB version {Version}.
-
- SQL LocalDB returned HRESULT {0:X}.
+
+ SQL LocalDB returned HRESULT {HResult}.
-
- Shared SQL LocalDB instance '{0}' for owner SID '{1}' as '{2}'.
+
+ Shared SQL LocalDB instance {InstanceName} for owner SID {OwnerSid} as {SharedInstanceName}.
-
- Sharing SQL LocalDB instance '{0}' for owner SID '{1}'. Shared instance name: '{2}'.
+
+ Sharing SQL LocalDB instance {InstanceName} for owner SID {OwnerSid} as shared instance name {SharedInstanceName}.
-
- Started SQL LocalDB instance '{0}' using named pipe '{1}'.
+
+ Started SQL LocalDB instance {InstanceName} using named pipe {NamedPipe}.
-
+
Tracing started for SQL LocalDB.
-
- Starting SQL LocalDB instance '{0}'.
+
+ Starting SQL LocalDB instance {InstanceName}.
-
+
Starting tracing for SQL LocalDB.
-
- Stopped SQL LocalDB instance '{0}' after {1}.
+
+ Stopped SQL LocalDB instance {InstanceName} after {Timeout}.
-
- Stopped sharing SQL LocalDB instance '{0}'.
+
+ Stopped sharing SQL LocalDB instance {InstanceName}.
-
+
Tracing stopped for SQL LocalDB.
-
- Stopping SQL LocalDB instance '{0}'. Timeout: {1}; Option(s): {2}.
+
+ Stopping SQL LocalDB instance {InstanceName} with timeout: {Timeout} and option(s) {StopOptions}.
-
- Stopping sharing SQL LocalDB instance '{0}'.
+
+ Stopping sharing SQL LocalDB instance {InstanceName}.
-
+
Stopping tracing for SQL LocalDB.
-
- No connection string named '{0}' can be found in the application configuration file.
+
+ The SQL LocalDB function {LocalDBFunctionName} could not be found.
-
- No SQL LocalDB instance returned by underlying SQL LocalDB API.
+
+ Ignoring invalid registry key name {RegistryKeyName}.
-
- No connection strings are configured in the application configuration file.
+
+ Failed to load SQL LocalDB API from {InstanceApiPath}. Error: {ErrorCode}.
-
- More than one connection string is configured in the application configuration file. The connection string name must be explicitly specified. Other connection strings may be inherited from higher-level configuration files such as machine.config.
+
+ Could not find SQL LocalDB API DLL {InstanceApiPath}.
-
- The specified database file name is invalid: {0}
+
+ The SQL LocalDB API was not loaded.
-
- The current AppDomain has no value set for the Data Directory.
+
+ No SQL LocalDB API DLL path could be found.
-
- The SQL LocalDB function {0} could not be found.
+
+ Could not open registry key {RegistryKeyName}.
-
- Ignoring invalid registry key name '{0}'.
+
+ Loaded SQL LocalDB API from {InstanceApiPath}.
-
- Failed to load SQL LocalDB API from '{0}'. Error: {1}.
+
+ SQL LocalDB instance {InstanceName} cannot be found so was not deleted.
-
- Could not find SQL LocalDB API DLL '{0}'.
+
+ The SQL LocalDB native API version to load was overridden by the user to {InstanceApiOverrideVersion}.
-
- The SQL LocalDB API was not loaded.
+
+ The SQL LocalDB instance {InstanceName} could not be deleted as it is currently in use.
-
- No SQL LocalDB API DLL path could be found.
+
+ Deleted file(s) for SQL LocalDB instance {InstanceName} from {InstanceFilesPath}.
-
- Could not open registry key '{0}'.
+
+ Failed to delete file(s) for SQL LocalDB instance {InstanceName} from {InstanceFilesPath}.
-
- Loaded SQL LocalDB API from '{0}'.
+
+ Deleting file(s) for SQL LocalDB instance {InstanceName} from {InstanceFilesPath}.
-
- SQL LocalDB instance '{0}' cannot be found so was not deleted.
+
+ The current Language Id {LanguageId} is not recognized by SQL LocalDB. Use a valid Windows Locale ID (LCID) or set the value to zero to use the Windows defaults.
-
- The SQL LocalDB native API version to load was overridden by the user to {0}.
+
+ The configured SQL LocalDB Instance API override version {InstanceApiOverrideVersion} cannot be found.
-
- The SQL LocalDB instance '{0}' could not be deleted as it is currently in use.
+
+ Failed to delete SQL LocalDB instance {InstanceName} with HRESULT {HResult}.
-
- Deleted file(s) for SQL LocalDB instance '{0}' from '{1}'.
+
+ Failed to stop SQL LocalDB instance {InstanceName} with HRESULT {HResult}.
-
- Failed to delete file(s) for SQL LocalDB instance '{0}' from '{1}': {2}
+
+ No logger was provided for the {0} instance.
-
- Deleting file(s) for SQL LocalDB instance '{0}' from '{1}'.
+
+ Obtaining versions for SQL LocalDB.
-
- The current value ({0}) of the {1}.LanguageId property is not recognized by SQL LocalDB. Use a valid Windows Locale ID (LCID) or set the value to zero to use the Windows defaults.
+
+ Obtained {VersionCount} versions for SQL LocalDB.
-
- No named pipe is associated with the specified SQL LocalDB instance.
+
+ SQL Server LocalDB is not installed.
-
- The configured SQL LocalDB Instance API override version '{0}' cannot be found on {1}.
+
+ The SQL LocalDB Instance API is not supported on this platform.
-
- Failed to create an instance of type '{0}': {1}
+
+ Unloaded SQL LocalDB Instance API library {InstanceApiPath}.
-
- Failed to delete SQL LocalDB instance '{0}'. HRESULT = {1:X}.
+
+ An error occurred calling the SQL Server LocalDB with HRESULT {HResult}.
-
- Failed to stop SQL LocalDB instance '{0}'. HRESULT = {1:X}.
+
+ The specified instance of {0} does not implement the {1} interface.
\ No newline at end of file
diff --git a/src/SqlLocalDb/SRHelper.cs b/src/SqlLocalDb/SRHelper.cs
index e941f56d..1970798a 100644
--- a/src/SqlLocalDb/SRHelper.cs
+++ b/src/SqlLocalDb/SRHelper.cs
@@ -1,16 +1,9 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// SRHelper.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
-namespace System.Data.SqlLocalDb
+using System;
+
+namespace MartinCostello.SqlLocalDb
{
///
/// A static class containing helper methods for use with the class.
@@ -34,22 +27,7 @@ internal static class SRHelper
/// is invalid or the index of a format item is less than zero,
/// or greater than or equal to the length of the array.
///
- public static string Format(string format, params object[] args)
- {
- if (format == null)
- {
- throw new ArgumentNullException(nameof(format));
- }
-
- if (args == null)
- {
- throw new ArgumentNullException(nameof(args));
- }
-
- return string.Format(
- SR.Culture,
- format,
- args);
- }
+ internal static string Format(string format, params object[] args)
+ => string.Format(SR.Culture, format, args);
}
}
diff --git a/src/SqlLocalDb/SqlLocalDbApi.cs b/src/SqlLocalDb/SqlLocalDbApi.cs
index f889dd85..97e103c7 100644
--- a/src/SqlLocalDb/SqlLocalDbApi.cs
+++ b/src/SqlLocalDb/SqlLocalDbApi.cs
@@ -1,30 +1,24 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Martin Costello (c) 2012-2015
-//
-//
-// See license.txt in the project root for license information.
-//
-//
-// SqlLocalDbApi.cs
-//
-// --------------------------------------------------------------------------------------------------------------------
+// Copyright (c) Martin Costello, 2012-2018. All rights reserved.
+// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
+using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
+using MartinCostello.SqlLocalDb.Interop;
+using Microsoft.Extensions.Logging;
-namespace System.Data.SqlLocalDb
+namespace MartinCostello.SqlLocalDb
{
///
- /// A class representing a wrapper to the SQL Server LocalDB native API.
- /// This class cannot be inherited.
+ /// A class representing a wrapper to the SQL Server LocalDB Instance API. This class cannot be inherited.
///
- public static class SqlLocalDbApi
+ public sealed class SqlLocalDbApi : ISqlLocalDbApi, ISqlLocalDbApiAdapter, IDisposable
{
///
/// The name of the default instance in SQL LocalDB 2012.
@@ -37,44 +31,106 @@ public static class SqlLocalDbApi
private const string DefaultInstanceName2014AndLater = "MSSQLLocalDB";
///
- /// The maximum length of an SQL LocalDB instance name, in bytes.
+ /// The maximum length of a SQL LocalDB instance name, in bytes.
///
- private const int MaxInstanceNameLength = (NativeMethods.MAX_LOCALDB_INSTANCE_NAME_LENGTH + 1) * sizeof(char);
+ private const int MaxInstanceNameLength = (LocalDbInstanceApi.MaximumInstanceNameLength + 1) * sizeof(char);
///
- /// The maximum length of an SQL LocalDB version string, in bytes.
+ /// The maximum length of a SQL LocalDB version string, in bytes.
///
- private const int MaxVersionLength = (NativeMethods.MAX_LOCALDB_VERSION_LENGTH + 1) * sizeof(char);
+ private const int MaxVersionLength = (LocalDbInstanceApi.MaximumInstanceVersionLength + 1) * sizeof(char);
///
/// The value to pass to functions which have a reserved parameter for future use.
///
private const int ReservedValue = 0;
+ ///
+ /// The native API. This field is read-only.
+ ///
+ private readonly LocalDbInstanceApi _api;
+
+ ///
+ /// Whether the instance has been disposed of.
+ ///
+ private bool _disposed;
+
///
/// The available versions of SQL Server LocalDB installed on the local machine.
///
- private static string[] _versions;
+ private string[] _versions;
///
- /// Whether to automatically delete the files associated with SQL LocalDB instances when they are deleted.
+ /// The timeout for stopping an instance of LocalDB.
///
- private static bool _automaticallyDeleteInstanceFiles = SqlLocalDbConfig.AutomaticallyDeleteInstanceFiles;
+ private TimeSpan _stopTimeout;
///
- /// The locale ID (LCID) to use for formatting error messages.
+ /// Initializes a new instance of the class.
///
- private static int _languageId = SqlLocalDbConfig.LanguageId;
+ /// The to use.
+ ///
+ /// is .
+ ///
+ ///
+ /// did create the required loggers.
+ ///
+ public SqlLocalDbApi(ILoggerFactory loggerFactory)
+ : this(new SqlLocalDbOptions(), loggerFactory)
+ {
+ }
///
- /// The options to use when stopping instances of SQL LocalDB.
+ /// Initializes a new instance of the class.
///
- private static StopInstanceOptions _stopOptions = SqlLocalDbConfig.StopOptions;
+ /// The to use.
+ /// The to use.
+ ///
+ /// or is .
+ ///
+ ///
+ /// did create the required loggers.
+ ///
+ public SqlLocalDbApi(SqlLocalDbOptions options, ILoggerFactory loggerFactory)
+ : this(options, new WindowsRegistry(), loggerFactory)
+ {
+ }
///
- /// The timeout for stopping an instance of LocalDB.
+ /// Initializes a new instance of the class.
///
- private static TimeSpan _stopTimeout = SqlLocalDbConfig.StopTimeout;
+ /// The to use.
+ /// The to use.
+ /// The to use.
+ ///
+ /// , or is .
+ ///
+ ///
+ /// did not create the required loggers.
+ ///
+ internal SqlLocalDbApi(SqlLocalDbOptions options, IRegistry registry, ILoggerFactory loggerFactory)
+ {
+ if (options == null)
+ {
+ throw new ArgumentNullException(nameof(options));
+ }
+
+ if (registry == null)
+ {
+ throw new ArgumentNullException(nameof(registry));
+ }
+
+ LoggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
+ Logger = loggerFactory.CreateLogger() ?? throw new InvalidOperationException(SRHelper.Format(SR.SqlLocalDbApi_NoLoggerFormat, nameof(SqlLocalDbApi)));
+ var apiLogger = loggerFactory.CreateLogger() ?? throw new InvalidOperationException(SRHelper.Format(SR.SqlLocalDbApi_NoLoggerFormat, nameof(LocalDbInstanceApi)));
+
+ AutomaticallyDeleteInstanceFiles = options.AutomaticallyDeleteInstanceFiles;
+ LanguageId = options.LanguageId;
+ StopOptions = options.StopOptions;
+ StopTimeout = options.StopTimeout;
+
+ _api = new LocalDbInstanceApi(options.NativeApiOverrideVersion, registry, apiLogger);
+ }
///
/// Gets or sets a value indicating whether to automatically delete the
@@ -87,16 +143,12 @@ public static class SqlLocalDbApi
/// used. The default value is , unless overridden
/// by the SQLLocalDB:AutomaticallyDeleteInstanceFiles application configuration setting.
///
- public static bool AutomaticallyDeleteInstanceFiles
- {
- get { return _automaticallyDeleteInstanceFiles; }
- set { _automaticallyDeleteInstanceFiles = value; }
- }
+ public bool AutomaticallyDeleteInstanceFiles { get; set; }
///
/// Gets the name of the default SQL LocalDB instance.
///
- public static string DefaultInstanceName
+ public string DefaultInstanceName
{
get
{
@@ -107,7 +159,7 @@ public static string DefaultInstanceName
return string.Empty;
}
- if (NativeMethods.NativeApiVersion.Major == 11)
+ if (_api.NativeApiVersion.Major == 11)
{
return DefaultInstanceName2012;
}
@@ -125,11 +177,7 @@ public static string DefaultInstanceName
/// order is used. This property is provided for integrators to specifically override the language used from
/// the defaults used by the local installed operating system.
///
- public static int LanguageId
- {
- get { return _languageId; }
- set { _languageId = value; }
- }
+ public int LanguageId { get; set; }
///
/// Gets the version string for the latest installed version of SQL Server LocalDB.
@@ -137,19 +185,21 @@ public static int LanguageId
///
/// No versions of SQL Server LocalDB are installed on the local machine.
///
- public static string LatestVersion
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
+ public string LatestVersion
{
get
{
+ EnsurePlatformSupported();
+
// Access through property to ensure initialized
- IList versions = Versions;
+ IReadOnlyList versions = Versions;
if (versions.Count < 1)
{
- string message = SRHelper.Format(
- SR.SqlLocalDbApi_NoVersionsFormat,
- Environment.MachineName);
-
+ string message = SRHelper.Format(SR.SqlLocalDbApi_NoVersionsFormat, Environment.MachineName);
throw new InvalidOperationException(message);
}
@@ -165,11 +215,7 @@ public static string LatestVersion
///
/// Gets or sets the options to use when stopping instances of SQL LocalDB.
///
- public static StopInstanceOptions StopOptions
- {
- get { return _stopOptions; }
- set { _stopOptions = value; }
- }
+ public StopInstanceOptions StopOptions { get; set; }
///
/// Gets or sets the default timeout to use when
@@ -178,7 +224,7 @@ public static StopInstanceOptions StopOptions
///
/// is less than .
///
- public static TimeSpan StopTimeout
+ public TimeSpan StopTimeout
{
get
{
@@ -189,10 +235,7 @@ public static TimeSpan StopTimeout
{
if (value < TimeSpan.Zero)
{
- string message = SRHelper.Format(
- SR.SqlLocalDbApi_TimeoutTooSmallFormat,
- nameof(value));
-
+ string message = SRHelper.Format(SR.SqlLocalDbApi_TimeoutTooSmallFormat, nameof(value));
throw new ArgumentOutOfRangeException(nameof(value), value, message);
}
@@ -210,10 +253,15 @@ public static TimeSpan StopTimeout
///
/// The installed versions of SQL LocalDB could not be determined.
///
- public static IList Versions
+ public IReadOnlyList Versions
{
get
{
+ if (!IsWindows)
+ {
+ return Array.Empty();
+ }
+
if (_versions == null)
{
// Use lazy initialization to allow some functionality to be
@@ -225,41 +273,92 @@ public static IList Versions
}
}
+ ///
+ ISqlLocalDbApi ISqlLocalDbApiAdapter.LocalDb => this;
+
+ ///
+ /// Gets a value indicating whether the executing platform is Microsoft Windows.
+ ///
+ internal static bool IsWindows { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+
+ ///
+ /// Gets the to use.
+ ///
+ internal ILoggerFactory LoggerFactory { get; }
+
+ ///
+ /// Gets the to use.
+ ///
+ private ILogger Logger { get; }
+
+ ///
+ /// Gets the full path of the directory containing the SQL LocalDB instance files for the current user.
+ ///
+ ///
+ /// The full path of the directory containing the SQL LocalDB instance files for the current user.
+ ///
+ ///
+ /// The folder usually used to store SQL LocalDB instance files is %LOCALAPPDATA%\Microsoft\Microsoft SQL Server Local DB\Instances.
+ ///
+ public static string GetInstancesFolderPath()
+ {
+ return Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "Microsoft",
+ "Microsoft SQL Server Local DB",
+ "Instances");
+ }
+
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
///
/// Creates a new instance of SQL Server LocalDB.
///
/// The name of the LocalDB instance.
+ ///
+ /// An containing information about the instance that was created.
+ ///
///
/// is .
///
///
/// No versions of SQL Server LocalDB are installed on the local machine.
///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
///
/// The SQL Server LocalDB instance specified by could
/// not be stopped or the installed versions of SQL LocalDB could not be determined.
///
- public static void CreateInstance(string instanceName)
- {
- // Use the latest version
- CreateInstance(instanceName, LatestVersion);
- }
+ public ISqlLocalDbInstanceInfo CreateInstance(string instanceName) => CreateInstance(instanceName, LatestVersion);
///
/// Creates a new instance of SQL Server LocalDB.
///
/// The name of the LocalDB instance.
/// The version of SQL Server LocalDB to use.
+ ///
+ /// An containing information about the instance that was created.
+ ///
///
/// or is .
///
///
/// SQL Server LocalDB is not installed on the local machine.
///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
///
/// The SQL Server LocalDB instance specified by and could not be created.
///
- public static void CreateInstance(string instanceName, string version)
+ public ISqlLocalDbInstanceInfo CreateInstance(string instanceName, string version)
{
if (instanceName == null)
{
@@ -271,14 +370,16 @@ public static void CreateInstance(string instanceName, string version)
throw new ArgumentNullException(nameof(version));
}
- Logger.Verbose(Logger.TraceEvent.CreateInstance, SR.SqlLocalDbApi_LogCreatingFormat, instanceName, version);
+ Logger.CreatingInstance(instanceName, version);
InvokeThrowOnError(
- () => NativeMethods.CreateInstance(version, instanceName, ReservedValue),
- Logger.TraceEvent.CreateInstance,
+ () => _api.CreateInstance(version, instanceName, ReservedValue),
+ EventIds.CreatingInstanceFailed,
instanceName);
- Logger.Verbose(Logger.TraceEvent.CreateInstance, SR.SqlLocalDbApi_LogCreatedFormat, instanceName, version);
+ Logger.CreatedInstance(instanceName, version);
+
+ return GetInstanceInfo(instanceName);
}
///
@@ -293,13 +394,13 @@ public static void CreateInstance(string instanceName, string version)
///
/// SQL Server LocalDB is not installed on the local machine.
///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
///
/// The SQL Server LocalDB instance specified by could not be deleted.
///
- public static void DeleteInstance(string instanceName)
- {
- DeleteInstance(instanceName, deleteFiles: AutomaticallyDeleteInstanceFiles);
- }
+ public void DeleteInstance(string instanceName) => DeleteInstance(instanceName, deleteFiles: AutomaticallyDeleteInstanceFiles);
///
/// Deletes the specified SQL Server LocalDB instance.
@@ -316,10 +417,13 @@ public static void DeleteInstance(string instanceName)
///
/// SQL Server LocalDB is not installed on the local machine.
///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
///
/// The SQL Server LocalDB instance specified by could not be deleted.
///
- public static void DeleteInstance(string instanceName, bool deleteFiles)
+ public void DeleteInstance(string instanceName, bool deleteFiles)
{
DeleteInstanceInternal(instanceName, throwIfNotFound: true, deleteFiles: deleteFiles);
}
@@ -334,7 +438,13 @@ public static void DeleteInstance(string instanceName, bool deleteFiles)
/// The default instance(s) of any version(s) of SQL LocalDB that are
/// installed on the local machine are not deleted.
///
- public static int DeleteUserInstances() => DeleteUserInstances(deleteFiles: AutomaticallyDeleteInstanceFiles);
+ ///
+ /// SQL Server LocalDB is not installed on the local machine.
+ ///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
+ public int DeleteUserInstances() => DeleteUserInstances(deleteFiles: AutomaticallyDeleteInstanceFiles);
///
/// Deletes all user instances of SQL LocalDB on the current machine,
@@ -351,53 +461,52 @@ public static void DeleteInstance(string instanceName, bool deleteFiles)
/// The default instance(s) of any version(s) of SQL LocalDB that are
/// installed on the local machine are not deleted.
///
- public static int DeleteUserInstances(bool deleteFiles)
+ ///
+ /// SQL Server LocalDB is not installed on the local machine.
+ ///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
+ public int DeleteUserInstances(bool deleteFiles)
{
int instancesDeleted = 0;
- IList instanceNames = GetInstanceNames();
+ IReadOnlyList instanceNames = GetInstanceNames();
- if (instanceNames != null)
+ foreach (string instanceName in instanceNames)
{
- foreach (string instanceName in instanceNames)
+ ISqlLocalDbInstanceInfo info = GetInstanceInfo(instanceName);
+
+ // Do not try to delete automatic instances.
+ // These are the default instances created for each version.
+ // As of SQL LocalDB 2014, the default instance is named 'MSSQLLocalDB'.
+ if (!info.Exists ||
+ info.IsAutomatic ||
+ string.Equals(info.Name, DefaultInstanceName2014AndLater, StringComparison.Ordinal))
{
- ISqlLocalDbInstanceInfo info = GetInstanceInfo(instanceName);
-
- // Do not try to delete automatic instances.
- // These are the default instances created for each version.
- // As of SQL LocalDB 2014, the default instance is named 'MSSQLLocalDB'.
- if (!info.Exists ||
- info.IsAutomatic ||
- string.Equals(info.Name, DefaultInstanceName2014AndLater, StringComparison.Ordinal))
- {
- continue;
- }
+ continue;
+ }
- // In some cases, SQL LocalDB may report instance names in calls
- // to enumerate the instances that do not actually exist. Presumably
- // this can occur if the installation/instances become corrupted.
- // Such failures to delete an instance should be ignored
- try
+ // In some cases, SQL LocalDB may report instance names in calls
+ // to enumerate the instances that do not actually exist. Presumably
+ // this can occur if the installation/instances become corrupted.
+ // Such failures to delete an instance should be ignored
+ try
+ {
+ if (DeleteInstanceInternal(instanceName, throwIfNotFound: false, deleteFiles: deleteFiles))
{
- if (DeleteInstanceInternal(instanceName, throwIfNotFound: false, deleteFiles: deleteFiles))
- {
- instancesDeleted++;
- }
+ instancesDeleted++;
}
- catch (SqlLocalDbException ex)
+ }
+ catch (SqlLocalDbException ex)
+ {
+ if (ex.ErrorCode == SqlLocalDbErrors.InstanceBusy)
{
- if (ex.ErrorCode == SqlLocalDbErrors.InstanceBusy)
- {
- Logger.Warning(
- Logger.TraceEvent.DeleteFailedAsInstanceInUse,
- SR.SqlLocalDbApi_LogDeleteFailedAsInUseFormat,
- ex.InstanceName);
-
- continue;
- }
-
- throw;
+ Logger.DeletingInstanceFailedAsInUse(ex, ex.InstanceName);
+ continue;
}
+
+ throw;
}
}
@@ -418,17 +527,22 @@ public static int DeleteUserInstances(bool deleteFiles)
///
/// SQL Server LocalDB is not installed on the local machine.
///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
///
/// The information for the SQL Server LocalDB instance specified by could not obtained.
///
- public static ISqlLocalDbInstanceInfo GetInstanceInfo(string instanceName)
+ public ISqlLocalDbInstanceInfo GetInstanceInfo(string instanceName)
{
if (instanceName == null)
{
throw new ArgumentNullException(nameof(instanceName));
}
- Logger.Verbose(Logger.TraceEvent.GetInstanceInfo, SR.SqlLocalDbApi_LogGettingInfoFormat, instanceName);
+ Logger.GettingInstanceInfo(instanceName);
+
+ LocalDbInstanceInfo info;
int size = LocalDbInstanceInfo.MarshalSize;
IntPtr ptrInfo = Marshal.AllocHGlobal(size);
@@ -436,20 +550,24 @@ public static ISqlLocalDbInstanceInfo GetInstanceInfo(string instanceName)
try
{
InvokeThrowOnError(
- () => NativeMethods.GetInstanceInfo(instanceName, ptrInfo, size),
- Logger.TraceEvent.GetInstanceInfo,
+ () => _api.GetInstanceInfo(instanceName, ptrInfo, size),
+ EventIds.GettingInstanceInfoFailed,
instanceName);
- LocalDbInstanceInfo info = MarshalStruct(ptrInfo);
-
- Logger.Verbose(Logger.TraceEvent.GetInstanceInfo, SR.SqlLocalDbApi_LogGotInfoFormat, instanceName);
-
- return info;
+ info = MarshalStruct(ptrInfo);
}
finally
{
Marshal.FreeHGlobal(ptrInfo);
}
+
+ Logger.GotInstanceInfo(instanceName);
+
+ var result = new SqlLocalDbInstanceInfo(this);
+
+ result.Update(info);
+
+ return result;
}
///
@@ -461,27 +579,30 @@ public static ISqlLocalDbInstanceInfo GetInstanceInfo(string instanceName)
///
/// SQL Server LocalDB is not installed on the local machine.
///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
///
/// The SQL Server LocalDB instance names could not be determined.
///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Design",
- "CA1024:UsePropertiesWhereAppropriate",
- Justification = "Requires enumeration of native API and allocating unmanaged memory.")]
- public static IList GetInstanceNames()
+ public IReadOnlyList GetInstanceNames()
{
- Logger.Verbose(Logger.TraceEvent.GetInstanceNames, SR.SqlLocalDbApi_LogGetInstances);
+ EnsurePlatformSupported();
+
+ Logger.GettingInstanceNames();
// Query the LocalDB API to get the number of instances
int count = 0;
- int hr = NativeMethods.GetInstanceNames(IntPtr.Zero, ref count);
+ int hr = _api.GetInstanceNames(IntPtr.Zero, ref count);
if (hr != 0 &&
hr != SqlLocalDbErrors.InsufficientBuffer)
{
- throw GetLocalDbError(hr, Logger.TraceEvent.GetInstanceNames);
+ throw GetLocalDbError(hr, EventIds.GettingInstanceNamesFailed);
}
+ string[] names;
+
// Allocate enough memory to receive the instance name array
int nameLength = MaxInstanceNameLength;
IntPtr ptrNames = Marshal.AllocHGlobal(nameLength * count);
@@ -489,42 +610,20 @@ public static IList GetInstanceNames()
try
{
InvokeThrowOnError(
- () => NativeMethods.GetInstanceNames(ptrNames, ref count),
- Logger.TraceEvent.GetInstanceNames);
+ () => _api.GetInstanceNames(ptrNames, ref count),
+ EventIds.GettingInstanceNamesFailed);
// Read the instance names back from unmanaged memory
- string[] names = MarshalStringArray(ptrNames, nameLength, count);
-
- Logger.Verbose(Logger.TraceEvent.GetInstanceNames, SR.SqlLocalDbApi_LogGotInstancesFormat, names.Length);
-
- return names;
+ names = MarshalStringArray(ptrNames, nameLength, count);
}
finally
{
Marshal.FreeHGlobal(ptrNames);
}
- }
- ///
- /// Gets the full path of the directory containing the SQL LocalDB instance files for the current user.
- ///
- ///
- /// The full path of the directory containing the SQL LocalDB instance files for the current user.
- ///
- ///
- /// The folder usually used to store SQL LocalDB instance files is %LOCALAPPDATA%\Microsoft\Microsoft SQL Server Local DB\Instances.
- ///
- [Diagnostics.CodeAnalysis.SuppressMessage(
- "Microsoft.Design",
- "CA1024:UsePropertiesWhereAppropriate",
- Justification = "Calls a number of methods so is more appropriate as a method.")]
- public static string GetInstancesFolderPath()
- {
- return Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
- "Microsoft",
- "Microsoft SQL Server Local DB",
- "Instances");
+ Logger.GotInstanceNames(names.Length);
+
+ return names;
}
///
@@ -541,17 +640,22 @@ public static string GetInstancesFolderPath()
///
/// SQL Server LocalDB is not installed on the local machine.
///
+ ///
+ /// The method is called from a non-Windows operating system.
+ ///
///
/// The information for the SQL Server LocalDB version specified by