Index: tools/install/Installer.cs ================================================================== --- tools/install/Installer.cs +++ tools/install/Installer.cs @@ -95,11 +95,11 @@ #region Public Enumerations [Flags()] public enum InstallFlags { - #region Normal Flags + #region Normal Values None = 0x0, GlobalAssemblyCache = 0x1, AssemblyFolders = 0x2, DbProviderFactory = 0x4, VsPackage = 0x8, @@ -109,11 +109,11 @@ VsDevEnvSetup = 0x80, #endregion /////////////////////////////////////////////////////////////////////// - #region Composite Flags + #region Composite Values Framework = GlobalAssemblyCache | AssemblyFolders | DbProviderFactory, /////////////////////////////////////////////////////////////////////// @@ -130,18 +130,44 @@ VsPackageGlobalAssemblyCache), #endregion /////////////////////////////////////////////////////////////////////// + #region Suggested Default Values Default = All + #endregion + } + + /////////////////////////////////////////////////////////////////////////// + + [Flags()] + public enum ProviderFlags + { + #region Normal Values + None = 0x0, + SystemEf6MustBeGlobal = 0x1, + DidLinqWarning = 0x2, + DidEf6Warning = 0x4, + ForceLinqEnabled = 0x8, + ForceLinqDisabled = 0x10, + ForceEf6Enabled = 0x20, + ForceEf6Disabled = 0x40, + #endregion + + /////////////////////////////////////////////////////////////////////// + + #region Suggested Default Values + Default = None + #endregion } /////////////////////////////////////////////////////////////////////////// [Flags()] public enum TracePriority { + #region Normal Values None = 0x0, Lowest = 0x1, Lower = 0x2, Low = 0x4, MediumLow = 0x8, @@ -148,11 +174,17 @@ Medium = 0x10, MediumHigh = 0x20, High = 0x40, Higher = 0x80, Highest = 0x100, + #endregion + + /////////////////////////////////////////////////////////////////////// + + #region Suggested Default Flags Default = Medium + #endregion } #endregion /////////////////////////////////////////////////////////////////////////// @@ -1976,10 +2008,11 @@ string configVersion, string vsVersionSuffix, string debugFormat, string traceFormat, InstallFlags installFlags, + ProviderFlags providerFlags, TracePriority debugPriority, TracePriority tracePriority, bool perUser, bool install, bool wow64, @@ -2017,10 +2050,11 @@ this.configVersion = configVersion; this.vsVersionSuffix = vsVersionSuffix; this.debugFormat = debugFormat; this.traceFormat = traceFormat; this.installFlags = installFlags; + this.providerFlags = providerFlags; this.debugPriority = debugPriority; this.tracePriority = tracePriority; this.perUser = perUser; this.install = install; this.wow64 = wow64; @@ -2211,20 +2245,30 @@ "Entity Framework 6 assembly was not resolved.", traceCategory); return false; } + + /////////////////////////////////////////////////////////////////// + + private static bool IsSystemEf6AssemblyGlobal() + { + if (systemEf6Assembly == null) + return false; + + return systemEf6Assembly.GlobalAssemblyCache; + } #endregion /////////////////////////////////////////////////////////////////// #region Public Static Methods public static void BreakIntoDebugger() { Console.WriteLine( - "Attach a debugger to process {0} and press any key to " + - "continue.", (thisProcess != null) ? + "Attach a debugger to process {0} and press " + + "any key to continue.", (thisProcess != null) ? thisProcess.Id.ToString() : ""); try { Console.ReadKey(true); /* throw */ @@ -2253,15 +2297,15 @@ return new Configuration( thisAssembly, null, directory, coreFileName, linqFileName, ef6FileName, designerFileName, null, null, null, TraceOps.DebugFormat, TraceOps.TraceFormat, - InstallFlags.Default, TracePriority.Default, - TracePriority.Default, false, true, false, false, false, + InstallFlags.Default, ProviderFlags.Default, + TracePriority.Default, TracePriority.Default, false, true, + false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, true, true, - false, false, false); + false, true, true, false, false, false); } /////////////////////////////////////////////////////////////////// [MethodImpl(MethodImplOptions.NoInlining)] @@ -2922,10 +2966,31 @@ continue; } configuration.perUser = (bool)value; } + else if (MatchOption(newArg, "providerFlags")) + { + object value = ParseEnum( + typeof(ProviderFlags), text, true); + + if (value == null) + { + error = TraceOps.DebugAndTrace( + TracePriority.Lowest, debugCallback, + traceCallback, String.Format( + "Invalid provider flags value: {0}", + ForDisplay(text)), traceCategory); + + if (strict) + return false; + + continue; + } + + configuration.providerFlags = (ProviderFlags)value; + } else if (MatchOption(newArg, "registryVersion")) { configuration.registryVersion = text; } else if (MatchOption(newArg, "strict")) @@ -3417,12 +3482,59 @@ return ((installFlags & hasFlags) != InstallFlags.None); } /////////////////////////////////////////////////////////////////// + public bool HasFlags( + ProviderFlags hasFlags, + bool all + ) + { + if (all) + return ((providerFlags & hasFlags) == hasFlags); + else + return ((providerFlags & hasFlags) != ProviderFlags.None); + } + + /////////////////////////////////////////////////////////////////// + public bool IsLinqSupported() { + // + // NOTE: Check to see if the caller has forced LINQ support to + // be enabled -OR- disabled, thereby bypassing the need + // for "automatic detection" by this method. + // + if (HasFlags(ProviderFlags.ForceLinqEnabled, true)) + { + if (!HasFlags(ProviderFlags.DidLinqWarning, true)) + { + TraceOps.DebugAndTrace(TracePriority.MediumHigh, + debugCallback, traceCallback, + "Forced to enable support for \"Linq\".", + traceCategory); + + providerFlags |= ProviderFlags.DidLinqWarning; + } + + return true; + } + else if (HasFlags(ProviderFlags.ForceLinqDisabled, true)) + { + if (!HasFlags(ProviderFlags.DidLinqWarning, true)) + { + TraceOps.DebugAndTrace(TracePriority.MediumHigh, + debugCallback, traceCallback, + "Forced to disable support for \"Linq\".", + traceCategory); + + providerFlags |= ProviderFlags.DidLinqWarning; + } + + return false; + } + // // NOTE: Return non-zero if the System.Data.SQLite.Linq // assembly should be processed during the install. // If the target is Visual Studio 2005, this must // return zero. @@ -3432,22 +3544,67 @@ /////////////////////////////////////////////////////////////////// public bool IsEf6Supported() { + // + // NOTE: Check to see if the caller has forced EF6 support to + // be enabled -OR- disabled, thereby bypassing the need + // for "automatic detection" by this method. + // + if (HasFlags(ProviderFlags.ForceEf6Enabled, true)) + { + if (!HasFlags(ProviderFlags.DidEf6Warning, true)) + { + TraceOps.DebugAndTrace(TracePriority.MediumHigh, + debugCallback, traceCallback, + "Forced to enable support for \"Ef6\".", + traceCategory); + + providerFlags |= ProviderFlags.DidEf6Warning; + } + + return true; + } + else if (HasFlags(ProviderFlags.ForceEf6Disabled, true)) + { + if (!HasFlags(ProviderFlags.DidEf6Warning, true)) + { + TraceOps.DebugAndTrace(TracePriority.MediumHigh, + debugCallback, traceCallback, + "Forced to disable support for \"Ef6\".", + traceCategory); + + providerFlags |= ProviderFlags.DidEf6Warning; + } + + return false; + } + // // NOTE: Return non-zero if the System.Data.SQLite.EF6 // assembly should be processed during the install. - // If the target is Visual Studio 2005 or Visual - // Studio 2008, this must return zero. Also, if - // the EF6 core assembly is unavailable, this must - // return zero. + // If the target is Visual Studio 2005 or Visual Studio + // 2008, this must return zero. // if (noNetFx40 && noNetFx45 && noNetFx451) return false; - return IsSystemEf6AssemblyAvailable(); + // + // NOTE: Also, if the EF6 core assembly is unavailable, this + // must return zero. + // + if (!IsSystemEf6AssemblyAvailable()) + return false; + + // + // NOTE: Finally, if the EF6 core assembly is not available + // globally [and this is a requirement for the current + // install], return zero. + // + return HasFlags(ProviderFlags.SystemEf6MustBeGlobal, true) ? + IsSystemEf6AssemblyGlobal() : true; } /////////////////////////////////////////////////////////////////// public AssemblyName GetCoreAssemblyName() /* REQUIRED */ @@ -3586,10 +3743,14 @@ traceCategory); traceCallback(String.Format(NameAndValueFormat, "InstallFlags", ForDisplay(installFlags)), traceCategory); + + traceCallback(String.Format(NameAndValueFormat, + "ProviderFlags", ForDisplay(providerFlags)), + traceCategory); traceCallback(String.Format(NameAndValueFormat, "DebugPriority", ForDisplay(debugPriority)), traceCategory); @@ -3705,10 +3866,22 @@ traceCallback(String.Format(NameAndValueFormat, "AssemblyConfiguration", ForDisplay(GetAssemblyConfiguration(assembly))), traceCategory); } + + /////////////////////////////////////////////////////////// + + traceCallback(String.Format(NameAndValueFormat, + "IsSystemEf6AssemblyAvailable", ForDisplay( + IsSystemEf6AssemblyAvailable())), + traceCategory); + + traceCallback(String.Format(NameAndValueFormat, + "IsSystemEf6AssemblyGlobal", ForDisplay( + IsSystemEf6AssemblyGlobal())), + traceCategory); /////////////////////////////////////////////////////////// traceCallback(String.Format(NameAndValueFormat, "IsLinqSupported", ForDisplay(IsLinqSupported())), @@ -3876,10 +4049,19 @@ public InstallFlags InstallFlags { get { return installFlags; } set { installFlags = value; } } + + /////////////////////////////////////////////////////////////////// + + private ProviderFlags providerFlags; + public ProviderFlags ProviderFlags + { + get { return providerFlags; } + set { providerFlags = value; } + } /////////////////////////////////////////////////////////////////// private TracePriority debugPriority; public TracePriority DebugPriority