diff --git a/GitTfs/Core/TfsInterop/TfsPlugin.cs b/GitTfs/Core/TfsInterop/TfsPlugin.cs index 2ad331b8..13686b7f 100644 --- a/GitTfs/Core/TfsInterop/TfsPlugin.cs +++ b/GitTfs/Core/TfsInterop/TfsPlugin.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using StructureMap; using StructureMap.Graph; using System.IO; +using Microsoft.Win32; namespace Sep.Git.Tfs.Core.TfsInterop { @@ -12,25 +14,43 @@ namespace Sep.Git.Tfs.Core.TfsInterop { public static TfsPlugin Find() { - var x = new PluginLoader(); + var pluginLoader = new PluginLoader(); var explicitVersion = Environment.GetEnvironmentVariable("GIT_TFS_CLIENT"); if (explicitVersion == "11") explicitVersion = "2012"; // GitTfs.Vs2012 was formerly called GitTfs.Vs11 if(!String.IsNullOrEmpty(explicitVersion)) { - return x.Try("GitTfs.Vs" + explicitVersion, "Sep.Git.Tfs.TfsPlugin") ?? - x.Fail("Unable to load TFS version specified in GIT_TFS_CLIENT (" + explicitVersion + ")!"); + return pluginLoader.TryLoadVsPluginVersion(explicitVersion) ?? + pluginLoader.Fail("Unable to load TFS version specified in GIT_TFS_CLIENT (" + explicitVersion + ")!"); } - return x.Try("GitTfs.Vs2013", "Sep.Git.Tfs.TfsPlugin") ?? - x.Try("GitTfs.Vs2012", "Sep.Git.Tfs.TfsPlugin") ?? - x.Try("GitTfs.Vs2010", "Sep.Git.Tfs.TfsPlugin") ?? - x.Try("GitTfs.Vs2015", "Sep.Git.Tfs.TfsPlugin") ?? - x.Fail(); + return pluginLoader.TryLoadVsPluginVersion("2015", true) ?? + pluginLoader.TryLoadVsPluginVersion("2013") ?? + pluginLoader.TryLoadVsPluginVersion("2012") ?? + pluginLoader.TryLoadVsPluginVersion("2010") ?? + pluginLoader.TryLoadVsPluginVersion("2015") ?? + pluginLoader.Fail(); } class PluginLoader { private List _failures = new List(); private static string VsPluginAssemblyFolder { get; set; } + private static readonly Dictionary VisualStudioVersions = new Dictionary() + { + {"2015", "14.0" }, + {"2013", "12.0" }, + {"2012", "11.0" }, + {"2010", "10.0" }, + }; + + public TfsPlugin TryLoadVsPluginVersion(string version, bool isVisualStudioRequired = false) + { + var assembly = "GitTfs.Vs" + version; + if (isVisualStudioRequired && !IsVisualStudioInstalled(version)) + { + return null; + } + return Try(assembly, "Sep.Git.Tfs.TfsPlugin"); + } public TfsPlugin Try(string assembly, string pluginType) { @@ -53,6 +73,49 @@ namespace Sep.Git.Tfs.Core.TfsInterop return null; } + private static bool IsVisualStudioInstalled(string version) + { + if (!VisualStudioVersions.ContainsKey(version)) + { + Trace.WriteLine("Visual Studio " + version + " not supported..."); + return false; + } + + var versionCode = VisualStudioVersions[version]; + //doc: http://blogs.msdn.com/b/heaths/archive/2015/04/13/detection-keys-for-visual-studio-2015.aspx + var isInstalled = TryGetRegString(@"SOFTWARE\Wow6432Node\Microsoft\DevDiv\vs\Servicing\" + versionCode) + || TryGetRegString(@"SOFTWARE\Microsoft\DevDiv\vs\Servicing\" + versionCode); + + if (!isInstalled) + { + Trace.WriteLine("Visual Studio " + version + " not found..."); + } + else + { + Trace.WriteLine("Visual Studio " + version + " detected..."); + } + return isInstalled; + } + + private static bool TryGetRegString(string path) + { + RegistryKey registryKey = Registry.LocalMachine; + try + { + Trace.WriteLine("Trying to get " + registryKey.Name + "\\" + path); + var key = registryKey.OpenSubKey(path); + if (key != null) + { + return true; + } + } + catch (Exception e) + { + Trace.WriteLine("Unable to get registry value " + registryKey.Name + "\\" + path + ": " + e); + } + return false; + } + static Assembly LoadFromSameFolder(object sender, ResolveEventArgs args) { string folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); diff --git a/doc/release-notes/NEXT.md b/doc/release-notes/NEXT.md index e1f087f4..a488d142 100644 --- a/doc/release-notes/NEXT.md +++ b/doc/release-notes/NEXT.md @@ -1 +1,2 @@ -Fix for RemoteInfo not populating IgnoreExceptRegex property when setting the RemoteOptions property (#880) +* Fix for RemoteInfo not populating IgnoreExceptRegex property when setting the RemoteOptions property (#880) +* Better loading strategy of the GitTfs.Vs20xx plugin to prevent a crash(#894 & #895) \ No newline at end of file